---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.63
secao: 46
titulo: "Shell de aplicação — **`estável`** (v0.50) · SH1–SH19 · 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) · **gate visual aprovado 2026-08-11 — FECHA O BLOCO 6A**"
quando_consultar: "SHELL DE APLICAÇÃO — COMECE AQUI PARA QUALQUER TELA DE PRODUTO: rail, topbar, sidebar, conteúdo; SH1–SH17. No produto toda tela vive dentro dele (SH17, §46.4, com a tabela dos 16 gabaritos)."
sequencia: 48 de 99
bytes_do_corpo: 51004
md5_do_corpo: 68a26f20f1e969c057bb04b2e86e04d6
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
---
## 46. Shell de aplicação — **`estável`** (v0.50) · SH1–SH19 · 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) · **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"*.
>
> **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 ERP — 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 ERP é **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.
>
> **Base (3 rodadas encadeadas, 2026-08-11):** **R1 canon interno** — o §33 como molde de pattern
> F6; o Bloco 5 inteiro como insumo (o shell não inventa, arruma); MN1 (as quatro saídas
> semânticas) e MN6 (comando indisponível fica visível), que o SH6 precisa distinguir; DW1 (os
> dois regimes do drawer) e CN6 (o precedente de standard); a escala de sobreposição
> 60<65<70<75<80; o §40 (densidade compacta medida em 33px). **R2 mercado e stack** — componente
> Sidebar oficial do shadcn/ui, que é o consumidor real do Lovable, com `SidebarProvider` e os
> três modos `offcanvas`/`icon`/`none`; blocos de sidebar colapsável com `Collapsible` do Radix e
> threading por `border-l`; prática consolidada de SaaS enterprise (topo para contexto global,
> lateral para navegação primária, porque as duas camadas fazem trabalhos diferentes e param de
> disputar espaço); SAP Fiori launchpad shell bar (logo, back, título, busca corporativa,
> notificações, Me Area). **R3 normas e fora-do-circuito** — ARIA11/W3C sobre landmark repetido
> exigindo nome único; MDN sobre `role="navigation"`; `aria-current="page"` como critério AAA de
> baixo custo; o corpus de acessibilidade de SPA (foco preso na navegação após troca de rota é o
> defeito nº 1, e o alvo do foco não pode ser landmark, link nem botão); Material Design
> navigation rail (3–7 destinos, posicionado abaixo da top bar). Consolidado aprovado pelo Rafael
> em 2026-08-11.
>
> **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 e SH19 (SH17 e SH18 vivem em 46.4 e 46.5)

> **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. **A exceção nomeada do rail foi SUPERSEDIDA no gate de
> 2026-08-15** (*"um bloco montado como os outros, todos independentes, igual o ClickUp"*): 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). Registro
> completo no CP1 do `seed-composicao.md` v1.4. O shell é a primeira instância
> do contrato, não a dona dele (supersede SUP-1, 2026-08-14; fecha a errata E-CF-03 — o
> cabeçalho desta seção dizia "SH1–SH14" com a tabela terminando em SH15).

| # | 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** · **largura 80px** · ícone do set §45 **+ rótulo sempre visível NO ESTADO PADRÃO, ≤9 caracteres por palavra** *(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 · **altura total, à esquerda da topbar** | 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 caracteres são MEDIDOS** (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**. *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 | 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) · 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** | 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 | 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 ERP: é produto, não DS | 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** | 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) | **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) |
| **SH14** | **Uma região NUNCA faz o trabalho de outra.** Se rail e sidebar coexistem, o rail é destino de topo e a sidebar é contexto | 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** | **ESTADOS DO RAIL (2026-09-15, `SH-P14`): o rail tem DOIS estados, declarados no atributo `data-rail` do contêiner `app` (o mesmo elemento que nomeia o contêiner do SH12): `expandido` — o PADRÃO do SH3, 80 px, ícone 20 + rótulo visível, como TODA tela nasce — e `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). **Gatilho: um BOTÃO no próprio rail, na BASE** (`.alterna-rail`, 48 × 44, a 8 px da base, último focável do rail — a ordem de Tab dos destinos não muda; `aria-expanded` = "o rail está expandido"; nome acessível "Recolher áreas"/"Expandir áreas"; ícones Lucide `chevrons-left`/`chevrons-right`, NM4 ②). **Quem LEMBRA o estado é o PRODUTO**: preferência do usuário, GLOBAL (nunca por tela), nasce expandido — as telas de referência não persistem nada (§46.5, porta do ERP). **O recolhido NÃO 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 onze telas; a régua CP-13 aceita 80 ou 56 conforme o atributo. | 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. | 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) · 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) |

### 46.2 Anatomia, tokens e fronteiras

**Rail:** largura **80px** (SH3 — medido: 68px úteis = 9 caracteres; "Comercial" cabe); 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). **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; `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. O painel **`.escopo`** de quadro/detalhe/gantt
**não entra** — se ele é a sidebar do shell ou painel de conteúdo é a `SH-P12`. *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**.

> **PENDÊNCIA SH-P1 — buraco na camada semântica, achado por este bloco.** **Nenhum token
> semântico de borda passa 3:1 contra `surface-raised` no tema claro:** `border-default` mede
> **1,49** e `border-strong` **2,53**. O campo de busca precisa de contorno que o identifique
> como componente (1.4.11), e a única saída medida foi consumir o **primitivo `cinza-500`**
> (3,38 no claro · 4,50 no escuro). Isso é **empréstimo declarado**, não regra nova — e viola a
> lei "componente consome semântico". *A correção certa é um token semântico novo na camada 2*,
> e ela não pertence a este bloco: mexer nos três gêmeos por causa do shell seria decidir a
> camada de tokens dentro de um pattern. Fecha quando a camada 2 for editada por outro motivo,
> pela regra GI2.
>
> **✅ 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".
>
> ✅ **`SH-P10` FECHADA em 2026-09-13 — veredito dele, verbatim: *"SH-P10: b-tirar-do-rail"* (MANIFESTO §209). Aplicado: a barra saiu do rail nos 8 moldes (a da sidebar ficou), SH5 reescrito por região, suítes invertidas para provar a ausência. O registro do achado, como estava:** a barra vertical do item ativo do rail: ele a viu como erro; é a marca do SH5. Verbatim dele, na aprovação do shell com material (MANIFESTO §207): *"A Rail está com o menu Comercial selecionado, repare no canto esquerdo que tem uma barcação (barra vertical) essa barra nao deveria estar ali, acho que ela vem de outra estruta e é aplicada ali de maneira errada. verifique por favor."* **Medido:** é o `::before` de `.rail-item[aria-current="page"]` — barra branca de 3 px, `left: -4px`, do topo 8 px à base 8 px do item, encostada na borda interna do rail; **não vem de outra estrutura**: é a regra SH5 desta seção (*"barra lateral de 3px mais peso tipográfico, nunca só fundo colorido"*), aplicada ao rail desde o Bloco 6A, invisível até 2026-08-15 (vivia em `left: -8px`, fora da caixa) e trazida para dentro pelo probe de pixel daquele dia; o gate de 2026-08-15/16 aprovou o shell com ela visível. A mesma barra existe nas outras sete telas com rail (`.rail-item.ativo::before` nos moldes de chat, detalhe, gantt, lista, quadro, referência e tabela) e a `suite-composicao.mjs` sonda o PIXEL dela (PX-01/PX-02); a `suite-shell.mjs` exige a regra (SH5-04). **Por que ela lê como resíduo agora:** com o material, a pílula clara ganhou volume e a barra ficou separada dela por 4 px de metal — e a pílula clara sobre o rail escuro **já sobrevive ao cinza sozinha** (é luminância: fronteira 5,31/7,87, SH15-b), com o peso 800 como segundo mecanismo; a barra foi desenhada para a **sidebar**, onde o ativo é só um fundo quase igual ao papel, e replicada no rail por simetria do SH5. **É decisão registrada, logo supersede é dele.** Duas saídas, renderizadas em cor e em cinza (folha SH-P10): **(a)** manter — nada muda; **(b)** tirar a barra do **rail** (a da sidebar fica) — o SH5 ganha a redação "no rail, a pílula clara é a marca que sobrevive ao cinza; a barra é da sidebar"; custo medido: 8 moldes (shell + 7 telas), SH5-04 da `suite-shell`, as sondas PX-01/PX-02 da `suite-composicao` (que passam a provar a AUSÊNCIA da barra fora da pílula), regeneração byte-idêntica das 8 telas e re-gate por captura — meia sessão. Dono: ele (veredito), depois a sessão. Nada foi mexido até o veredito.

**Fora do shell, declarado:** que menus existem e o que há dentro deles (**projeto do ERP**) ·
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).*

*(`SH-P14`, 2026-09-15 — as quatro camadas remedidas com o SH19: `suite-shell.mjs` **84 · 0** (SH3-04 e SH3-07 reescritos com o sinal certo; seção SH19 com 12 asserts; cobaia do HEAD reprova 13), `render-shell.mjs` **54 · 0** (R5 geometria dos dois estados · R6 conteúdo +24 px por viewport · R7 tooltip por teclado sem cobrir topbar/seletor e Esc · R8 nascimento expandido sem persistência · R9 drawer com rótulos), `contraste-shell.py` **55 · 0** (SH-R9/R10, o par do tooltip por tema), RC rasterizada **22 de 22** telas × tema e, na cobaia com o tooltip aberto (`shell-rail-recolhido-cobaia.html`, autofocus no 1.º destino), o tooltip medido no pixel a **13,86 / 12,75**; CP-13 **11 de 11** aceitando 80 (padrão) ou 56 (recolhido declarado) — cobaia negativa a 58 px reprova por uma linha (57 cai na tolerância declarada de 1 px da régua).)*

*(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)

> **Por que esta regra nasce agora.** Em 2026-09-14 a sessão do ERP construiu a tela "Configurar funil" seguindo o
> gabarito A18 (§86) — e a tela saiu **sem shell**: só uma barra superior, sem rail, sem sidebar. Ele reprovou de
> imediato, verbatim: *"tem certeza que as telas sao assim? o quadro aprovado do ERP tem uma rail a esquerda, etc. to
> achando essa tela muito simplória"*. Medido depois (MANIFESTO §219): a tela de referência do A18 é publicada SEM a
> casca (raiz `tela`, CP28 do `seed-composicao.md` — *"arquétipo que roda SEM shell"*), o §86 não cita o §46 uma vez,
> e nada no canon dizia com todas as letras o que todo mundo da casa sabia: **no produto, a casca é o shell e o
> gabarito é o que vai dentro**. Um agente de fora leu o gabarito como decisão de produto. Esta subseção fecha o buraco
> — e a página `/telas/` da vitrine passa a mostrar, por gabarito, se a referência traz a casca e onde ele vive no
> produto (lido desta tabela e medido no disco pelo gerador).

| # | Decisão | Porquê | Descartado |
|---|---|---|---|
| **SH17** | **No produto (ERP 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). |

**Os 16 gabaritos publicados, medidos no disco em 2026-09-14 (coluna "rail funcional" medida em 2026-09-15).** A coluna
"referência traz a casca" é MEDIDA no HTML (`class="rail"` e `class="topbar"` presentes); 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. 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 |
| 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 |
| 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 ERP 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 |

**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 (ERP, 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 ERP 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"*.

> **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.


---

