---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v2.00
secao: 46
titulo: "Shell de aplicação — **`estável`** (v0.52) · SH1–SH23 · pattern F6 · suíte `suite-shell.mjs` 68/68 ✓ · render 18/0 · contraste 32/0 (na estreia; em 2026-09-15, com o SH19: 84/0 · 54/0 · 55/0; em 2026-09-27, depois da SH-P29 e da SH-P34, MANIFESTO §262 e §264: suíte 116/0 · render 121/0) · **gate visual aprovado 2026-08-11 — FECHA O BLOCO 6A**"
status: vigente
vigente_desde: 2026-09-27
superseded_by: null
tipo_de_fatia: secao
historico: 46-historico.md
quando_consultar: "COMECE AQUI em tela de produto: rail, topbar, sidebar, conteúdo; SH1–SH23; drawer (SH12); material §93; conta e tema; tipos de destino do rail (SH22)."
em_uma_frase: "Cinco regiões nomeadas; o rail é peça sobre o canvas (radius-lg, calha nos quatro lados), 80 px, metal do §93, ativo em pílula clara."
nao_cobre: "O DS entrega o contrato POR REGIÃO; qual região o produto liga e o que ele põe dentro é decisão do projeto, e o app nativo é fronteira declarada."
conceitos: ["shell","rail","topbar","sidebar","navegacao","material","celular","arquetipo"]
vocabulario: ["rail","topbar","sidebar","chrome","landmark"]
sequencia: 93 de 184
bytes_do_corpo: 99614
md5_do_corpo: f7e5c7f00cbd00bea9b766f68f4d1715
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-componentes.md
---
<!-- gerado:inicio -->
**Em uma frase:** Cinco regiões nomeadas; o rail é peça sobre o canvas (radius-lg, calha nos quatro lados), 80 px, metal do §93, ativo em pílula clara.

**Vocabulário desta seção:** rail · topbar · sidebar · chrome · landmark

**O que esta seção NÃO cobre:** O DS entrega o contrato POR REGIÃO; qual região o produto liga e o que ele põe dentro é decisão do projeto, e o app nativo é fronteira declarada. — se é disto que você precisa, não preencha em silêncio: gere o pedido de cobertura (https://ds.seed.eng.br/pedidos/).

<!-- gerado:fim -->
## 46. Shell de aplicação — **`estável`** (v0.52) · SH1–SH23 · pattern F6 · suíte `suite-shell.mjs` 68/68 ✓ · render 18/0 · contraste 32/0 (na estreia; em 2026-09-15, com o SH19: 84/0 · 54/0 · 55/0; em 2026-09-27, depois da SH-P29 e da SH-P34, MANIFESTO §262 e §264: suíte 116/0 · render 121/0) · **gate visual aprovado 2026-08-11 — FECHA O BLOCO 6A**

> **Natureza:** pattern de **COMPOSIÇÃO** do F6, não componente novo — consome menu/dropdown
> (§35), tabs (§34), breadcrumb (§36), command palette ⌘K (§39), drawer (§31), avatar (§32),
> badge (§21), lista (§28), central de notificações (§33) e o botão (§1). **Nenhum componente
> nasce aqui.** É a mesma natureza do §33, o primeiro pattern F6 do sistema, e a fronteira que o
> Bloco 5 declarou desde 2026-08-06: *"sidebar/topbar é shell do F6, consome este bloco"*.
> **Camadas transversais que vestem esta seção, e onde a regra delas mora:** **material**
> (vidro e metal) no **§93** — o rail é metal escovado (MA2, receita `metal_rail`) e o
> painel lateral é vidro; **composição** (canvas, peça, calha, raio) no `seed-composicao.md`
> **CP1–CP32**; **tema e cor** em `02-tokens/seed-tokens.md`. **Regra geral do sistema:
> toda seção vestida por uma camada transversal APONTA a camada** — quem lê só esta seção
> tem de sair dela sabendo que o acabamento existe e onde procurá-lo. A regra nasce do
> defeito D-1 medido em 2026-09-19: um agente de IA leu o §46 inteiro e não achou o metal
> do rail, porque a ponte §46 → §93 só existia na direção inversa.
>
> **PRINCÍPIO-MÃE, decidido com o Rafael em 2026-08-11: CONTRATO POR REGIÃO, COMPOSIÇÃO LIVRE.**
> As cinco regiões são especificadas até o último detalhe; **qual delas o produto liga, e o que
> coloca dentro, é decisão do projeto do SIGA — não do Design System.** *Racional dele, adotado:*
> engessar a composição limita em vez de ajudar, e não gera problema de padronização — o que
> carrega a identidade é cor, tipografia, traço, densidade e comportamento do item ativo, não o
> arranjo das caixas. *O que o DS não abre mão:* **cada região se comporta igual em toda
> composição** (SH14) e **acessibilidade não é opcional em arranjo nenhum** (SH2, SH5, SH7, SH8).
>
> **Escopo do produto, decidido em briefing antes da pesquisa:** o SIGA é **web, responsivo,
> desktop-prioritário**, usado pela equipe — escritório como uso principal, campo como uso real.
> O menu **muda por perfil**. A navegação é **por ÁREA DO NEGÓCIO** (processo), não por
> ferramenta. O app nativo do cliente é **fronteira declarada**: quando existir, o DS entrega
> tokens e componentes, nunca layout de navegação, porque brigar com a convenção do iOS e do
> Android é perder. O site institucional é o **bloco 6B**, e nasce mobile-first.
>
> *(decisão registrada — ver Histórico da seção)*
>
> **REFERÊNCIA DE ARQUITETURA, e o que dela foi herdado.** O Rafael apresentou um layout de
> referência (`preview-clientes-v2.html`, 58.741 B, md5 `69f00537763e14ef907d2f8130c26a92`) no
> padrão de um produto de mercado, com instrução explícita: **"apenas ideia para entender o
> layout de construção"**. Regra que sai daqui e vale para todo bloco futuro: **de um layout de
> referência herda-se ESTRUTURA e COMPORTAMENTO; cor, tipografia e forma vêm do DS, sempre.**
> *Herdado:* o rail como camada acima da sidebar · a sidebar ser contextual ao rail · árvore de
> quatro níveis com fio de conexão · busca fixa e centralizada com o atalho impresso dentro ·
> seletor de contexto no topo à esquerda · contadores no fim da linha · ações que aparecem no
> hover · densidade compacta. *Descartado por não ser do sistema:* rail preto puro `#000000` (a
> superfície mais escura do DS é `#0B1419`), verde de sucesso `#2DBA7C` (o do DS é turquesa),
> gradiente terminando em `#D94B7D`, badge rosa, e neutros deslocados (`#9AA8B0` onde o DS tem
> `#90A6B3`; `#CBD3D8` onde tem `#ACBECA`) — a mesma deriva de hex digitado que custou as erratas
> E4 e E16 na Fase 5.

### 46.1 Decisões SH1–SH15, SH19 e SH20 (SH17, SH18, SH21 e SH22 vivem em 46.4, 46.5, 46.6 e 46.7)

> **O rail é peça sobre o canvas como as demais — `radius-lg`, calha nos quatro lados, sem
> borda** (a própria cor é a fronteira: 5,82/8,62 claro · 2,70/1,82 escuro contra o canvas).
> **O contrato de montagem de tela (ex-SH16) é LEI DO SISTEMA e vive no `seed-composicao.md`
> §1 (CP1)** — canvas `surface-subtle`, peça `surface-raised` + `radius-lg` + par sombra+anel,
> calha `sp-3`, nada encosta em nada. Registro completo no CP1 do `seed-composicao.md` v1.4.
> O shell é a primeira instância do contrato, não a dona dele.
>
> *(decisão registrada — ver Histórico da seção)*

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| **SH1** | **Cinco regiões nomeadas: rail · topbar · sidebar contextual · conteúdo · painel lateral.** Obrigatórias: **conteúdo** + **ao menos uma região de navegação**. As demais o produto liga conforme a tarefa | Composição é escolha de tarefa, não de identidade. O §33 já opera assim: não obriga ninguém a ter central de notificações — diz que, **se** tiver, é assim | Composição fixa em N arranjos canônicos (engessa arquitetura de produto de dentro do DS) · nenhuma região obrigatória (tela sem navegação nem landmark é beco sem saída) |
| **SH2** | **Toda região de navegação é landmark com NOME ACESSÍVEL ÚNICO**, e o nome **não contém a palavra "navegação"** — o leitor de tela já anuncia o papel. Nomes canônicos: "Áreas" (rail) · "Seções" (sidebar) · "Trilha" (breadcrumb) · "Conta" (menu do avatar) | ARIA11/W3C: landmark repetido exige nome único e significativo. O shell tem **três a quatro** `nav` simultâneos — sem nome, o usuário de leitor de tela recebe uma lista de navegações idênticas e não tem critério para escolher | `nav` anônimo · nome contendo "navegação" (redundância verbosa) · nomes iguais em regiões diferentes |
| **SH3** | **RAIL — contrato:** destinos de topo · **3 a 12** *(SH22, `SH-P34`, 2026-09-26: balão e destino direto contam no 3–12)* · **largura 80px no formato padrão (a Encurtada)** *(SH-P46, 2026-10-08: 56 px na Minimizada e 160 px na Expandida, opções do usuário — SH19)* · ícone do set §45 **+ rótulo sempre visível NO ESTADO PADRÃO, cada palavra CABE EM 68 px MEDIDOS — a régua é por LARGURA, não por letras** *(`SH-P31`, 2026-10-10, veredito dele, verbatim: *"a"* à pergunta "(a) trocar a regra para 'cabe em 68 px medidos' (régua por largura, não por letras)"; supersede o «≤9 caracteres por palavra» de agosto — medição: 68 px = o item de 72 px menos 2 px de padding de cada lado; a largura é a do TEXTO renderizado, no peso do ESTADO ATIVO (700, o mais largo; o de repouso é 600), a 11 px caixa-alta com o tracking do papel micro; instrumento: `render-shell.mjs` R2, que compara a caixa do texto com os px úteis do item, e a conta de letras SAIU do `suite-shell` SH3-05)* *(o estado recolhido só ícone é o SH19 — opção do usuário no desktop, nunca padrão; supersede parcial SH-P14, 2026-09-15)* · um ativo por vez · ordem estável · **abaixo da topbar, que ocupa a largura inteira da casca** *(supersede `SH-P24`, 2026-09-25, veredito dele verbatim "1 arranjo: sim" sobre o pedido "quero que o topbar seja fixo inicando acima da rail", MANIFESTO §250/§252; até então: "altura total, à esquerda da topbar")* · **acabamento: metal escovado quando a tela declara `data-material`** (§93 MA2, receita `metal_rail` → `.rail`) | O Material limita a 3–7, mas calibrado para tablet, com o rail substituindo a barra inferior; num ERP de desktop o rail é a espinha do produto. **Teto de 12 declarado como calibrado aqui, NÃO derivado de norma.** **Largura e limite de largura são MEDIDOS** *(texto de agosto abaixo preservado como histórico; o limite vigente é a régua por largura, `SH-P31`)* (conta de agosto, `medir-rail.mjs` — instrumento GASTO desde a errata E-CF-06 do §46.2, 2026-09-12: a conta viva é a do `mede-rotulo-rail.mjs`, 11 px com o tracking do papel micro; a remoção do arquivo é tabela de remoção): Montserrat 9px caixa-alta media **7,01px por caractere**; um rail de 64px tem 52px úteis e comporta 7 caracteres — três dos seis rótulos de exemplo transbordavam. 80px dão 68px úteis = **9 caracteres** *(a «9 caracteres» foi a tradução de agosto, a 9 px; ela envelheceu quando o papel `micro` foi a 11 px — E-CF-06 — e deixou de valer como régua: medido em 2026-10-10, no Chrome, a 11 px caixa-alta, peso do ativo 700: **«CONTRATOS» (9 letras) = 69,92 px e NÃO cabe** (69,11 px no peso de repouso 600), «ENGENHARIA» = 76,45 px, «Qualidade» (9 letras) = 68,55 px no ativo e NÃO cabe, «Comercial» (9) = 67,73 px e cabe, «Projetos» (8) 59,88 px, «Finanças» 58,50 px, «Compras» 56,97 px (600), «Obras» 40,23 px — a letra não prevê a largura: o mesmo número de letras cabe ou não)*. **Régua vigente (`SH-P31`): cada palavra do rótulo mede ≤ 68 px renderizada no peso do ativo; mede-se, não se conta.** *O rail cedeu de 64 para 80px porque "Comercial" (9) é nome legítimo de área de ERP — quem tem de caber é o negócio.* Rótulo truncado não é rótulo, logo o limite recai sobre a **palavra**. Altura total porque o rail é o nível MAIS ALTO de navegação — ficar dentro da moldura da topbar contradiz a hierarquia que ele representa *(razão de agosto, supersedida pela `SH-P24` em 2026-09-25: ele pediu a topbar de ponta a ponta acima do rail. O rail continua sendo o nível mais alto de NAVEGAÇÃO — a topbar não navega (SH10: identidade, busca e ações globais) —, e a hierarquia passa a ser lida na ordem: o global em cima, os destinos à esquerda. Medido no arranjo novo, a 1440 px: o rail perde 72 px de altura (60 da topbar + 12 de calha), a topbar ganha 92 px de largura, e o Tab passa pela topbar antes do rail)* | Rail só com ícone **como PADRÃO** (rótulo em tooltip não é descoberto — NN/g, *Icon Usability*, 27/07/2014: *"icon labels should be visible at all times"*; o §45 mede glifos a 24px, não a 24px sem contexto). *Supersede parcial `SH-P14` (2026-09-15, veredito dele "V-SH14.1 modo recolhido: b"): como OPÇÃO do usuário no desktop — nunca padrão, nunca resposta a tela estreita — o só-ícone é o estado recolhido do SH19; é a exceção que a própria fonte admite para "applications used every day" (NN/g, *Left-Side Vertical Navigation on Desktop*, 16/05/2021); o ERP é aplicação de uso diário pela equipe, e quem liga o recolhido já aprendeu os ícones. Levantamento datado de sete sistemas no MANIFESTO §227.4.* · rail abaixo da topbar (a posição que o Material recomenda, semanticamente errada aqui) *(descartado em agosto; é o arranjo vigente desde a `SH-P24`, 2026-09-25)* · teto de 7 (herdaria calibração de outro contexto — o erro da errata E7) |
| **SH4** | **SIDEBAR — contrato:** árvore de **até 4 níveis**, contextual à região acima. Quatro travas: **(a)** um ramo aberto por vez · **(b)** o ramo do item ativo abre sozinho ao carregar · **(c)** em modo estreito, níveis 2+ abrem em **flyout** · **(d)** quinto nível vira **tabs §34 dentro da tela** | O teto de 2 níveis foi proposto e **derrubado pelo Rafael com contraexemplo** (*Financeiro → Faturamento → Faturas emitidas*), e a referência confirma 4 na prática. As travas existem porque profundidade sem elas vira parede de 60 linhas. O flyout é **disclosure de links**, nunca `role="menu"` — distinção que o MN1 pagou caro para estabelecer | Árvore livre sem travas · nível 3 como navegação secundária dentro da página (solução de Fiori e Carbon; cai porque *explorar é ver a estrutura sem entrar nela*, e navegação secundária só aparece depois de já ter chegado) |
| **SH5** | **Item ativo: `aria-current="page"` + marca que SOBREVIVE AO GRAYSCALE, por região:** na **sidebar**, barra lateral de 3px mais peso tipográfico; no **rail**, a **pílula clara** (`turquesa-100` sobre o gradiente escuro) mais peso — nunca só fundo colorido de mesma luminância | Indicar o item atual exige as duas coisas: destaque visual e `aria-current` no link. E o **DF4** faz do grayscale gate estrutural do sistema — fundo colorido sozinho morre em cinza e em mono impresso. **Supersede SH-P10 (2026-09-13, veredito dele *"b-tirar-do-rail"*, MANIFESTO §209):** até então o rail também levava a barra; medido, a pílula clara sobre o rail escuro é **luminância** (fronteira 5,31/7,87, SH15-b) e sobrevive ao cinza sozinha — a barra, desenhada para a sidebar (onde o ativo é só um fundo quase igual ao papel), lia como resíduo ao lado da pílula. A barra saiu dos 8 moldes com rail; `suite-shell` SH5-04 e `suite-composicao` PX-01/PX-02 provam a ausência | Só fundo colorido · só `aria-current` (invisível para quem enxerga) · negrito sozinho (some em densidade compacta) · barra no rail (redundante com a pílula; supersedida) |
| **SH6** | **Navegação por perfil OMITE o item; ação indisponível MOSTRA com motivo** *(leva 30, `rail-3a`: o destino que AINDA NÃO TEM TELA não é «sem permissão» — segue o MN6 e fica visível com o motivo, SH27)* | O **MN6** decidiu que comando indisponível fica visível, com motivo, porque *"menu é inventário de comandos"*. Navegação é outra coisa: mostrar "Faturamento" a quem não pode entrar não ajuda ninguém **e revela a estrutura interna da empresa**. A distinção preserva o MN6 no domínio dele | Item bloqueado na sidebar (ruído permanente + vazamento organizacional) · omitir também na ação (o usuário não entende por que a operação falhou) |
| **SH7** | **Troca de rota move o foco para o CONTEÚDO** (`tabindex="-1"`, nunca o landmark em si), com **live region persistente** anunciando a tela | É o defeito nº 1 de aplicação de página única: o foco fica preso na navegação, o conteúdo troca e o usuário de leitor de tela não sabe. O alvo do foco **não pode** ser landmark, link nem botão — as três quebram por evidência documentada. O DS já tem o protocolo de live region no §1.13 | Não fazer nada (o comportamento padrão, e é o defeito) · focar o `main` como landmark (lê o conteúdo inteiro) · focar o primeiro link (some do fluxo de tabulação ao receber `tabindex="-1"`) |
| **SH8** | **Skip link como PRIMEIRO elemento focável**, visível ao receber foco *(camada: `--seed-z-salto` = 90, o degrau acima do tooltip — leva 30, `SH-P32` = «a»; §31.2)* | WCAG 2.4.1. Num ERP com dezenas de itens de menu, tabular por toda a navegação a cada tela é inviável — e o SH4 permite quatro níveis | Skip link permanentemente oculto (existe e não funciona) |
| **SH9** | **BUSCA fixa e centralizada na topbar, com o ATALHO IMPRESSO DENTRO DO CAMPO.** Ela abre a command palette §39 — é a mesma busca, com dois caminhos de entrada. **Escopo: navega, não consulta dado** | *Supersede da decisão anterior deste consolidado, que tirava o campo e deixava só o atalho.* O campo torna o atalho **descoberto por quem lê**, em vez de decorado por quem foi treinado — e a referência do Rafael mostrou isso antes de a spec ser escrita. Busca de registro depende de índice no SIGA: é produto, não DS. Filtrar o dado da própria tela é outra busca: a `busca-filtro` do §4, na barra de ferramentas do conteúdo (§4.7) | Só o atalho (aposta em treinamento) · campo que não abre o §39 (dois mecanismos de busca, duas fontes de verdade) · busca de registro no shell (fronteira de produto) |
| **SH10** | **TOPBAR — contrato de três zonas:** identidade e contexto à **esquerda** · busca ao **centro** · ações globais e conta à **direita**. Slots nomeados; o produto escolhe o que entra. **O título da tela vive no CONTEÚDO, não na topbar** | Prática consolidada de produto enterprise: topo para contexto global, lateral para navegação primária — assim as duas camadas param de disputar o mesmo espaço. O Fiori põe o título na shell bar e paga com uma barra que faz duas coisas | Título na topbar (duplica o `h1` do conteúdo e cria duas fontes de verdade sobre onde o usuário está) · topbar com conteúdo livre (vira depósito) |
| **SH11** | **Seletor de contexto existe, no topo à esquerda** | Estava reservado e desligado por falta de decisão de produto; a referência do Rafael decide que existe | Seletor dentro da sidebar (some quando a sidebar some) · nascer sem ele (redesenho depois) |
| **SH12** | **Em tela estreita, rail e sidebar colapsam num ÚNICO drawer §31 em regime MODAL** *(SH22, `SH-P34`, 2026-09-26: dentro do drawer não há prévia; o painel ancora na coluna da gaveta e o balão abre dentro do dialog, na frente do fundo (R17-19))* *(§95 AB1/AB2, 2026-10-10, V-AB1 a: **EXCETO no produto que satisfaz a régua da AB2** — de 3 a 5 destinos de topo, rótulo mais largo cabendo a 360 px, sem sidebar nem painel de escopo —, onde o rail vira a barra de abas de aplicativo e o drawer não existe; nunca os dois ao mesmo tempo)* | O CN6 escolheu **standard** porque o caso é *consultar sem sair da tela*. Navegação é o oposto: você escolhe e sai. Em tela estreita o drawer cobre o conteúdo — página interativa atrás seria mentira semântica, e o APG só admite `aria-modal` quando o fundo está de fato bloqueado | Drawer standard (incoerente com a tarefa) · rail persistente no celular (come 64 dos 360px) · sidebar espremida (não vira app, vira ERP ruim no celular) |
| **SH13** | **PAINEL LATERAL de detalhe: drawer §31 em regime STANDARD** — inspecionar um registro sem sair da lista | Aqui o caso **é** consulta lado a lado: ler → navegar à fonte → comparar. É o caso central que criou o regime standard no DW1 e que o CN6 já exerceu | Modal (perde o contexto da lista, que é justamente o que motivou o painel) · navegação para tela cheia (perde a posição de rolagem e a seleção) |
| **SH15** | **CHROME NÃO SEGUE O TEMA.** A superfície do rail e a tinta sobre ela são **fixas nos dois temas** — desde a CP-P3 (2026-08-14) a superfície é o gradiente `--seed-rail-background` (`turquesa-700 → turquesa-800`, CP20 adotado no gate G2) com tinta branca, e o item ativo é a **pílula clara** `turquesa-100` com tinta `turquesa-900` (SH15-b) — **desde a leva 30 (`SH-P27` = «b», folha de 2026-10-10) com NOME DE PAPEL, mesmos valores:** `--seed-rail-pill-bg` (`turquesa-100`) · `--seed-rail-pill-hover` (`turquesa-200`) · `--seed-rail-pill-pressed` (`turquesa-300`) · `--seed-rail-pill-text` (`turquesa-900`), invariantes de tema (`seed-tokens.md` §3e). **Acabamento: metal escovado quando a tela declara `data-material`** — a superfície não muda, o metal é camada por cima (§93 MA2, receita `metal_rail` → `.rail`; a intensidade é o token `--seed-mat-metal`) | **Achado da medição, não do desenho.** O rail consumia `surface-inverse`, que significa *"o oposto do tema"*: no escuro ele virava uma barra **clara** (`#F2F6F9`) dentro de uma interface escura, e o rótulo sobre o item ativo media **1,48**. O rail não quer ser o oposto do tema — quer ser estruturalmente escuro **nos dois**, como o chrome de aplicação que ele é. É o simétrico do **DG12** da Fase 5 (*tinta sobre dado não segue o tema, porque o objeto contrastado é claro nos dois modos*). Medido no estado atual: branco sobre os **dois extremos do gradiente** 6,32/9,37 · pílula 5,31/7,87 de fronteira · tinta da pílula 11,37. *(Errata **E-CF-05** fechada na v0.66: esta linha ainda descrevia o valor da era `cinza-900` — "e o item ativo usa `#006C62` fixo" — duas gerações atrás do artefato: a E-CF-04 consolidou o parágrafo do §46.2 e esqueceu esta linha. A REGRA nunca mudou; o VALOR mudou duas vezes: cinza-900 → turquesa-700 (v6.3) → gradiente (CP-P3).)* | `surface-inverse` (inverte por definição — era o defeito) · rail claro no claro e escuro no escuro (perde a âncora visual que faz o chrome ser reconhecível entre temas) |
| **SH15-c** | **O ANEL DE FOCO DO ITEM DO RAIL é DUPLO e NÃO é o `--seed-focus-ring` do §0** *(`SH-P38`, 2026-10-10 — promovido da casca ao canon por «a», exposto a veto; o código é da `SH-P29`, 2026-09-26, e NÃO mudou nesta promoção; texto abaixo = o que o código faz, conferido em `shell_bloco.py` e no molde)*. Item focado por teclado (`.rail-item:focus-visible`): `outline: none` e `box-shadow: inset 0 0 0 2px currentColor, 0 0 0 2px var(--seed-text-on-brand-deep)` — **duas faixas de 2 px, 4 px no total**: por DENTRO, 2 px da **tinta do próprio item** (`currentColor`: branca no item nu; `turquesa-900` `#00352F` na pílula do ativo — o mesmo par do rótulo), desenhada com `inset` (dentro da caixa do item, sem ocupar o vão); por FORA, 2 px de `--seed-text-on-brand-deep` (`#FFFFFF` nos dois temas — o rail não segue o tema). Zero desfoque, zero deslocamento. Só vale para o `.rail-item` (o rail inteiro, nos 3 formatos do SH19, claro e escuro); os itens do painel e do balão do rail têm foco próprio (`outline: 2px solid var(--seed-border-focus)` com `outline-offset: -2px`). **Contraste forçado:** o bloco `forced-colors: active` do molde devolve `outline: 2px solid Highlight !important` com `outline-offset: 2px !important` em todo `:focus-visible`, que se soma ao anel. **Régua:** `render-shell.mjs` R16 (16 casos: 2 dos 3 formatos — Encurtada e Minimizada — × 2 temas × ativo/inativo × repouso/sobrevoo; a Expandida não entra na R16 [não conferido: nasceu depois] — cada faixa do anel ≥ 3:1 contra as duas cores que a encostam, com o fundo composto sobre os DOIS extremos do gradiente, e o anel não invade o vizinho nem passa da borda do rail) | **Medido pela casa em 2026-09-26 (SH-P29), escrito aqui sem remedir nesta promoção:** o anel do §0 item 3 (`--seed-focus-ring` = 2 px de `surface-page` + 2 px de `border-focus`) falha no rail por três razões — segue o tema e o rail não (SH15); no claro o branco interno encosta na pílula `turquesa-100` e mede **1,19:1**; o `border-focus` encosta no gradiente e mede **1,96 / 2,91**; e os 4 px de anel passam do vão de 2 px entre itens, invadindo o vizinho. O anel duplo usa só o que já estava medido: a tinta do item sobre a pílula **11,37** (9,35 no sobrevoo, 7,39 no pressionado), o branco sobre o gradiente **6,32 / 9,37** — cada faixa encosta em cor ≥ 3:1 (WCAG 2.2 SC 1.4.11), e os 2 px de fora cabem exatamente no vão entre itens e na folga de 4 px até a borda do rail. `currentColor` e não o primitivo: a `SH-P27` deu nome semântico à tinta da pílula na leva 30 (`--seed-rail-pill-text`) e o anel a acompanha sem outra edição | `--seed-focus-ring` do §0 (1,19:1 na pílula; invade o vizinho) · `outline: auto` do Chrome (cor fora do controle da casca — era o que a casca fazia até a SH-P29) · anel de 4 px num só traço (não cabe no vão) |
| **SH14** | **Uma região NUNCA faz o trabalho de outra.** Se rail e sidebar coexistem, o rail é destino de topo e a sidebar é contexto *(SH22, `SH-P34`, 2026-09-26: a prévia do SH22 é a sidebar em pré-visualização, na mesma caixa; ancorar é carregar a sidebar, nunca criar uma terceira navegação)* | Duas navegações com o mesmo papel deixam o usuário de leitor de tela sem critério de escolha — quebra o SH2 por dentro. É a trava que permite a composição ser livre sem virar deriva | Sidebar como segundo rail · rail com itens de contexto |
| **SH19** | **FORMATOS DO RAIL (2026-09-15, `SH-P14`; TRÊS desde 2026-10-08, `SH-P46`): o rail tem três formatos, declarados no atributo `data-rail` do contêiner `app` (o mesmo elemento que nomeia o contêiner do SH12) — para a pessoa e no código: Minimizada = `recolhido` · Encurtada = `expandido` · Expandida = `largo`.** **Encurtada** (`expandido`) — o PADRÃO do SH3, 80 px, ícone 20 + rótulo visível embaixo, como TODA tela nasce. **Minimizada** (`recolhido`) — **56 px** (item `sp-12` = 48 + calha `sp-1` = 4 de cada lado), item **48 × 48**, ícone **24 px** (IC4 "navegação"), rótulo FORA DA VISTA e NO DOM (clip de 1 px, nunca `display:none`: o nome acessível do destino não muda) que reaparece como **tooltip** em `:hover` e `:focus-visible` (§23: X1 é o rótulo · X3 Esc fecha sem mover o foco, corredor hoverable, carência de fechamento `dur-expressive` · X6 par `surface-inverse`/`text-inverse`, raio 6, a 8 px do alvo; o do PRIMEIRO destino desce para não cobrir o seletor de contexto — interseção 0 px², medida). **Expandida** (`largo`) — **160 px** = `sp-16` + `sp-24` (o CSS soma os dois tokens), item em LINHA com a mesma altura do padrão (58 px: nenhum destino se move na vertical ao trocar de formato), ícone 20 + rótulo em caixa de sentença no papel `corpo-denso` 600 (700 no ativo), o botão da base com o texto ao lado do ícone. **A Expandida CAI para a Encurtada abaixo do limiar medido** — contêiner `app` abaixo de 1080 px com sidebar (janela 1104) e de 1050 px com o escopo do SH20 (janela 1074): o conteúdo nunca fica abaixo dos 616 px que o padrão entrega a 1024 com sidebar; sem sidebar nem escopo ela nunca cai pelo limiar (o piso é o do SH12, 860); **com um painel lateral aberto (§31.4) ela também cai para a Encurtada quando, com os 160 px, o conteúdo ficaria abaixo do piso de 640 px do painel e os 80 px o levam a 640 px ou mais** (`SH-P69`: o piso do painel prevalece sobre o de 616 px; o módulo do painel marca `data-rail-cede="painel"` no `.app`, o rail fica em 80 px, o rótulo curto vale como na Encurtada, e a marca sai quando o painel fecha ou o espaço volta; medido: chat a 1104 e 1127 px, mensageria de 1030 a 1109 px, detalhe de 1074 a 1097 px; o estado depende só da largura, nunca do caminho da janela); caída (pelo limiar ou pelo painel), **a preferência fica intacta** e o botão fica indisponível (`aria-disabled`) com o motivo no nome. **Gatilho: um BOTÃO no próprio rail, na BASE** (`.alterna-rail`, 48 × 44 — na Expandida, a largura do item —, a 8 px da base, último focável do rail — a ordem de Tab dos destinos não muda): **alterna Encurtada ↔ Expandida** e, da Minimizada, volta à Encurtada; `aria-expanded` = "o rail está na Expandida"; nome acessível "Expandir áreas" (Encurtada) · "Encurtar áreas" (Expandida) · "Mostrar rótulos das áreas" (Minimizada); ícones Lucide `chevrons-right`/`chevrons-left`, NM4 ②. **A Minimizada só se escolhe na preferência** (menu de conta, SH21). **Sobrevoo que expande** (`data-rail-sobrevoo` = `ligado` | `desligado` no mesmo `.app`, nasce desligado, vale SÓ na Encurtada): com o ponteiro de mouse no rail por 300 ms o rail mostra a Expandida POR CIMA do conteúdo, sem reflow (a coluna da grade segue com 80 px; fronteira pelo par sombra + anel do CP17, faixa 60 de chrome — no escuro o mesmo par do rail de hoje), e fecha 500 ms depois de o ponteiro sair (as constantes do SH22); Esc fecha e não reabre até o ponteiro sair (SC 1.4.13); clicar num destino fecha; só `(hover: hover)` e `(pointer: fine)` — nunca no toque nem abaixo do SH12 —, com a largura animada em `--seed-dur-productive` (150 ms; movimento reduzido: de uma vez) desde a leva 48 (`SH-P71`; veredito dele, folha 14, Q5 = c, 2026-10-28, verbatim: *"aplicar 150 ms direto."*; antes era "sem animação de largura", a D14 do SH29, SUPERSEDIDA; o escopo no sobrevoo é decisão do agente, exposta a veto); a troca de formato do rail anima do mesmo jeito, e o Q3, o piso de 640 px do painel (PL10) e a cessão do rail leem a largura FINAL, nunca o meio da animação; **o foco de teclado NÃO abre**; com a prévia de um destino `painel` (SH22) a prévia só começa a contar depois do rail aberto e, quando ela abre, o sobrevoo CEDE — as duas camadas nunca juntas. **Quem LEMBRA formato e sobrevoo é o PRODUTO**: preferência do usuário, GLOBAL (nunca por tela), nasce Encurtada com o sobrevoo desligado — as telas de referência demonstram e não persistem nada (§46.5, porta do SIGA). **Nenhum formato existe abaixo do limiar do SH12 nem no toque** (§23 X2): dentro do drawer o rail volta a 80 px com rótulos e o botão some. Emitido pelo módulo único `shell_bloco.py` nas doze telas; a régua CP-13 aceita 80, 56 ou 160 conforme o atributo; a régua do comportamento é a `render-rail.mjs` (R18 limiar, R19 sobrevoo, R20 botão e menu). *(SH22, `SH-P34`, 2026-09-26: no recolhido, o tooltip de um destino painel cede à prévia quando ela abre — nunca as duas camadas ao mesmo tempo (medido, R17-18))* | **Pedido dele, verbatim (2026-10-08, `SH-P46`):** *"preciso que crie um novo formato para o Rail. hoje temos 2, minimizado e encurtado, crie o formato expandido. o usuário poderá optar pelo formato que quiser. o formato padrao continua o mesmo, ele pode expandir e encurtar pelo botao ou alterar suas preferencias. no formato encurtado quero que nas preferencias vc coloque opçãp de expandir para o formato expandido se passar o mouse em cima"*. Estudo `SH-P46` (2026-10-08): o custo é de 80 px de conteúdo em toda largura (12 de 12 telas; a 1024 com sidebar, 616 → 536 px); o limiar devolve os 616; a prévia do SH22 e o sobrevoo disputam o ponteiro (7 de 8 destinos da `tela-shell` são painel). **Veredito dele, verbatim (2026-10-08): *"pode seguir / folha nao abriu"*** — aprova as 8 saídas marcadas "← leitura da sessão" (Q1 nomes · Q2 160 px · Q3 limiar · Q4 a prévia cede · Q5 o foco não abre · Q6 a) o botão alterna Encurtada ↔ Expandida · Q7 rádios e checkbox no menu de conta · Q8 a fronteira no escuro); ele não viu as imagens antes do "pode seguir", e as telas regeneradas vão a ele antes de publicar (veto aberto). Na implementação a altura do item na Expandida ficou a do padrão, não os 48 px do protótipo: medido, com 48 o 3.º destino subia 20 px ao abrir o sobrevoo e saía de baixo do ponteiro (a prévia nunca abria, R19-13) — exposto a veto. *Até 2026-10-08:* Pergunta dele no gate do Grupo 2 (MANIFESTO §226.5): *"o Rail pode ser minimizado pra a esquerda aparecendo apenas o icone e escondendo o nome? as telas devem ser responsivas."* Estudo `SH-P14` (§227.4): cinco de sete sistemas lidos têm o modo recolhido, quatro "só ícone" a 48 px com rótulo em tooltip, todos como ESCOLHA do usuário, nenhum como padrão em desktop largo nem no celular; +24 px de conteúdo medidos a 1440/1280/1024/900. **Veredito dele, verbatim (2026-09-15, MANIFESTO §229): *"V-SH14.1 modo recolhido: b · V-SH14.2 gatilho: a · V-SH14.3 posição do botão: a · V-SH14.4 quem lembra: a · veto: nenhum"*** — b = só o recolhido (V1 + V2, sem o expandido de 220 px); a = botão; a = base; a = preferência do usuário, global, nasce expandido. A "responsividade" da pergunta já tem dono (SH12): o recolhido é opção de desktop, não resposta a largura. | *[superada pelo veredito de 2026-10-08, `SH-P46`: a Expandida existe, com 160 px, opcional e com o limiar do Q3; texto de setembro:]* Expandido de 220 px com rótulo em linha (a sidebar de 280 px JÁ é a expansão do rail — SH14; custaria 140 px de conteúdo: a 1024 a tabela do exemplo quebra) · gatilho por largura da janela (Fluent `Auto`: colidiria com o degrau único do SH12 a 860 e criaria um segundo limiar) · *[superada pelo veredito de 2026-10-08, `SH-P46`: o sobrevoo existe como PREFERÊNCIA, nasce desligado, só na Encurtada e só com ponteiro fino, com o contrato da 1.4.13; texto de setembro:]* sobrevoo que expande (Carbon: abre sem querer, briga com 1.4.13 e com o toque) · recolhido como padrão ou como resposta a tela estreita (NN/g 2014; aí o certo é o drawer) · `display:none` no rótulo (apaga o nome acessível) · `title` como nome (X1) · persistir nas telas de referência (fronteira de produto, CN4) · *(SH-P46, 2026-10-08)* Expandida de 146 px (sem folga para rótulo maior que "Comercial") ou de 176 px (−96 px de conteúdo) · nenhum limiar (536 px a 1024 com sidebar) · o botão em ciclo pelos três formatos (sem `aria-expanded`; o nome muda a cada clique) · o botão com menu de formato (dois cliques em toda troca) · o foco de teclado abrir o sobrevoo (o rail "respiraria" a cada Tab) · a prévia do SH22 deslocada para a borda do rail aberto (pularia 80 px ao ancorar) · item de 48 px na Expandida (move o destino sob o ponteiro, medido) |
| **SH20** | **O painel `.escopo` (árvore de filtro de 250 px, em quadro/detalhe/gantt) É UMA EXTENSÃO DO RAIL:** some do conteúdo no MESMO limiar do SH12 (860 px de contêiner `app`) e reaparece dentro do MESMO drawer que já leva rail e sidebar, MOVIDO (não copiado) pelo mesmo `<script>` — nunca um acordeão nem um limiar próprio | Achado `SH-P12`: o `.escopo` tinha regra PRÓPRIA, mais estreita (420 px), deixando só 274 px de conteúdo entre 860 e 420 px, e SUMINDO SEM VOLTA abaixo de 420 px (lacuna de acessibilidade nomeada `SH-P15`). Medido pelo agente que preparou o gate (`scratchpad/grupo-4/SH-P12/RELATORIO.md`): a Alternativa A custa ≈ 6 linhas em 4 arquivos reusando um mecanismo já coberto por suíte (foco, Esc, `aria-expanded`); a B (acordeão com `<details>`, limiar próprio de 620 px) custaria 45–60 linhas novas sem cobertura própria. **Veredito dele, verbatim (2026-09-16, MANIFESTO §233.1): *"V-SH12.2 (Escopo rail × acordeão): a (vira rail) · veto/observação: nenhum"*** | Acordeão independente com limiar próprio a 620 px (Alternativa B — mais código novo, sem suíte, e o número "independente" calculado convergia para perto do 860 do SH12 de qualquer forma) · manter a regra própria de 420 px sem afordance de reabrir (a lacuna `SH-P15` ficaria sem dono) |

### 46.2 Anatomia, tokens e fronteiras

**Rail:** largura **80px** (SH3 — 68px úteis; cada palavra do rótulo cabe em 68 px MEDIDOS, `SH-P31`; "Comercial" cabe: 67,73 px no ativo); superfície
**fixa nos dois temas** (SH15 — o rail NÃO consome `surface-inverse`, que foi o defeito medido a
1,48), hoje o **gradiente da rampa da marca** via semântico próprio `--seed-rail-background`
(`turquesa-700 #006C62 → turquesa-800 #005048`; CP20 do `seed-composicao.md`, **adotado no gate
G2 de 2026-08-14 e executado na CP-P3** — extremos medidos 6,32/9,37, tinta passa nos dois, nunca
na média); hover e pressionado do item consomem os overlays de chrome do SUP-6
(`--seed-chrome-overlay-hover/-active`, medidos **em composição**: 4,88/6,82 e 4,68/6,50);
ícone 24px do §45 + rótulo em micro-caps; item ativo pela regra do SH5; alvo de toque ≥44px.
*(Errata E-CF-04 fechada na v0.65: este parágrafo dizia 64px, `surface-inverse` e implicava
`cinza-900`. Atualizado de novo na v0.66 pela CP-P3: a redação "gradiente admitido — adoção
pendente de gate visual" ficou falsa após o gate.)*
**Topbar:** altura 60px; `surface-raised` com borda inferior `border-subtle`; z-index **60** (a
mesma faixa de chrome da escala 60<65<70<75<80 fixada no Bloco 4). **Desde a `SH-P24` (2026-09-25) ocupa a largura inteira da casca, ACIMA do rail:** a casca é uma grade 2 × 2 (`grid-template-columns: auto minmax(0, 1fr)`) com a topbar nas duas colunas da primeira linha, e o rail e a `.coluna` na segunda; no código a topbar é o PRIMEIRO filho do `.app` (ordem de Tab = ordem visual, WCAG 2.4.3); o vão até o rail é a margem da topbar (`sp-3`), para a tela sem topbar (SH-P17) usar a mesma grade sem 12 px a mais em cima. Emitido pelo módulo único `shell_bloco.py`; medido em 12 de 12 telas com casca (`render-shell.mjs` TB-01 a TB-03 na `tela-shell`). **Sidebar:** largura 280px,
`surface-page`; indentação progressiva com fio de conexão em `border-subtle`; contador opcional
no fim da linha em mono; linha na densidade **compacta** do §40 (33px medidos), com alvo real de
toque garantido pela linha inteira, como no §28. **Conteúdo:** `main` com `tabindex="-1"` para o
SH7. **Painel lateral:** §31 integral em standard, z-index 65.
**Colapso em tela estreita (SH12) — o número, fixado em 2026-09-15 (`SH-P13`):** o limiar é **860 px de
CONTÊINER `app`** (`@container app (max-width: 860px)`), nunca de janela — regra de reflow responde ao espaço
da aplicação (D4/CP27; a mesma tela dentro de um painel estreito colapsa igual). Vive no molde do shell desde
2026-08-14 (render conferido a 840/420/360, MANIFESTO §30) e desde a `SH-P13` é EMITIDO pelo módulo único
`shell_bloco.py` para as onze telas com casca. Abaixo dele: rail e sidebar (`nav` "Seções") somem; o botão **☰**
(`.abre-nav`, 44 × 44, PRIMEIRO item da zona esquerda da topbar, SH10 — e, em produto SEM topbar, PRIMEIRO elemento da coluna de conteúdo, classe `.abre-nav-solto`, na faixa onde a topbar estaria: `SH-P17`, 2026-09-20, porque sem ele a tela ficaria abaixo do limiar com rail e sidebar ocultos e NENHUMA afordância para reabri-los; `aria-haspopup="dialog"`) abre um
`<dialog class="nav-drawer">` MODAL (`showModal()`, §31 DW3) de **300 px, máx. 88 % da janela, encostado à
esquerda**, com superfície `surface-page`, sombra `shadow-overlay` + anel e o `::backdrop` do §30; rail e sidebar
são **MOVIDOS** para dentro (não copiados: cópia duplica `id` e deixa botão sem ouvinte) e **devolvidos ao fechar**
(botão Fechar ou Esc); o foco entra no drawer e volta ao ☰ ao fechar. **Desde a `SH-P12` item 2 (SH20, veredito dele "a", MANIFESTO §233.1, 2026-09-16) o painel `.escopo`** de quadro/detalhe/gantt **também entra** — é uma extensão do rail, some e é MOVIDO junto pelo MESMO seletor. *Medido em 2026-09-15 nas onze
telas (Chrome, `mede-casca.mjs`): colapsa a ≤ 884 px de janela (884 − 24 px de calha = 860 de contêiner) e volta
a 885; a 390 e 768 px, 44 de 44 (tela × tema) com rail oculto, `scrollWidth` = janela, drawer modal com `nav`
"Áreas" (+ "Seções" onde há sidebar); a 1024 e 1366, 44 de 44 com rail de 80 px. Linha de base antes do conserto:
oito das dez telas transformavam o rail numa FAIXA horizontal de 74 px a 390 px — a forma que o SH12 descartou
por outro caminho — e duas (quadro, gantt) mantinham a coluna de 80 px com 274 px para o conteúdo; a 768 px as
dez mantinham o rail.* O número 860 não deriva de norma: é o degrau em que rail (80) + sidebar (280) + calhas
deixariam menos de ~480 px ao conteúdo — calibrado no shell e aprovado em render; quem o mudar remede as onze.
**Estado recolhido do rail (SH19) — fixado em 2026-09-15 (`SH-P14`, veredito dele em MANIFESTO §229):** o contêiner `app` declara `data-rail="expandido"` (nascimento) ou `data-rail="recolhido"`. Recolhido: rail **56 px** = item `sp-12` (48) + `sp-1` (4) de cada lado (padding `8px sp-1`, `overflow: visible` — o tooltip sai pela direita; custo declarado: nesse estado o rail não rola, e 12 destinos × 50 px + botão pedem ≥ 668 px de altura); item **48 × 48**, ícone **24 px**; o `span` do rótulo fica no DOM com clip de 1 px e, em `:hover`/`:focus-visible`, vira o tooltip do §23 (papel `rotulo` em caixa de sentença, `surface-inverse`/`text-inverse` — 13,86 claro · 12,75 escuro, medidos por token e no pixel —, `radius-3`, `shadow-overlay`, z-index 80, a `sp-2` do item; no escuro com borda `border-default`); o tooltip do PRIMEIRO destino nasce com o topo a `sp-2` abaixo do item (4 px abaixo da base da topbar), porque centrado cobriria o seletor de contexto — medido: interseção 0 px² com a topbar e com `#b-contexto` nos seis destinos, nos dois temas. **Botão `.alterna-rail`:** último filho do `nav.rail`, 48 × 44, `margin-top: auto` (8 px da base), transparente sobre o rail com sobrevoo/pressionado pelos overlays de chrome (SUP-6, como o item não ativo); `type="button"`, `aria-expanded` (`true` de nascimento), nome "Recolher áreas"/"Expandir áreas"; dois SVG no DOM (Lucide `chevrons-left`/`chevrons-right`), o `aria-expanded` escolhe qual aparece; `alterna_rail()` troca o atributo e o nome — e NÃO grava nada. Dentro do `dialog.nav-drawer` (fora do `.app`) o seletor do estado não alcança: o rail volta a 80 px com rótulos e o botão fica oculto (medido a 390 e 768 com o atributo ligado, 44 de 44). *Medido em 2026-09-15 nas onze telas (`render-shell.mjs` R5–R9, `mede-rail.mjs`): padrão → recolhido = rail 80 → 56, item 72 × 58 → 48 × 48, ícone 20 → 24, conteúdo +24 px em toda largura com rail visível; o único pixel novo em repouso é o glifo do botão na base do rail (64–73 px diferentes por tela × tema, caixa x 46–57).*

**Nenhum par de cor novo** — mas **compor pares medidos separadamente não garante que a
combinação passe**, e o `contraste-shell.py` provou isso: a primeira execução deu **22 PASS ·
8 FAIL**. Correções, todas por medição: o rail deixou de consumir `surface-inverse` (SH15) · o
contador e o *placeholder* saíram de `text-muted` (3,38 e 3,11 no claro) para `text-secondary`
(6,55 e 6,03) · o item ativo da sidebar deixou de ser texto de marca (4,23) e passou a **texto
primário com barra em `text-brand`** — a cor não carrega o estado, quem carrega é a barra e o
peso (SH5) · a sigla do seletor de contexto saiu de branco sobre `surface-brand` (2,71) para
branco sobre `surface-brand-deep` (6,32). Placar final: **32 PASS · 0 FAIL**.

> *(decisão registrada — ver Histórico da seção)*
>
> **✅ FECHADA em 2026-08-14, pela via prevista (gatilho GI2 + decisão do Rafael: *"vamos
> resolver logo"*):** a camada 2 foi editada pela CP-P3 (gêmeos v1.11) e, na mesma janela, os
> gêmeos v1.12 promovem o empréstimo a semântico — **`--seed-border-interactive`** = `cinza-500`
> `#788F9D` nos dois temas, medido contra as **seis superfícies** onde borda de componente
> aparece (3,38/3,38/3,11 claro · 4,50/5,51/5,05 escuro, todos ≥3,0), slot dark declarado
> (coincidência medida, não invariância). O campo de busca do shell consome o semântico desde o
> preview v0.3 — **nenhum primitivo é mais consumido por exceção no §46**. *Alternativa
> descartada com número:* `cinza-600` também passa (3,21–4,74), mas mudaria a cor RENDERIZADA
> que o gate visual já aprovou, sem motivo — a pendência pedia promoção de expressão, não de
> valor. A metade "separação de peça" já havia fechado no CP17 (par sombra+anel).

> **Errata E-CF-06 (2026-09-12, F10.4 / `MA-P6`) — a conta do SH3 envelheceu, e o rótulo ativo vazava da pílula.** O SH3 diz *"Montserrat 9px caixa-alta mede 7,01px por caractere; 68px úteis = 9 caracteres"*: era verdade em agosto, quando o rótulo tinha 9 px. Na v1.14 dos gêmeos o papel `micro` passou a **11 px** e o rótulo do rail o consome desde então — **medido em 2026-09-12** (Chrome real, `mede-rotulo-rail.mjs`): "COMERCIAL" a 600 = **68,94 px** e a 800 = **69,52 px** sem tracking; com o `.02em` local (0,22 px × 9) o ativo media **71,5 px** dentro de um item de 72 px com 2 px de padding — a caixa de linha ia de x=18 a x=89,5 e a pílula acabava em x=88. Era isso que a régua de contraste rasterizado (F10.3) acusou como `MA-P6`: um pixel do "L" final, cobertura total, fora da pílula, turquesa-900 sobre o gradiente do rail = **2,08**. Conserto no **gerador** (`gen-shell.py` v0.9, molde): a sobrescrita local de tracking sai e o rótulo consome o tracking do próprio papel (`--seed-txt-micro-ls`, −0,2 px) — o ativo cai para **67,7 px** e cabe nos 68 úteis; `max-width: 72px` no span como rede (excesso simétrico pelo `align-items: center`, nunca só pela direita). O contrato SH3 (rail 80 px · item 72 px · ≤ 9 caracteres por palavra) **não muda**; muda a conta que o justifica: **a 11 px, 9 caracteres cabem nos 68 px úteis só com o tracking do papel** (−0,2 px), não com tracking positivo. Depois do conserto: `render-shell.mjs` **34 · 0** (o R2 voltou a medir "nenhum rótulo transborda" de verdade — com o span preso em 68 px ele passava enquanto o texto vazava do span) e a régua RC devolve o shell **sem texto abaixo do piso nos dois temas**.
>
> **Pendência `SH-P9` (2026-09-12) — peso 800 sem face 800.** O shell e o painel declaram `font-weight: 800` (rótulo ativo do rail, KPI, botão da solução, sujeito do hero) e os moldes só carregam Montserrat 400/500/600/700 (`03-assets/fontes/montserrat/` não tem ExtraBold): o navegador **sintetiza** o 800 a partir do 700 — medido: 700 e 800 têm o **mesmo avanço** (69,52 px), o que um ExtraBold real não teria. A guarda TP1 (`guarda-tipografia-viva.mjs`) não vê, porque mede se as faces DECLARADAS carregam, não se os pesos PEDIDOS têm face. Duas saídas, para o gate: (a) trazer o ExtraBold para o acervo e declará-lo nos moldes — muda o render de todo texto 800 e **re-mede o rail** (o rótulo cresce); (b) baixar os 800 para 700 nos moldes — o SH5 pede *"mais peso"* que o 600, e o 700 cumpre. Custo medido de (a): um arquivo TTF novo (licença OFL, a mesma), 2 moldes, e a régua RC nas duas telas; de (b): 2 moldes e a `suite-shell.mjs` (SH5-05 exige 800 no ativo). Dono: sessão, com o veredito dele. ✅ **FECHADA em 2026-09-14 — por APLICAÇÃO da sessão, exposta a veto (MANIFESTO §223.4): não houve gate, porque a marca §4.1/§4.3 já decide (o sistema usa 400/500/600/700; 800 e 900 são display de marketing) e a mudança não altera um pixel — perguntar seria pedir só a concordância dele.** Aplicado: os quatro papéis passam a declarar **700** nos dois moldes (e a `suite-shell` SH5-05, a `suite-painel` PN13-03/AC-09). **Errata do enunciado, medida antes de aplicar:** o navegador NÃO sintetiza o 800 — o Chrome só engrossa por síntese quando a face casada pesa menos de 600; com a face 700 carregada, "800" rende a própria 700 sem alteração: as capturas inteiras das duas telas nos dois temas saíram **pixel-idênticas** entre o estado anterior e o 700 declarado (0 px diferentes, `mede-sh-p9.mjs`), e a régua RC devolveu o mesmo placar (4 PASS · 0 FAIL). Logo (b) não muda um pixel: torna a declaração verdadeira. A alternativa (a) — o ExtraBold real da mesma linhagem (instância wght=800 da variável v9.000, medida byte a byte igual aos cinco TTF da casa) — foi renderizada nos dois temas: o rótulo "COMERCIAL" a 11 px passaria a medir **68,375 px** (−0,375 px além dos 68 úteis do SH3; a RC ainda passava, 11,27 no pior pixel) e o H1 de toda tela (`titulo-tela`, 800) engrossaria em todas as telas; descartada porque a marca §4.1/§4.3 reserva 800/900 ao display de marketing — o sistema usa 400/500/600/700. O censo achou o mesmo `800` sem face em mais 24 moldes, no token `--seed-txt-titulo-tela-weight` e no KPI em JetBrains Mono (que só tem 400/500/700): pendência própria, com a TP1-d medindo "peso pedido tem face".
>
> *(decisão registrada — ver Histórico da seção)*

**Fora do shell, declarado:** que menus existem e o que há dentro deles (**projeto do SIGA**) ·
qual perfil vê o quê (**regra de negócio**) · persistência do estado da sidebar **e do estado do rail** (SH19: preferência do usuário, global, nasce expandido — V-SH14.4 = a; a tela de referência nunca persiste)
(**produto — Lovable/Supabase**, mesma fronteira do CN4) · busca de registro (**produto**) ·
dashboard e composição de painel (**bloco 6C**) · site institucional (**bloco 6B**) · app nativo
do cliente (**fora do DS**: tokens e componentes sim, layout de navegação não) · **o que o slot
de IA da topbar abre** (sub-bloco próprio da F6 — o slot existe, o destino não é especificado
aqui).

**Consequência declarada da navegação por PROCESSO:** como o mesmo objeto é alcançável por mais
de um caminho, o **breadcrumb §36 deixa de ser decoração** e passa a responder *por qual caminho
eu cheguei* — é ele que desambigua, não a sidebar.

### 46.3 Os 7 testes

1. **Nenhum par de cor novo**; todos herdados e medidos.
2. **Item ativo nunca depende só de cor** *(e, no estado recolhido do SH19, o rótulo nunca sai do DOM: `title` não é nome, `display:none` não é clip — `suite-shell` SH3-04)* — na sidebar barra + peso, no rail pílula clara + peso, sempre com `aria-current` (SH5; SH-P10).
3. **Grayscale:** rail, sidebar e ativo permanecem legíveis (DF4 como gate estrutural).
4. **Regra do um:** um item ativo por região; uma região por papel (SH14).
5. **Landmarks:** três a quatro `nav` simultâneos, todos com nome único, nenhum contendo a
   palavra "navegação" (SH2).
6. **Troca de rota:** foco no conteúdo e anúncio na live region, sem foco em landmark, link ou
   botão (SH7); skip link é o primeiro focável (SH8).
7. **360px:** rail e sidebar colapsam em drawer modal único; nada transborda; alvos ≥44px (SH12) — *e, desde a `SH-P14` (SH19), com `data-rail="recolhido"` ligado o drawer traz o rail a 80 px com TODOS os rótulos visíveis e o botão de alternar oculto (o recolhido não sobrevive ao colapso; `render-shell` R9).* *Até a `SH-P13` (2026-09-15) só a `tela-shell` cumpria; desde então as onze telas com casca, medidas a 390/768 nos dois temas (44 de 44).*

*(Estado: **`estável` desde 2026-08-11**, por "aprovo" explícito do Rafael após o gate visual
sobre o preview v0.1. **Quatro camadas cumpridas:** `suite-shell.mjs` **68 PASS · 0 FAIL** —
*prova de que as guardas são reais:* contra um preview com 5 defeitos deliberados, reprova em
**8**; `render-shell.mjs` em Chrome real **18 PASS · 0 FAIL**; `contraste-shell.py` **32 PASS ·
0 FAIL** após as correções que a própria medição exigiu; e o gate visual humano. **Pendência que
o bloco levou consigo: SH-P1**, que é da camada de tokens, não do shell — **fechada em
2026-08-14 pelos gêmeos v1.12** (`border-interactive`; fechamento completo na própria
pendência, acima).)*

### 46.4 SH17 — no PRODUTO, toda tela de aplicação vive dentro do shell; o gabarito é o conteúdo (F11.1, 2026-09-14)

> *(decisão registrada — ver Histórico da seção)*

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| **SH17** | **No produto (SIGA e apps internos), TODA tela de aplicação vive dentro do shell §46: o shell é a CASCA (rail · topbar · sidebar · conteúdo, pelo princípio-mãe "contrato por região, composição livre") e o gabarito A1–A20 é o CONTEÚDO da região `conteudo`.** A tela de referência de um gabarito pode ser publicada SEM a casca (raiz `tela`, CP28) para medir o conteúdo isolado — isso é decisão de BANCADA, nunca de produto. Fora do shell só o que não é tela de aplicação: **autenticação** (A19 — antes de haver sessão), **página pública/institucional** (A5, §47 — raiz `pagina`) e o **documento quando EXPORTADO** (A13 em PDF/impresso; na leitura dentro do app ele vive no shell). Quem constrói uma tela começa pelo §46 e só então abre o gabarito do conteúdo. | O §46 diz que "qual região o produto liga é decisão do ERP" — e é; mas *se o shell existe* nunca foi pergunta: o ERP o decidiu no briefing de 2026-08-11 e todas as telas aprovadas com rail (quadro, lista, tabela, detalhe, gantt, chat, referência) o provam. Faltava a frase, e a ausência custou uma tela errada e duas rodadas de gate. | Escrever a casca dentro de cada gabarito (duplicaria o shell 16 vezes — o CP28 nasceu justamente para NÃO fazer isso); deixar como estava (o primeiro consumidor de fora errou, e a regra da casa diz que erro do criador é o aviso de que o acervo ensina errado). |

**As 25 telas de referência publicadas — 20 gabaritos, porque o A1 tem TRÊS telas (os regimes do shell: com topbar, sem topbar `SH-P17`, e sem topbar com barra de abas, leva 36) e o A2, o A7 e o A23 têm DUAS cada (a tela de referência composta e a lista; o quadro e o funil; o chat em forma PAINEL e a mensageria em forma TELA, leva 36), e as duas telas do acesso ao SIGA, A27 e A28, têm uma cada (leva 39, letra v, 2026-10-12: `tela-portal-cliente` e `tela-envio-fornecedor`, aprovadas por ele na folha 7), e as telas de estado de sistema, A29, têm uma (leva 43, 2026-10-18: `tela-estado`, §96, pedido `VI2`), e as duas vistas do parceiro indicador, A30 (a área logada, `tela-portal-parceiro`) e A31 (a página pública do link, `tela-cadastro-indicado`), têm uma cada (leva 46, 2026-10-25, `VT-P18`: aprovadas por ele na folha 9, M1 e M2 «ok») — [contagem corrigida em 2026-10-11 pela letra f: o texto dizia 17, o `TELAS` do gerador da vitrine mede 19; desde 2026-10-12 (`VT-P15`) este número e o dos gabaritos são MEDIDOS: a `guarda-contagem-telas.py` lê esta frase, a tabela abaixo e as páginas da vitrine e reprova se divergirem, dizendo o número a escrever] —, medidas no disco em 2026-09-14, com a linha do regime sem topbar acrescentada em 2026-09-20 (coluna "rail funcional" medida em 2026-09-15).** *(Errata da `SH-P17`: esta frase dizia "os 16 gabaritos" e 16 era o número de TELAS — o A2 sempre teve duas; a vitrine repetia o erro contando `len(TELAS)`.)* A coluna
"referência traz a casca" é MEDIDA no HTML (`class="rail"` presente — a casca é o RAIL, a navegação que o
SH1 torna obrigatória; a topbar sempre foi opcional pelo SH1, e desde a `SH-P17` (2026-09-20) a
`tela-shell-sem-topbar` é o gabarito disso: até ali a medição exigia as DUAS classes e teria lido a tela
nova como "sem casca", que é falso); a coluna "rail funcional
(medido)" também é medida — **sim** = o rail é o landmark do SH2, `<nav class="rail" aria-label="Áreas">`, com um
`aria-current="page"`, `main` com `id` e `tabindex="-1"` e skip link (é o que o CP-13 do `conferir-peca.py` prova);
**não** = rail ilustrativo (`role="img"`), que existiu nas dez telas com casca até a `SH-P11` (2026-09-15) — quem
copiava a casca de uma tela que não a `tela-shell` copiava casca de mentira; **—** = a referência não traz rail. A
coluna "no produto" é a decisão do SH17. Como cada gabarito se monta dentro da região `conteudo` (canvas, peça, calha) é o contrato por arquétipo do `seed-composicao.md` §3. O gerador da vitrine lê esta tabela pelo nome da tela, remede a casca E o
rail no disco e ABORTA se o medido divergir do escrito — a tabela nunca envelhece em silêncio. Desde a `SH-P11` as
onze telas com casca emitem a MESMA casca do módulo único `06-validacao/ferramentas/shell_bloco.py` (rail, skip
link, altura da topbar, foco do conteúdo — e, desde a `SH-P13`, o colapso do SH12: botão ☰, drawer modal e a regra de 860 px): copiar a casca de qualquer uma delas é copiar a do shell.

| gabarito | tela de referência | referência traz a casca? (medido) | no produto | por quê | rail funcional (medido) |
|---|---|---|---|---|---|
| A1 | `tela-shell` | sim (é a casca) | é o shell | — | sim |
| A1 | `tela-shell-sem-topbar` | sim (sem topbar) | dentro do shell | o MESMO shell no regime SEM topbar (SH1: obrigatórias são conteúdo + uma navegação; SH21/V-SH16.2: o avatar na base do rail; SH12 pelo ☰ no topo do conteúdo) — é o gabarito do produto que não liga a topbar, como o SEED Chat | sim |
| A1 | `tela-shell-abas` | sim (sem topbar, com barra de abas) | dentro do shell | o MESMO shell sem topbar com a BARRA DE ABAS (§95, AB1–AB12, com «Compras» como destino balão que abre a folha modal) e o botão flutuante (§1.14) abaixo de 860 px de contêiner — terceiro regime do A1, emitido pelo `gen-shell.py`; mede-se com a `guarda-barra-abas` | sim |
| A2 | `tela-referencia` · `tela-lista` | sim | dentro do shell | tela de aplicação | sim |
| A3 | `tela-tabela` | sim | dentro do shell | tela de aplicação | sim |
| A4 | `tela-painel` | não (raiz `conteudo`) | dentro do shell | o painel É a região de conteúdo do shell (§48; CP3: "o canvas do shell") — a referência mostra só a região | — |
| A5 | `tela-site` | não (raiz `pagina`) | FORA — página pública | não é aplicação (§47) | — |
| A7 | `tela-quadro` | sim | dentro do shell | tela de aplicação — foi o quadro aprovado que ele citou ("tem uma rail a esquerda") | sim |
| A7 | `tela-quadro-funil` | sim | dentro do shell | o MESMO quadro no modo funil comercial (`gen-tela-quadro.py --funil`, QD-P14, 2026-10-11) — exerce o QD22 (Editar/Novo funil) | sim |
| A8 | `tela-detalhe` | sim | dentro do shell | tela de aplicação | sim |
| A11 | `tela-gantt` | sim | dentro do shell | tela de aplicação | sim |
| A13 | `tela-documento` | não (raiz `tela`) | dentro do shell na leitura; FORA quando exportado | ler um documento é uma tela do app; o PDF/impresso não tem chrome (C25 do §88) | — |
| A14 | `tela-atividade` | sim | dentro do shell | tela de aplicação | sim |
| A17 | `tela-busca` | sim | dentro do shell | tela de aplicação | sim |
| A18 | `tela-configuracoes` | não (raiz `tela`) | dentro do shell | configurações é ROTA do app (CF-01, §86); a navegação lateral das seções ocupa a região `sidebar` do shell (papel de contexto, SH14). Foi esta a tela que o SIGA leu como "sem casca" | — |
| A19 | `tela-autenticacao` | não (raiz `tela`) | FORA — antes da sessão | não há app antes de entrar | — |
| A20 | `tela-onboarding` | sim | dentro do shell | o primeiro uso já é o app | sim |
| A23 | `tela-chat` | sim | dentro do shell | tela de aplicação | sim |
| A23 | `tela-mensageria` | sim | dentro do shell | a mensageria na forma TELA (§94, LC-38, leva 36): lista de conversas e conversa na MESMA peça (MS4); a `tela-chat` segue como forma PAINEL (§55) | sim |
| A27 | `tela-portal-cliente` | sim | dentro do shell | a área do CLIENTE logado (PN10 e DP12 numa tela, §48; leva 38): o rail traz só os destinos do cliente — Início, Financeiro, Documentos, Chamados — e nasce na Expandida (SH19); o cliente vê só o que é dele; aprovada por ele na folha 7 (K1 «ok», K2) | sim |
| A28 | `tela-envio-fornecedor` | não (raiz `pagina`) | FORA — página pública, aberta por link com token | o fornecedor NÃO tem login (D6 do briefing do SIGA): abre o link, envia o orçamento (até 5 arquivos, K6) e recebe o protocolo; antes e fora de qualquer sessão não há app (SH17); `noindex`, sem caminho de volta ao SIGA; aprovada por ele na folha 7 (K5 «ok») | — |
| A29 | `tela-estado` | não (raiz `tela`) | FORA — antes e fora de qualquer sessão | as páginas de estado de sistema (404, 403, 500, manutenção, sessão expirada; §96, TE1–TE10): a pessoa pode nem estar logada, então não há app (SH17); `noindex`, sem campo, sem dependência externa; arquétipo `autenticacao` (SH18); pedido `VI2`, "a" (folha 11, 2026-10-18) — o gate visual dele sobre a tela ainda não aconteceu | — |
| A30 | `tela-portal-parceiro` | sim | dentro do shell | a área do PARCEIRO INDICADOR logado (PN10 e DP12 numa tela, §48; leva 38, refeita na leva 39): quem indica clientes à SEED acompanha as próprias indicações só até o pagamento de 100% e nada depois; o rail traz só os destinos dele — Início, Indicações, Indicar alguém e Comissões — e nasce na Expandida (SH19, K2); dois status separados (a etapa da indicação e a situação da comissão); a variante «Também é cliente» soma os destinos da área do cliente; aprovada por ele na folha 9 (M1 «ok», 2026-10-18; M5 = b: Pix e também banco, agência e conta) | sim |
| A31 | `tela-cadastro-indicado` | não (raiz `pagina`) | FORA — página pública, aberta por link com token | o INDICADO se cadastra sozinho pelo link que o parceiro compartilhou, sem login (autocadastro; leva 39, letra s): antes de haver conta não há app (SH17); `noindex, nofollow` e `no-referrer`; o HTML servido não traz as palavras da lista `seed-proibidas` e não mostra quem enviou o link (M2b = a); o estado «enviado» tem um só texto para todos, inclusive quem já está na base; aprovada por ele na folha 9 (M2 «ok», 2026-10-18) | — |

**As linhas A27 e A28 (leva 39, letra v, `VT-P16`, 2026-10-12).** As duas telas foram aprovadas por ele na folha 7 de 2026-10-12 (K1 «ok» para a área do cliente, K5 «ok» para a página do fornecedor; MANIFESTO §311.1). O que NÃO veio dele e é decisão da sessão, exposta a veto: (i) o CÓDIGO — A27 e A28 são os próximos livres medidos no `TELAS` (maior A23) e no `mapa-cobertura-ds.md` (maior A26), e as duas ainda não têm linha no mapa; (ii) o § que governa cada uma — §48 (o PN10) para a área do cliente, §14 (o campo de arquivo) para a página do fornecedor, que não tem seção própria; (iii) a página do fornecedor ser a única linha «FORA — página pública» que não é o A5. As vistas «aceite de convite» (A19, §83) e «Pessoas» (A18, §86) não ganham linha: são vistas de gabaritos que já estão na tabela, e a página de cada uma na vitrine passa a listá-las.

**Endereço dos links públicos — o padrão vive AQUI, num só lugar (`PR-P159`, leva 40, 2026-10-13; decisão da sessão, exposta a veto).** Toda página pública aberta por link (`data-arquetipo="pagina"` sem ser o A5) mora no host `https://siga.seed.eng.br` (o endereço do SIGA, SH23), e o TOKEN vai no CAMINHO da URL, nunca em query string (`?token=`): é um valor aleatório de 22 caracteres base64url (128 bits), sem nenhum dado da pessoa nem da cotação dentro dele. O link de indicação é `/i/<token>` (a proposta da `tela-cadastro-indicado`, leva 39, que o decisor ainda não vetou nem confirmou); o link do fornecedor é `/f/<token>` — **proposta, a veto**, escolhida por simetria com o `/i/`, porque a `tela-envio-fornecedor` declarava só «token no caminho», sem caminho concreto. Toda página nesse padrão traz `<meta name="robots" content="noindex, nofollow">` e `<meta name="referrer" content="no-referrer">` (as duas telas já trazem) e nenhum link que carregue o token para fora; o que ela NÃO pode dizer a quem a abre vai na meta `<meta name="seed-proibidas" content="item|item">` (itens separados por `|`, comparados sem caixa e sem acento), emitida pelo gerador da tela e medida pela `guarda-palavras-proibidas.py` (`PR-P158`). Os geradores das duas telas citam este parágrafo em vez de repetir o padrão.

**Aplicado sem pergunta — exposto a veto (regra da casa):** as três linhas que decidem o que o canon não dizia — A4
painel, A13 documento e A18 configurações **dentro** do shell — são aplicação do briefing do §46 e da reprovação dele
de 2026-09-14, não decisão nova. **Confirmadas por ele em 2026-09-14** (gate F11.1, verbatim: *"V-F11.1 tabela SH17: confirmo · V-F11.2 login: aprovo · veto: nenhum"*, MANIFESTO §220.1) — desde então as três linhas são decisão dele, não aplicação da sessão.
### 46.5 SH18 — toda tela publicada declara o próprio arquétipo no `<html>` (V-LC11, 2026-09-15)

> **Por que esta regra nasce.** A LC-11 (MANIFESTO §223.5) deu à ficha de conformidade o item **CP-13**, que mede no
> navegador se uma tela de aplicação tem o shell deste §46 (rail de 80 px, topbar de 60 px, `main` com foco e id, skip
> link). O que a régua não sabe sozinha é se uma tela DEVE ter shell: pelo SH17, login, site e onboarding vivem fora
> dele. Ela lia a raiz de consulta do CP27 (`app` mede · `pagina` não se aplica) e, quando a raiz era `tela` ou
> `conteudo` — gabarito publicado sem a casca —, dizia NÃO MEDI e pedia `--arquetipo` a quem roda. Uma IA que só
> recebe o HTML não tem como declarar. Veredito dele em 2026-09-15 (MANIFESTO §224.1), verbatim: *"V-LC11
> data-arquetipo: sim"*.

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| **SH18** | **Toda tela publicada — referência da casa ou tela de consumidor (SIGA, apps) — declara no `<html>` o atributo `data-arquetipo` com UM valor da lista fechada: `aplicacao` (tela de aplicação: o shell §46 é obrigatório e o CP-13 o mede) · `autenticacao` (antes da sessão, A19: sem shell) · `pagina` (página pública, A5/§47: sem shell) · `bancada` (referência publicada SEM a casca para medir o conteúdo isolado — raiz `tela`/`conteudo`, CP28: o shell não se aplica AO ARQUIVO; a coluna "no produto" do SH17 continua valendo para o gabarito) · `documento` (documento exportado, PDF/impresso: sem chrome, C25 do §88). O atributo declara o que ESTE HTML é; o SH17 declara onde o GABARITO vive no produto.** | Fato no artefato, não heurística — o mesmo princípio do CP27 (raiz de consulta declarada). Com o atributo, a régua mede sozinha e serve a qualquer IA sem instrução; valor fora da lista é FAIL no CP-13 (declaração errada é defeito do artefato); `--arquetipo` na linha de comando continua como sobrescrita explícita e sai impresso como tal, dizendo o que o artefato declarava | Ficar com `--arquetipo` manual: custo zero agora, e cada consumidor teria de saber declarar. Adivinhar pela forma (contar `class="rail"`): régua que infere o tipo erra no primeiro caso misto |

**Os 16 moldes declaram (2026-09-15):** `aplicacao` — `shell`, `tela-referencia`, `tela-lista`, `tela-tabela`,
`tela-quadro`, `tela-detalhe`, `tela-gantt`, `tela-atividade`, `tela-busca`, `tela-onboarding`, `tela-chat` (as onze
com "referência traz a casca: sim" no SH17 — dez delas com casca ainda ilustrativa, `SH-P11`, e por isso reprovadas
pelo CP-13 até a SH-P11 fechar: é a verdade, não um defeito da declaração) · `bancada` — `painel`,
`tela-configuracoes`, `tela-documento` (as três publicadas sem a casca) · `autenticacao` — `tela-autenticacao` ·
`pagina` — `site`. O shell do SIGA declara `aplicacao` (`src/routes/__root.tsx`). **Casca ilustrativa não existe mais como categoria (SH-P11, 2026-09-15, MANIFESTO §225.5):** referência que mostra o shell traz o shell REAL emitido pelo módulo `shell_bloco.py` (rail `nav[aria-label="Áreas"]`, skip link, `main#conteudo[tabindex="-1"]`); referência que NÃO traz a casca declara `bancada` — é o que a fila chamava de "o CP-13 aceita casca ilustrativa como não se aplica declarado".

> **Porta do ERP para o ESTADO DO RAIL (SH19, `SH-P14`, 2026-09-15 — é aqui que o V-SH14.4 = a vive).** O DS entrega os dois estados, o contrato do atributo e o comportamento do botão; o ERP implementa: (1) o contêiner `app` do shell declara `data-rail="expandido"` ou `"recolhido"` — e **nasce `expandido`** para todo usuário; (2) o botão `.alterna-rail` na base do rail (o mesmo do módulo: `aria-expanded`, "Recolher áreas"/"Expandir áreas", chevrons do Lucide) chama `alterna_rail()`; (3) **a preferência é do USUÁRIO e GLOBAL** — gravada por usuário (Supabase, mesma fronteira do CN4 e da persistência da sidebar), nunca por tela nem por dispositivo/sessão: recolher numa tela e achar expandido na seguinte é o defeito que o `IsPaneOpen` global do Fluent evita; ao entrar, o shell lê a preferência e aplica o atributo ANTES do primeiro desenho (sem salto de 24 px); (4) abaixo do limiar do SH12 e no toque o estado não se aplica (o drawer traz o rail com rótulos) e a preferência fica guardada para o desktop; (5) o tooltip do recolhido segue o §23 como o módulo o emite (posição do 1.º destino, Esc, carência). Verbatim dele: *"V-SH14.1 modo recolhido: b · V-SH14.2 gatilho: a · V-SH14.3 posição do botão: a · V-SH14.4 quem lembra: a · veto: nenhum"*.

> **Porta do SIGA para os TRÊS FORMATOS e o SOBREVOO (SH19, `SH-P46`, 2026-10-08 — supersede parcial da porta acima, que segue valendo no que esta não muda).** (1) `data-rail` passa a ter três valores — `recolhido` | `expandido` | `largo` — e **nasce `expandido`** (a Encurtada) para todo usuário; (2) um segundo atributo no mesmo `.app`, `data-rail-sobrevoo` = `ligado` | `desligado`, nasce `desligado` e só tem efeito com `expandido`; (3) a preferência passa a **3 valores + 1 booleano, do USUÁRIO e GLOBAL** (por conta, a mesma fronteira de antes), aplicada nos dois atributos ANTES do primeiro desenho; ir à Expandida não apaga o sobrevoo, que volta a valer na volta à Encurtada; (4) o botão alterna Encurtada ↔ Expandida e o menu de conta (SH21) traz os três formatos e o sobrevoo — o produto grava a escolha ao ver o atributo do `.app` mudar (o script do módulo reage à mudança e repinta o botão; ele mesmo não grava nada); (5) abaixo do limiar do Q3 a Expandida aparece como Encurtada SEM mudar a preferência; abaixo do SH12 e no toque nenhum formato e nenhum sobrevoo se aplicam. Verbatim dele: *"pode seguir / folha nao abriu"*.

> **Tinta de marca no shell (V-CT9 = a, MANIFESTO §224.1):** item ativo, contador ou rótulo que use tinta de marca
> sobre `surface-subtle` ou `surface-brand-subtle` (sidebar, pílula, badge) usa **`text-brand-strong`** — a regra mora
> no **§73.5**; o censo da CT-P9 (208 de 208 HTML) não achou ocorrência viva nas telas.

### 46.6 SH21 — conta e tema: UM menu por tela, aberto pelo avatar (`SH-P16`, V-SH16, 2026-09-19)

| decisão | regra |
|---|---|
| **SH21** | **Toda tela de produto tem UM menu de conta, aberto pelo avatar** (`aria-haspopup="menu"`, já previsto no SH2), com os itens **Perfil · Tema (claro · escuro · seguir o sistema) · Sair**. *(SH-P46, 2026-10-08, Q7: entre Tema e Sair entra o grupo **Barra lateral** — três `menuitemradio` Minimizada · Encurtada · Expandida — e o `menuitemcheckbox` **"Expandir ao passar o mouse"**, VISÍVEL e indisponível fora da Encurtada com o motivo escrito "Só no formato Encurtada" (MN6; o nome é o rótulo e o motivo é a descrição); opções não fecham o menu (MN4); são 9 itens = 2 ações + 7 opções, e o teto ~7 do MN5 é de ações; o script marca os rádios POR GRUPO e o teclado percorre o `menuitemcheckbox`.)* Onde a topbar existe (SH10), o avatar vive na zona direita dela; **em produto sem topbar, o avatar vive na base do rail**, imediatamente acima do botão de recolher do SH19 — que continua o ÚLTIMO item focável do rail. O alternador de tema **nunca** é um controle solto na topbar nem itens empilhados no rail: é item do menu. **Preferência de tema:** nasce seguindo o sistema operacional (`prefers-color-scheme`); a primeira escolha manual da pessoa passa a valer sobre o sistema e é guardada **por CONTA** (sincroniza entre aparelhos), nunca só por aparelho; a precedência é escolha guardada da conta › `data-theme` declarado no documento › sistema — o degrau do meio existe para que artefato de evidência, que declara o tema de propósito, renderize igual em qualquer máquina. **O menu segue o §35 (MN1–MN8) integralmente:** abre por clique, Enter, Espaço ou ↓ (↑ abre no último item), as setas circulam, Home/End vão às pontas, há typeahead, Esc fecha e devolve o foco ao avatar, o clique fora fecha, e **Tab FECHA o menu e o foco segue o fluxo do documento** — aprisionar o foco é regime de diálogo modal (§31), não de menu. Os três estados de tema são `menuitemradio` e alternar um **não** fecha o menu (MN4: opção não é ação). O painel é superfície OPACA (§93 MA3/MA12: menu não leva vidro) e é emitido fora de `.app`, para o `overflow` do rail e o `backdrop-filter` da casca não o cortarem. Emitido pelo módulo único `06-validacao/ferramentas/shell_bloco.py` (`conta_menu()`, painel `#menu-conta`, grupo de tema `#menu-conta-tema`) nas onze telas com casca; o CP-13 do conferidor mede que o menu existe, onde vive e que é um só por tela. |

**Onde vivem os tokens do tema.** O SH21 decide o CONTROLE e a preferência; os valores dos dois temas são do `seed-tokens.md` §3 (semânticos claro e escuro) e a inversão se prova na bancada do §64 — esta seção aponta, não redefine.

**Origem e decisão.** Lacuna medida no reconhecimento da F12 (MANIFESTO §234.3): 0 de 11.991 linhas deste canônico diziam onde vive o alternador de tema num produto — as 6 ocorrências eram da barra de provas de bancada, que no produto não existe — e em 2026-09-18 o SEED Chat recebeu avatar, tema e sair empilhados no rodapé do rail sem regra para seguir. O estudo `09-pesquisa/2026-09-19-estudo-conta-e-tema-no-shell/` (F12.5) renderizou três variantes nas telas reais e mediu nove sistemas de mercado (6 de 9 põem o tema dentro do menu de conta; nenhum documenta "rodapé de rail"). Veredito dele, verbatim (MANIFESTO §235.2): *"V-SH16.1 (onde vive o alternador de tema): b · V-SH16.2 (conta/sair sem topbar): (sem resposta) — Mantemos V2. no caso do seed chat o botao do perfil fica na rail, se clicar nele vai ter la a opção de sair ou de tema claro e escuro. o que está sendo decidido é onde o botao de perfil fica onde nao tem topbar e a resposta é na parte inferior da rail. · V-SH16.3 (de quem é a preferência): a · veto: nenhum"*. Consequência para o SEED Chat: os itens empilhados no rodapé do rail convergem para o avatar que abre o menu (é a resposta do DS ao pedido de cobertura do rodapé do rail, que nunca chegou ao banco — §235.1).

**Aplicação exposta a veto (F12.9, 2026-09-19).** O nome acessível do menu sai do próprio avatar por `aria-labelledby` (padrão APG do *menu button*): "Conta de <pessoa> — <presença>", que contém o literal "Conta" que o SH2 nomeia; se a intenção do SH2 era o nome literal "Conta", é uma linha de decisão. E o regime SEM topbar ganhou GABARITO em 2026-09-20 (`SH-P17`): até então nenhuma das onze telas de referência o exercitava — as onze tinham topbar e as onze punham o avatar nela —, e o caso "avatar na base do rail" só existia em cobaia (`06-validacao/provas/tela-html/shell-sem-topbar-cobaia.html`). A `05-html-de-referencia/telas/tela-shell-sem-topbar.html` (gabarito A1, linha própria na tabela do SH17) é emitida do MESMO molde e pelo MESMO gerador da `tela-shell.html` (`gen-shell.py` v0.12), com três diferenças e nenhuma a mais: a topbar sai inteira — e com ela saem o seletor de contexto (SH11), a busca (SH9) e o sino (§33), nenhum deles região obrigatória do SH1 —, o avatar vai para a BASE DO RAIL (esta decisão) e o **☰ do SH12 passa a ser o primeiro elemento da coluna de conteúdo** (SH12 no §46.2: sem topbar não haveria porta nenhuma para o drawer abaixo de 860 px). A cobaia continua, e de propósito: a tela é o GABARITO — o que um consumidor copia — e a cobaia é a prova da RÉGUA, derivada da tela COM topbar variando UMA condição. **O que continua sem gabarito porque é decisão de PRODUTO, não do DS:** se o chat deve ser servido sem topbar — o §55 (Chat) não cita topbar em nenhuma das catorze decisões dele, e a `tela-chat` segue com topbar, que é a forma do chat DENTRO do SIGA; o SEED Chat, que é produto próprio, não a tem.

### 46.7 SH22 — tipos de destino do rail: painel, balão e direto (`SH-P34`, V-SH34.6, 2026-09-26)

| decisão | regra |
|---|---|
| **SH22** | **TIPOS DE DESTINO DO RAIL:** todo destino do rail declara, pelo PRODUTO, UM tipo no atributo `data-rail-tipo`: `painel`, `balao` ou `direto`. O contrato de cada tipo, logo abaixo, é parte desta decisão. |

- **painel:**
  - O sobrevoo abre a PRÉVIA da coluna de contexto, com o 1.º nível dela. Só com ponteiro fino e `(hover: hover)`, e só depois de 150 ms de intenção (300 ms até a leva 49; ver "Os tempos").
  - A prévia ocupa a CAIXA da coluna: popover do §31 (faixa 75), `surface-overlay`, par sombra + anel do CP17.
  - Ela fica enquanto o ponteiro está no destino ou nela e some 500 ms depois de ele sair dos dois (SC 1.4.13). Esc fecha sem mover o foco, e ela não reabre até o ponteiro sair do destino.
  - Com a prévia aberta, a troca entre destinos é imediata, salvo quando o ponteiro vai a caminho dela (triângulo de rumo).
  - O destino ativo não abre prévia.
  - O CLIQUE ancora: a sidebar do SH4 carrega a árvore inteira do destino.
  - O clique num subitem da prévia ancora com SÓ o submenu dele, mais um "voltar à área".
  - Quando ancorar num subitem exige NAVEGAR para outra tela, o produto leva o grupo no endereço (parâmetro de consulta ou segmento de caminho), e a tela de destino abre a coluna só com aquele submenu e o "voltar à área"; dentro da mesma tela, o evento `seed-rail-ancora` basta. Motivo: o endereço sobrevive a recarregar, voltar e compartilhar. *(Decisão da sessão, exposta a veto dele: MANIFESTO §268, `SH-P40`.)*
  - Teclado: o foco sozinho não abre; → abre com o foco no 1.º subitem; ↑↓, Home e End andam; ← e Esc fecham e devolvem o foco; Tab fecha e segue a ordem a partir do destino.
  - Toque: não há prévia, e o toque ancora.
- **balao:**
  - É disclosure do APG (`aria-expanded` + `aria-controls`), nunca `role="menu"`.
  - O clique abre com o foco na 1.ª opção; o segundo clique, Esc, clique fora e Tab fecham.
  - Nunca ancora. A opção escolhida navega, a coluna some e o gatilho passa a ser o ativo.
  - **Na barra de abas (§95, AB12; folha 6, J5 = b, 2026-10-12) o balão NÃO é popover:** a aba abre uma FOLHA MODAL inferior igual à do «Mais» (AB11), com as opções em lista de itens ≥ 44 px; é disclosure de diálogo (`aria-haspopup="dialog"`), ainda nunca `role="menu"`; Esc, toque no véu e o botão Fechar fecham e devolvem o foco à aba; a opção escolhida deixa a aba do balão ativa. A emenda vale SÓ para a barra — no rail o balão continua ao lado dele (`abreBalao` mede `rail.right`).
- **direto:** navega, e a coluna some.
- Quem carrega a coluna é o produto, ao ouvir o evento `seed-rail-ancora`. O DS emite as camadas e o comportamento pelo módulo único `shell_bloco.py`.
- **Descartado:** abrir a prévia no foco (12 destinos piscando no Tab); prévia menor que a coluna (a troca "pula" ao ancorar); balão como `role="menu"` (MN1); fechar por tempo sem Esc (quebra o 1.4.13).

**Os tempos.** Os tempos da PRÉVIA do SH22 são 150 ms de intenção para abrir e 500 ms de carência para fechar (`SH-P70` b, leva 50; veredito dele, folha 17, Q1 = b, 2026-10-30 23:28 UTC, MANIFESTO §326.8 — a opção b da folha: «150/500 ms: abre em ≈ 156 ms, fecha em 500 ms»; medido no Chrome: a prévia abriu em 152 e 157 ms, `render-shell.mjs` R17-02, que reprova abaixo de 120 ms e acima de 150 + 100 ms + a deriva da sonda). São constantes nomeadas no módulo `shell_bloco.py` (`ATRASO_ABRE_MS`, `CARENCIA_FECHA_MS`), não token de duração: token de duração encolhe com movimento reduzido, e intenção não é animação (V-SH34.5 = a). Até a leva 49 eram 300/500 ms (NN/g 2015, "Timing Guidelines for Exposing Hidden Content", 0,3 a 0,5 s).

**Com o sobrevoo do rail (SH19, `SH-P46`, 2026-10-08, Q4).** Quando a pessoa liga "Expandir ao passar o mouse", a prévia de um destino `painel` só começa a contar os 150 ms de intenção depois de o rail abrir e, quando ela abre, o sobrevoo CEDE (o rail volta a 80 px e a prévia fica na caixa da coluna) — as duas camadas nunca juntas. O sobrevoo que EXPANDE o rail tem constantes PRÓPRIAS (`ATRASO_EXPANDE_MS = 300`, `CARENCIA_EXPANDE_MS = 500`, NN/g 2015) e não acompanhou a prévia: a pergunta da folha 17 foi só sobre a prévia (separar as constantes foi decisão da sessão, leva 50, exposta a veto). Custo declarado: o rail aberto aparece ≈ 160 ms antes de ceder (medido de 158 a 173 ms em 6 leituras; era ≈ 300 ms). Régua: `render-rail.mjs` R19-13 (piso 140 ms, teto 250 ms).

**Origem e decisão.** Pedido dele, com três fotos do ClickUp, registrado no relatório do agente J (`ds-w2-entregas/j/RELATORIO.md`) e no MANIFESTO §264: o sobrevoo abre, à direita do rail, a coluna com as opções; o clique faz dela a coluna carregada; o clique direto num subitem carrega só o submenu dele; e há destinos que abrem só um balão. A resposta implementada: o DS define os três tipos e o contrato; o produto declara, destino a destino, o tipo e os filhos. Prancha `09-pesquisa/2026-09-26-sh-p34/prancha.html`, com seis perguntas (V-SH34.1 a .6). Veredito dele, verbatim (MANIFESTO §264.1, chat, 2026-09-26 ~15:35Z): *"ficou otimo"*; e, perguntado se a frase valia como resposta às seis, com a promoção ao canon (seletor de opções, ~15:41Z): *"Sim, tudo como aplicado (Recommended)"*. As seis ficam na saída a: 300 ms de intenção (V-SH34.1; tempos revistos na leva 50, `SH-P70` b: 150 ms); a prévia na mesma caixa da coluna, 280 px, a sidebar do SH4 (V-SH34.2); o primeiro toque, sem mouse, ancora direto (V-SH34.3); no destino direto e na opção do balão a coluna some, pelo SH14 (V-SH34.4); os tempos como constantes (V-SH34.5); e esta regra no canon como SH22 (V-SH34.6). Réguas: `suite-shell.mjs` (asserções SH-P34) e `render-shell.mjs` R17, nas duas telas da casca.

### 46.8 SH23 — o sistema de gestão da SEED se chama SIGA (`SH-P43`, 2026-10-05)

| decisão | regra |
|---|---|
| **SH23** | **O NOME DO PRODUTO É "SIGA".** O sistema de gestão da SEED engenharia, que até 2026-10-04 o DS chamava de "o ERP", chama-se **SIGA — Sistema Integrado de Gestão Assistida**, com a tagline **"Gestão inteligente"**. Em todo texto vivo do DS (canônico, tela de referência, bancada, peça gerada, microcopy de exemplo) o produto se escreve **SIGA**, em maiúsculas (é sigla). **A dona continua a SEED engenharia:** "SIGA, o sistema de gestão da SEED engenharia". |

- **Primeira menção de cada documento:** "SIGA (Sistema Integrado de Gestão Assistida)"; da segunda em diante, só "SIGA".
- **Tagline:** "Gestão inteligente". Aparece na entrada do produto (é o que o título da aba da entrada leva); as telas internas levam só o nome.
- **Forma do `<title>` do produto:** na **entrada**, `SIGA · Gestão inteligente`; nas **telas internas**, `<Tela> · SIGA` (nome da tela primeiro, depois o produto; separador "·" com espaço dos dois lados). Rótulos de ação: "Entrar no SIGA", "Áreas do SIGA". Forma já aplicada pela sessão do SIGA nas telas do sistema.
- **Cor e marca não mudam:** SIGA é o NOME do produto, não uma submarca; usa a marca SEED, os tokens e o shell deste §46 como antes. Nenhum logotipo "SIGA" nasce aqui (decisão da sessão, exposta a veto).
- **Categoria não é nome** (decisão da sessão, exposta a veto): "ERP" continua valendo como CATEGORIA de software em geral ("sistemas ERP", "ERP de mercado", comparação com SAP/Fiori); a regra troca só o produto da SEED.
- **História não se reescreve:** changelog, veredito verbatim, citação do decisor, data passada e a evidência de gate (peça em `07-pecas/`, `08-historico/`, `09-pesquisa/`, MANIFESTO) mantêm "ERP" byte a byte. O mesmo vale para identificadores de código e de pasta que já existem (`gen-erp-*.py`, `erp-render/`, `seed-erp`, classes CSS): nomes técnicos só mudam por decisão própria, com o custo medido.

**Origem e decisão.** Veredito dele, dado no `seed-erp` e registrado no MANIFESTO §285 (aviso da sessão SIGA, ~01:40Z de 2026-10-05), verbatim: *"eu fiz a definiçao do nome do sistema, pois ele nao vai se chamar ERP. o nome é "SIGA" – Sistema Integrado de Gestão Assistida. com a tagline "Gestão inteligente" apos o merge, registre essas informações, pode trocar os nomes onde tiver, nome de pasta, repositorio, etc."* Fonte primária: `seed-erp`, branch `dev`, `docs/produto/DECISAO_2026-10-04_nome_SIGA.md` (commit `83e6996`). Confirmação dele ao ser perguntado se o nome entra no DS (2026-10-05, ~17:05Z): *"sim, está correto, definimos SIGA como nome"*, e *"pode abrir o proximo grupo"*. A forma do título da aba e os rótulos não são palavra dele: vêm da sessão do SIGA, exposta a veto.

### 46.9 SH24–SH28 — cinco regras do rail que o SIGA pediu (folha de 2026-10-10, resposta dele «a, a, a»)

*Para quem lê sem ter visto a conversa:* o SIGA (§46.8) montou o rail do menu comercial e voltou ao DS com cinco lacunas do contrato SH3/SH4/SH6/SH22. A folha de gate de 2026-10-10 (versão 3, itens `V-SH31.1`, `SH-P35`, `SH-P36`, `rail-3a`, `rail-3b`) pôs as opções com o custo medido, e a resposta dele foi *aplicar a recomendação da sessão*. **Numeração SH24–SH28 é da sessão desta leva (primeiro número livre depois do SH23, medido), ajustável.** O SIGA já aplicou, em provisório, as quatro primeiras; esta seção as torna regra. **O DS ainda NÃO desenha** a abreviação, o ícone de saída, o pé do rail, o item indisponível nem o item-ação da coluna no `shell_bloco.py` — é contrato escrito, com o desenho por fazer (custos na coluna «medido»).

| decisão | regra | medido |
|---|---|---|
| **SH24** | **ROTULO QUE NÃO CABE NO RAIL → ABREVIAÇÃO OFICIAL** *(`V-SH31.1` = «c»)*. O item do rail tem 68 px úteis a 11 px (SH3, ≤ 9 caracteres por palavra). Quando o nome do destino não cabe, o **produto declara um rótulo curto** por destino («Eng.», «Adm.»); o **nome inteiro** nunca some: aparece na prévia, na coluna ancorada e no tooltip. **O nome acessível CONTÉM o texto visível** (WCAG 2.5.3 Label in Name): «Eng. — Engenharia», nunca só «Engenharia». A régua do SH3 continua sendo a largura medida do rótulo VISÍVEL (o curto), não a do nome inteiro. | ENGENHARIA mede 76,45 px e ADMINISTRATIVO 98,64 px a 11 px (peso 600 inativo, 700 ativo), acima dos 68; medidas do agente J batem com as do SIGA em 7 de 7 rótulos (0,00 px de diferença). No DS: NÃO MEDI o desenho. *Descartadas:* fonte de 9 px (abaixo do piso de 11 px da marca, §4.8; ADMINISTRATIVO não cabe nem a 9: 80,20), duas linhas com hífen (palavra partida), rail de 111 px (+31 px, supersede da largura do SH3). **Risco:** «Adm.» (setor) ao lado de «Admin» (sistema) confunde — resolvido pelo SH26 (o sistema vai ao pé). |
| **SH25** | **DESTINO `direto` QUE ABRE OUTRO PRODUTO EM JANELA NOVA** *(`SH-P35` = «a»)*: é um **modificador do tipo `direto`** do SH22, nunca um quarto tipo. Leva (1) um **ícone de saída** no canto do item e (2) o aviso no **nome acessível**, ANTES do clique (WCAG 3.2.5, técnica G201): «Chat, abre o SEED Chat em nova janela». O tooltip repete o aviso. Conta no limite de 3 a 12 do SH3 como qualquer direto. | O SIGA já aplicou assim (seed-erp a59d5a5, provisório). No DS: ~15 linhas no módulo, 1 regra de CSS, 2 asserts (estimativa do agente J, não medida); o ícone de 12 px dentro do item de 72 px: NÃO MEDI. *Descartadas:* só o aviso falado (quem enxerga só descobre depois do clique), botão na topbar (o Chat sai de onde a pessoa o procura). |
| **SH26** | **O DESTINO DO SISTEMA VAI AO «PÉ» DO RAIL** *(`SH-P36` = «a»)*: a administração do SISTEMA («Admin», que não é o setor Administrativo) fica no **pé** do rail, acima do botão de recolher (SH19) e **separada dos setores** por um espaço de rodapé. **Conta no limite de 3 a 12 destinos do SH3.** A ordem de foco é: setores → pé → recolher. | O SIGA já aplicou (provisório). No DS: ~20 linhas + asserts de ordem de foco (estimativa do agente J, não medida). *Descartadas:* item do menu de conta (fica a 2 cliques e escondido; o SH21 é Perfil · Tema · Sair), último item comum da lista (mistura ferramenta do sistema com setor). |
| **SH27** | **DESTINO QUE VAI EXISTIR E AINDA NÃO TEM TELA → VISÍVEL, INDISPONÍVEL, COM MOTIVO** *(`rail-3a` = «b»; o SH6 ganhou a frase)*: segue o **MN6** (item indisponível do menu): fica no rail, com `aria-disabled="true"`, o **motivo** ligado por `aria-describedby` («Ainda não disponível no <produto>») e um balão no foco. **Tinta legível: razão ≥ 4,5:1 — NUNCA 55 % de opacidade.** O que NÃO vai existir (a Qualidade, pela G5 dele) SAI do rail; só omite o item o SH6 original (perfil sem permissão). | O provisório do SIGA (55 %) mede 3,04:1 no topo do rail e 3,99:1 no pé, abaixo de 4,5; a 80 % mede 4,66:1 (mede-contraste, 2026-10-03). No DS: 1 variante no `shell_bloco.py` + asserts, NÃO MEDI; no SIGA: trocar 55 % por uma tinta ≥ 4,5 (1 regra). *Descartadas:* omitir (o rail do SIGA cairia a 2 destinos, abaixo do mínimo de 3 do SH3), página «ainda não» (um clique que leva a lugar nenhum). |
| **SH28** | **ÁREA SEM FILHOS NA COLUNA: O TEXTO + O CAMINHO PARA QUEM PODE CRIAR** *(`rail-3b` = «b»)*. A coluna é uma árvore (SH4), e todo item da árvore é navegável; o texto que só informa («Nenhum funil nesta área.») **não é item**: fica no grupo **sem papel de item** (não recebe foco pelas setas; o leitor de tela o lê como descrição do grupo). **Z4 (sempre porquê + próximo passo):** para quem tem permissão de criar, o grupo ganha um item-ação navegável, «Novo funil em <área>»; quem não tem vê só o texto, sem controle morto. | Contraste do aviso 5,61 (claro) / 6,8 (escuro). No DS: NÃO MEDI (o desenho e os asserts); o SIGA já tem o diálogo «Novo funil em <área>» no cabeçalho do quadro — dois lugares para criar funil (ver `QD-P12`). *Descartadas:* só o texto (vazio sem próximo passo, contra o Z4), omitir a área vazia (ela some e reaparece conforme o banco). |

**SH24 na Encurtada: rótulo curto + tooltip com o nome completo (`SH-P74` d, leva 50, 2026-10-31).** Na tela que NASCE na Expandida e passa à Encurtada, o item cujo nome não cabe nos 68 px declara um rótulo curto (`data-curto`, que cabe nos 68 px; SH-P54, leva 39) e o nome completo aparece como tooltip no sobrevoo e no foco de teclado (veredito dele, folha 17, Q3 = d, 2026-10-30 23:28 UTC, MANIFESTO §326.8 — a opção d da folha: «Vc: rótulo curto + tooltip com o nome completo»). Item cujo nome já cabe não ganha tooltip. **Mecanismo: tooltip `position: fixed` posicionado por script.** O rail da Encurtada rola, e `overflow-y: auto` corta o que sai dele; `overflow: visible` faria o rail deixar de rolar. Medido (`prova-rail-tooltip.mjs --medida`, Chrome, leva 50): o tooltip fixo alcança 16 de 16 destinos a 1440 × 500 px e a 1440 × 900 px, sem corte; `overflow: visible` alcança 5 de 16 a 1440 × 500 e 12 de 16 a 1440 × 900 (escolha do mecanismo: decisão da sessão, exposta a veto). Vale também na gaveta do SH12 a 800 px (o mesmo `nav.rail` vai à gaveta); não vale no sobrevoo aberto (o nome completo já aparece) nem no largo cedido. Esc fecha o tooltip sem mover o foco (X3 do §23). O tooltip usa `surface-inverse`/`text-inverse` (contraste do estudo H3: 13,86:1 no claro, 12,75:1 no escuro; não remedido no pixel). **Opt-in:** `rail(..., tooltip=True)` mais `css_rotulo_curto()`, `css_tooltip_curto()` e `script_tooltip_curto()` do `shell_bloco.py`; nenhuma tela de referência o usa ainda (só a cobaia `provas/rail-tooltip/`). Provas: `prova-rail-tooltip.mjs` 24 de 24 (12 casos × 2 temas), cobaias 9 de 9, `teste-rail-tooltip-contrato.py` 15 de 15. **Tensão aberta, exposta a veto:** o item de rótulo curto tem `aria-label` só com o nome completo (desde a SH-P54, leva 39), e a linha SH24 acima pede que o nome acessível CONTENHA o texto visível («Eng. — Engenharia», WCAG 2.5.3); a leva 50 não mudou o `aria-label`.

### 46.10 SH29 — a coluna de contexto: FIXA ou SOLTA (leva 42, 2026-10-17; desenho final na leva 43, 2026-10-18)

*Para quem lê sem ter visto a conversa:* a casca tem três colunas, da esquerda para a direita: o **rail** (SH19, três formatos), a **coluna de contexto** e o conteúdo. A coluna de contexto é a sidebar "Seções" (SH2, 280 px) ou o painel `.escopo` "Escopo" (SH20, 250 px). Nenhuma tela tem as duas. Até a leva 42 ela era **estática**: largura fixa no molde, sem estado e sem botão, em 10 de 10 telas com coluna (6 com "Seções", 4 com "Escopo"). A lacuna já estava nomeada no `mapa-cobertura-ds.md` como C25, "Sidebar colapsável com memória", parcial. **Numeração SH29 da sessão da leva 42** (primeiro número livre depois do SH28, medido), ajustável.

**Os vereditos dele, verbatim.**
- **O pedido (2026-10-17 ~21:09Z):** *"outra alteração que vc precisa fazer. na tela (painel) temos 3 campos, da esquerda pra direita temos o Rail, depois o menu e por ultimo a tela correto? / o rail ja possui 3 opções de tamanho, mas a coluna de menu pelo que me lembro nós nao trabalhamos ela. se realmente ela for estatica, quero que vc implemente a opção dela recolher, nao a ponto de simir, mas sim ficar apenas uma barra (coluna) fina. dessa forma a janela ganha mais espaço, principalmente em telas pequenas. / estudo sobre e implemente"*. Medido: a `tela-painel` citada não tem coluna (é o Painel do §48); a casca de três colunas da frase é a do §46.
- **O gate (folha 11, G1, 2026-10-18 18:56:23Z):** escolha **"a"** (aprovar e publicar), com a observação inteira: *"a coluna quando passar o mouse em cima ela deve expandir. o botao em baixo é so para dizer se ela fica fixa aberta ou se ela recolhe quando o mouse nao está em cima."*

| decisão | regra | medido |
|---|---|---|
| **SH29** | **A COLUNA DE CONTEXTO É FIXA OU SOLTA.** O estado vive no atributo `data-sidebar` do contêiner `app`, o mesmo elemento do `data-rail` e do SH12. **`aberta` = FIXA:** a coluna com a largura dela (280 px "Seções", 250 px "Escopo") empurra o conteúdo. **É como TODA tela nasce.** **`recolhida` = SOLTA:** em repouso, a coluna é uma **faixa de 56 px** (`sp-12` + 2 × `sp-1`, a conta da Minimizada do SH19), só com o botão. Ela **abre POR CIMA do conteúdo**, sem empurrar: a largura canônica com margem negativa que devolve à grade os mesmos 56 px, na camada `--seed-z-chrome`, com o par `--seed-shadow-overlay` + anel `--seed-border-subtle` do sobrevoo do rail (CP17/Q8). Abre quando: (1) o **mouse** para nela por `--seed-dur-expressive` (300 ms), só em `(hover: hover) and (pointer: fine)`; (2) o **foco** entra nela — Tab, `focus()` do produto, leitor de tela; não o que vem de um clique ou toque nela, que o sobrevoo e o toque já tratam (solta, o conteúdo sai da vista por um clip de 1 px, mas continua focável e na árvore de acessibilidade); (3) um **toque** bate na faixa ou no botão; (4) um destino `painel` do rail (SH22) é ancorado, sem mudar a preferência. **Fecha:** quando o mouse sai, depois da carência `--seed-dur-expressive-slow` (400 ms); quando o foco sai — e, se o foco sai para OUTRO elemento, ela fecha mesmo com o mouse em cima (SC 2.4.11 da WCAG 2.2: aberta, ela cobriria o elemento que recebeu o foco); com **clique ou toque fora**; com **Esc** — só quando o foco ou o mouse está nela; consumido, o Esc não propaga (um diálogo ou menu por baixo não fecha junto) —, que devolve o foco ao botão se ele estava dentro (`data-aberto="false"` trava a reabertura até o foco ou o ponteiro sair). Uma tecla qualquer desfaz a marca de toque (aparelho híbrido: o Enter no botão fixa). Clicar num item DENTRO da coluna aberta não a fecha. **O botão** (`.alterna-coluna`) fica na **base** da coluna, 48 × 44, e gruda no fundo da janela (`position: sticky`). É o **último focável** dela. É um **alternador de FIXAR**: `aria-pressed` = "fixa", **nome FIXO** ("Fixar seções aberta" / "Fixar escopo aberto", D16, exposto a veto). Ícones Lucide `pin` (fixa) / `pin-off` (solta), NM4 ②. `aria-controls` aponta para a própria coluna. No **toque**, o 1.º toque abre e, com ela aberta, tocar o botão fixa. **Abaixo do limiar do SH12 (860 px de contêiner) nada muda:** a coluna vai inteira à gaveta, o botão some ali e a preferência fica guardada. Com a coluna solta, a Expandida do rail **não cai** pelo Q3 (616 + 160 + 56 + 24 = 856 < 860). A largura anima em 150 ms (`--seed-dur-productive`; movimento reduzido: de uma vez) desde a leva 48 — a D14 ("sem animação de largura") foi SUPERSEDIDA (`SH-P71`, ver a D14 abaixo). **Quem lembra é o PRODUTO** (preferência do usuário, global, aplicada antes do 1.º desenho, a porta do SH19); as telas de referência não persistem nada. Emitido pelo módulo único `shell_bloco.py` nas 10 telas com coluna. | Ganho de conteúdo, solta × fixa: **+224 px** com "Seções" e **+194 px** com "Escopo" (1440 px: 1032 → 1256 e 1062 → 1256; 1100 px: 692 → 916 e 722 → 916). Aberta por cima, o conteúdo se move **0 px** (10 de 10 telas). Ícone do botão: 7,53 a 8,20:1 nas 24 capturas (piso 3:1). Réguas: `suite-shell.mjs` SH29-01 a 19 (jsdom: 140 · 0), `render-rail.mjs` R18-e a o (150 de 150: limiar, 56 px, SH12, dobra, `aria-controls`, mouse, teclado, toque, foco não obscurecido, foco sem Tab), HV1 20 de 20 nas 10 telas × 2 temas, MH2 47 de 47 (medidos em 2026-10-18). |

**As decisões D1–D26 do estudo** (expostas a veto), citadas pelo `ESTUDO.md` de cada fase:
- **D1–D14** (fase 1, `ds-w42-entregas/a/ESTUDO.md`): atributo `data-sidebar` (D1) · 56 px por tokens (D2) · botão na base (D3) · nomes (D4, substituído pelo D16) · ícones (D5, substituídos pelo D17) · conteúdo fora da vista (D6, ajustado pelo D19) · sem título na faixa (D7) · foco (D8) · nada persiste na tela (D9) · sem item no menu de conta (D10) · gaveta abaixo de 860 px (D11) · Q3 com a coluna fina (D12) · ancorar (D13, substituído pelo D25) · sem animação (D14, **SUPERSEDIDA** — ver o parágrafo seguinte).
- **D14 — SUPERSEDIDA em 2026-10-28 (leva 48, `SH-P71`).** Era: sem animação de largura (a troca de formato acontecia de uma vez). Veredito dele, folha 14, Q5 = c, 2026-10-28, verbatim: *"aplicar 150 ms direto."* (contra a recomendação "a" da folha, sem observação escrita). Agora: o recolher e o abrir da coluna de contexto, a troca de formato do rail (inclusive o sobrevoo que o expande, SH19) e o empurrão do painel lateral (§31.4) animam a LARGURA em `--seed-dur-productive` (150 ms, token do canon); `prefers-reduced-motion: reduce` troca de uma vez, como antes (o token vai a 0 ms e há `transition: none` explícito); nenhum `transition: all`; a regra do piso de 640 px, a cessão do rail e o Q3 leem o estado FINAL, nunca o meio da animação. O painel aparece de uma vez e só o empurrão do conteúdo anima; o arraste da borda e o carregamento da página não animam (decisões do agente, expostas a veto). Prova: `provas/shell-animacao/prova-animacao-150.mjs` (27 de 27; `--cobaia` reprova a prova cega). A R18 do `render-rail.mjs` mede CONGELADA (`CSS_CONGELA`) e é cega ao meio da animação; quem prova o meio é a prova `shell-animacao`. Safari, Firefox e a barra de rolagem horizontal do rail em Chrome com janela: NÃO MEDI.
- **D15–D26** (fase 3, `ds-w43-entregas/sh29-f3/ESTUDO.md`): mesmos valores do atributo, `aberta` = fixa e `recolhida` = solta (D15) · alternador com nome fixo e `aria-pressed` (D16) · ícones `pin`/`pin-off` (D17) · intenção e carência por token (D18) · conteúdo solto focável e o teclado abre (D19) · abre por cima sem reflow (D20) · Esc com trava (D21) · toque (D22) · clique fora fecha (D23) · clique dentro não fecha (D24) · ancorar abre por cima sem fixar (D25) · estado só pelo ícone, sem placa da marca (D26) · da 2.ª revisão independente: o foco que sai para outro elemento fecha mesmo com o mouse em cima (D27), todo foco que entra abre, menos o de clique/toque nela (D28), tecla desfaz a marca de toque (D29), Esc só com foco ou mouse nela e consumido (D30).
- **Consertos medidos na fase 2** (`ds-w42-entregas/sh29-f2/RELATORIO.md`): o envelope `@container app (width > 860px)` (a coluna ficava em fluxo no celular), o botão `sticky` (34 de 60 combinações com o botão abaixo da dobra) e o Q3 contando só a coluna visível (`nav.sidebar:not([hidden])`).

**Porta do SIGA para a coluna (SH29).**
1. O contêiner `app` declara `data-sidebar="aberta"` ou `"recolhida"` onde houver coluna de contexto, e nasce `aberta`.
2. O botão `.alterna-coluna` na base da coluna alterna os dois; o script do módulo repinta o `aria-pressed` quando o atributo muda por fora.
3. A preferência é do USUÁRIO e GLOBAL, na mesma fronteira do estado do rail: o produto a aplica no atributo antes do primeiro desenho e a grava ao ver o atributo mudar.
4. Abaixo do SH12 a preferência fica guardada e não se aplica.
5. `data-aberto` (aberta por cima) é estado de INTERAÇÃO, nunca preferência: o produto não o grava.

