Componentes
46. Shell de aplicação
seed-componentes.md v2.00 · §46seção 93 de 18446-shell-de-aplicacao-estavel-v0-52-sh1-sh23.md · MD5 f7e5c7f0Título completo no canon: 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
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/).
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) noseed-composicao.mdCP1–CP32; tema e cor em02-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, md569f00537763e14ef907d2f8130c26a92) 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 (#9AA8B0onde o DS tem#90A6B3;#CBD3D8onde 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 noseed-composicao.md§1 (CP1) — canvassurface-subtle, peçasurface-raised+radius-lg+ par sombra+anel, calhasp-3, nada encosta em nada. Registro completo no CP1 doseed-composicao.mdv1.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. |
| 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#788F9Dnos 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-600també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 papelmicropassou 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.02emlocal (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 comoMA-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.pyv0.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: 72pxno span como rede (excesso simétrico peloalign-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.mjs34 · 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 declaramfont-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 asuite-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 asuite-shellSH5-05, asuite-painelPN13-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 mesmo800sem face em mais 24 moldes, no token--seed-txt-titulo-tela-weighte 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#
- Nenhum par de cor novo; todos herdados e medidos.
- Item ativo nunca depende só de cor (e, no estado recolhido do SH19, o rótulo nunca sai do DOM:
titlenão é nome,display:nonenão é clip —suite-shellSH3-04) — na sidebar barra + peso, no rail pílula clara + peso, sempre comaria-current(SH5; SH-P10). - Grayscale: rail, sidebar e ativo permanecem legíveis (DF4 como gate estrutural).
- Regra do um: um item ativo por região; uma região por papel (SH14).
- Landmarks: três a quatro
navsimultâneos, todos com nome único, nenhum contendo a palavra "navegação" (SH2). - 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).
- 360px: rail e sidebar colapsam em drawer modal único; nada transborda; alvos ≥44px (SH12) — e, desde a
SH-P14(SH19), comdata-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-shellR9). Até aSH-P13(2026-09-15) só atela-shellcumpria; 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,
maincom 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 (appmede ·paginanão se aplica) e, quando a raiz eratelaouconteudo— gabarito publicado sem a casca —, dizia NÃO MEDI e pedia--arquetipoa 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êinerappdo shell declaradata-rail="expandido"ou"recolhido"— e nasceexpandidopara todo usuário; (2) o botão.alterna-railna base do rail (o mesmo do módulo:aria-expanded, "Recolher áreas"/"Expandir áreas", chevrons do Lucide) chamaalterna_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 oIsPaneOpenglobal 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-railpassa a ter três valores —recolhido|expandido|largo— e nasceexpandido(a Encurtada) para todo usuário; (2) um segundo atributo no mesmo.app,data-rail-sobrevoo=ligado|desligado, nascedesligadoe só tem efeito comexpandido; (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.appmudar (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-subtleousurface-brand-subtle(sidebar, pílula, badge) usatext-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-ancorabasta. 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.
- O sobrevoo abre a PRÉVIA da coluna de contexto, com o 1.º nível dela. Só com ponteiro fino e
- balao:
- É disclosure do APG (
aria-expanded+aria-controls), nuncarole="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 nuncarole="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 (abreBalaomederail.right).
- É disclosure do APG (
- 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 únicoshell_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-painelcitada 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): atributodata-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: reducetroca de uma vez, como antes (o token vai a 0 ms e hátransition: noneexplícito); nenhumtransition: 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;--cobaiareprova a prova cega). A R18 dorender-rail.mjsmede CONGELADA (CSS_CONGELA) e é cega ao meio da animação; quem prova o meio é a provashell-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 erecolhida= solta (D15) · alternador com nome fixo earia-pressed(D16) · íconespin/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ãosticky(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).
- O contêiner
appdeclaradata-sidebar="aberta"ou"recolhida"onde houver coluna de contexto, e nasceaberta. - O botão
.alterna-colunana base da coluna alterna os dois; o script do módulo repinta oaria-pressedquando o atributo muda por fora. - 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.
- Abaixo do SH12 a preferência fica guardada e não se aplica.
data-aberto(aberta por cima) é estado de INTERAÇÃO, nunca preferência: o produto não o grava.
Também cita o §46: tela-atividade, tela-busca, tela-chat, tela-detalhe, tela-gantt, tela-lista, tela-mensageria, tela-onboarding, tela-portal-cliente, tela-portal-parceiro, tela-quadro, tela-quadro-funil, tela-referencia, tela-shell-abas, tela-shell-sem-topbar, tela-tabela.