---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 74
titulo: "BT1 FECHA POR INSTRUMENTO — a barra de provas travada no topo em TODO o acervo (2026-08-20, DÉCIMA parte) · nasce `validacao/guarda-barra-fixa.mjs`, **alvo de PASTA**"
sequencia: 80 de 98
bytes_do_corpo: 17949
md5_do_corpo: d0255e969f39a7e07038fe10a5a66984
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 74. BT1 FECHA POR INSTRUMENTO — a barra de provas travada no topo em TODO o acervo (2026-08-20, DÉCIMA parte) · nasce `validacao/guarda-barra-fixa.mjs`, **alvo de PASTA**

> **Para quem chega sem contexto.** **BT1** é o contrato, escrito em **§64.1** desde 2026-08-16, que
> diz: *a barra de controles de todo artefato produzido — bancada OU tela — é fixa no topo*
> (`position:sticky; top:0`, com faixa de fundo própria e sombra de separação). **Barra de provas** é
> essa barra: os botões que existem só para AVALIAR o artefato (alternar tema claro/escuro, prova em
> escala de cinza, seletor de largura de página), não para usá-lo. **Bancada** (`banco-*.html`) é o
> catálogo dos estados de um componente; **tela** (`tela-*.html`) é um caso de uso montado.
> **Alvo de pasta** é a propriedade de um instrumento que descobre seus próprios alvos varrendo o
> diretório (`readdirSync(dir).filter(f => f.endsWith('.html'))`) em vez de percorrer uma lista
> escrita à mão — com isso a cobertura cresce sozinha quando nasce um arquivo novo.
>
> Esta seção **não** cria contrato novo. Ela registra que o contrato de 2026-08-16 **nunca havia sido
> medido no acervo inteiro**, e o instrumento que passou a medir.

### 74.1 Por que a seção existe: a BT-P2 foi declarada fechada sobre uma LISTA

O contrato BT1 nasceu de um gate visual em 2026-08-16, verbatim do Rafael:

> *"em uma avaliação de página .html deixe sempre o topo com escala de cinza, claro ou escuro, tamanho
> de página, sempre travado no topo pra quando rolar a página ele ficar fixo no topo"*

e foi estendido a telas no dia seguinte, também verbatim:

> *"todo material que você produzir tem que ter a barra fixa, todos você já tem essa opção, só não é
> fixo"*

A pendência que aplicava isso — a **BT-P2** — foi **declarada FECHADA em 2026-08-17** com a frase
*"aplicada e MEDIDA em nove telas mais `banco-dominio`"*, e com uma única exclusão declarada
(`tela-site.html`). **Dez artefatos. O acervo tem trinta e quatro** (cinquenta e um HTMLs contando a
família de e-mail e os mostruários).

Em 2026-08-20 o Rafael abriu o `banco-navegacao.html`, viu os três botões de prova soltos no fluxo do
documento — rolando para fora da janela junto com o conteúdo — e escreveu:

> *"lembra que eu pedi para todos os arquivos .html que tiverem seletor de claro/escuro ou outro tipo
> de edicao, que era pra fixar isso na barra superior. vc fez em varios arquivos, mas o
> banco-navegacao.html nao está dessa forma. **acredito ter outros**."*

> ### A LIÇÃO DE MÉTODO — e esta casa já pagou por ela mais de uma vez
> **PENDÊNCIA DE CONTRATO TRANSVERSAL NÃO FECHA POR LISTA — FECHA POR INSTRUMENTO DE ALVO DE PASTA.**
> O contrato diz *"todo artefato produzido"*; a verificação cobriu dez de trinta e quatro. E
> *"acredito ter outros"* é a forma polida de dizer que **ninguém contou**. A mesma família de defeito
> apareceu no **42º defeito** (§73): a varredura de contraste escolhia alvo por **prefixo de nome de
> arquivo** e deixava 17 dos 51 HTMLs de fora — escondendo 862 folhas de texto reprovadas.
>
> *Alternativa descartada:* consertar só o `banco-navegacao.html` (o arquivo que ele apontou) e
> responder "feito". Descartada porque o próprio pedido dele contém a razão — *"acredito ter outros"*
> —, e porque um conserto sem instrumento não impede o defeito de voltar no próximo arquivo novo.

### 74.2 As quatro cláusulas do instrumento

O `validacao/guarda-barra-fixa.mjs` mede BT1 em quatro cláusulas. **Três das quatro são
COMPORTAMENTAIS** — a página é rolada de verdade num Chromium de verdade e o retângulo é medido
depois — porque `position:sticky` declarado na folha de estilo **não é prova de que a barra gruda**.

| # | Cláusula | Como é medida | Por que ela existe |
|---|---|---|---|
| **BT1-a** | **A barra é travada** | `getComputedStyle(barra).position` ∈ {`sticky`, `fixed`} | **Peneira apenas.** Serve para nomear a causa no relatório; o veredito de verdade é o da BT1-b |
| **BT1-b** | **Ela continua no topo depois de ROLAR** | rola a página até o fim; exige topo do retângulo **dentro da janela** e a **menos de 4px de zero** | Pega o defeito real mais comum: `sticky` declarado e **morto** porque um ANCESTRAL tem `overflow:hidden`, `overflow:auto`, `transform`, `filter` ou `contain` — `sticky` só funciona no contexto de rolagem do ancestral, e **isso não se vê na folha de estilo**. A guarda diagnostica o ancestral culpado pelo nome |
| **BT1-c** | **Ela não é coberta** | depois de rolar, `elementFromPoint` no centro da barra devolve a barra ou um descendente dela; **e** se o clique no controle é INTERCEPTADO, reprova aqui | Nasceu de defeito medido em 2026-08-17: na `tela-chat` a barra e o painel de chat empatavam em `z-index:60` e, a 320px, o chat cobria a barra inteira. **Barra coberta é instrumento inoperante, não alvo ausente** — por isso é FAIL e não `[n/a]` |
| **BT1-d** | **Ela não cobre conteúdo** | com a página **NO TOPO**, o irmão seguinte tem de começar depois do fim da barra | O padrão canônico exige `sticky` e **não** `fixed`, para a barra continuar ocupando espaço no fluxo. Medido: com `fixed`, o primeiro elemento depois dela fica DEBAIXO dela |

### 74.3 Como os controles de prova são achados — peneira DECLARADA + prova COMPORTAMENTAL

⚠ **A peneira inicial é por TEXTO ACESSÍVEL do controle, e ela é uma lista escrita à mão** — que é
exatamente o defeito que esta guarda nasceu para consertar. Usá-la aqui é **dívida declarada**: o
vocabulário sai **IMPRESSO no placar** junto com a contagem do que descartou.

Vocabulário medido em vigor: `tema · escuro · claro · dark · light · cinza · grayscale · escala de
cinza · largura · faixa · px · prova · provas · alternar · grade · baseline · forçar · forcar`.
Medido a 1440×900: **93 candidatos** pela peneira, **608 controles descartados**.

O que impede a dívida de virar mentira é a segunda etapa: **nenhum candidato vira controle de prova
sem PROVA COMPORTAMENTAL.** A guarda **clica** o candidato e exige que o clique mude a assinatura do
`<html>` — um atributo (`data-theme`, `class`, `style`), o `filter` computado, ou a largura do
contêiner de conteúdo. Dos 93 candidatos, **33 se provaram por comportamento**.

> **Candidato que passa a peneira e NÃO muda nada sai `[n/a]` NOMEADO, nunca FAIL** — pode ser um
> botão de conteúdo cujo rótulo apenas *parece* de instrumento. E o clique é **desfeito** (segundo
> clique quando há `aria-pressed`, recarga da página quando não há), para o passe seguinte medir a
> mesma página.

### 74.4 O censo: **22 PASS · 11 FAIL · 18 [n/a]** → **33 PASS · 0 FAIL · 18 [n/a]**

Placar de abertura a 1440×900, com a decomposição por cláusula: **9 BT1-a · 10 BT1-b · 0 BT1-c ·
2 BT1-d**. Os onze reprovados, com o número medido:

| artefato | contêiner da barra | `position` antes | topo medido depois de rolar |
|---|---|---|---|
| `banco-cn.html` | `main.controls` | `static` | **+80px** (a barra desceu com o conteúdo) |
| `banco-composicao.html` | `div.ctr` | `static` | **−1689px** (saiu da janela) |
| `banco-dados.html` | `div.controls` | `static` | **−21,1px** |
| `banco-dataviz-di.html` | `div.bar` | `static` | **−4639,7px** |
| `banco-dataviz-tokens.html` | `div.toolbar` | `static` | **−640,6px** |
| `banco-feedback.html` | `div.toolbar` | **`fixed`** | **+12px** — travada, mas **BT1-b** (12px > 4px de tolerância) **e BT1-d** (cobria o conteúdo) |
| `banco-formfield.html` | `header.top` | `static` | **−7503px** |
| `banco-icones.html` | `div.bar` | `static` | **−221,2px** |
| `banco-navegacao.html` | `div.controls` | `static` | **−1414,1px** — o arquivo que o Rafael apontou a olho nu |
| `banco-superficies.html` | `div.toolbar` | **`fixed`** | **+12px** — mesmo par BT1-b + BT1-d |
| `banco-tokens.html` | `header` | `static` | **−1811px** |

**Depois do conserto: 33 PASS · 0 FAIL · 18 [n/a]**, medido em **DUAS condições** — 1440×900 **e**
320×900. *Medir duas vezes significa VARIAR UMA CONDIÇÃO, não repetir o mesmo comando:* a 320px o
número de candidatos cai para 92 e o de descartados para 585, e o veredito não muda.

Os **18 `[n/a]`** são nomeados, não mudos, e o censo agrega o motivo: **18× artefato SEM controle de
prova** — a família de e-mail (`ea-*`, `en-*`, `et-*` e `seed-email-*`), que é HTML de e-mail e **não
tem nem pode ter** instrumento de avaliação embutido; mais `banco-componentes`, `reconstrucao-dm`,
`seed-dataviz-di-prova-impressa` e `seed-design-system`. Há ainda **2×** (1× a 320px) o motivo
*página NÃO ROLA nesta janela* — `tela-shell` e `tela-referencia` cabem em 900px de altura, e onde não
há rolagem a BT1-b **não pode ser medida**; o veredito de PASS ali vem das outras três cláusulas.

### 74.5 O conserto canônico — e a PRIMEIRA tentativa que o print do Rafael revogou

O bloco aplicado aos onze, idêntico em todos:

```css
#seed-barra-provas { position: sticky; top: 0; z-index: 9000;
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin: 0 0 16px; padding: 10px 12px;
  background: var(--seed-surface-subtle); border-bottom: 2px solid var(--seed-border-default);
  box-shadow: 0 1px 0 rgba(0,0,0,.04), 0 6px 16px -12px rgba(0,0,0,.5); }
```

Três decisões de forma, com o porquê:

1. **O contêiner recebeu `id="seed-barra-provas"`, não uma classe nova.** *Alternativa descartada:*
   trocar a classe existente (`.controls`, `.toolbar`, `.bar`, `.ctr`) por uma única classe canônica.
   Descartada porque **quebraria toda suíte que consulta o seletor antigo** — e o `id` é específico o
   bastante para a regra não vazar para outros elementos com a mesma classe.
2. **`sticky`, não `fixed`.** É a BT1-d: `fixed` sai do fluxo e cobre o primeiro elemento seguinte.
   Os dois arquivos que já usavam `fixed` (`banco-feedback`, `banco-superficies`) reprovavam por isso.
3. **`flex-wrap: wrap`.** A 320px os três botões não cabem em uma linha; sem quebra, o último vaza da
   caixa — que é exatamente a cláusula **SH1-d** de §72.

> ⚠ **A primeira tentativa foi REVOGADA pelo print.** Travar a barra onde ela estava deixou-a
> **ABAIXO do título** do documento: ao rolar, o que ficava grudado no topo era um retângulo de botões
> com o `<h1>` já fora da tela — visualmente pior que antes. **Conserto real: o nó inteiro foi MOVIDO
> para ser o primeiro filho de `<body>`.** É a regra **4.1.10** do método em ação pela segunda sessão
> consecutiva: *medição de propriedade pode passar enquanto o olho reprova; o juiz da aparência é o
> PIXEL, e no caso da composição é o gate visual.*

**Seis dos onze também ganharam declaração de token**: eles consumiam `--seed-surface-subtle` e
`--seed-border-default` — que a folha nova usa — **sem declará-los em nenhum bloco de tema**.

### 74.6 Duas suítes reprovaram meu conserto, e as duas estavam CERTAS

Depois do conserto, `suite-dados` deu **38 · 1** e `suite-navegacao` deu **92 · 1** — as duas nas
provas **NV-01/NV-02**, que exigem que todo token consumido exista declarado. Eram **tokens
fantasma**: os seis arquivos citados acima. Conserto **na causa** (declarar os dois tokens em cada
bloco de tema), não no sintoma: **39 · 0** e **93 · 0**.

> É **exatamente** o mesmo defeito que a guarda **BP1** achou em seis bancadas em 2026-08-17. Fica
> registrado porque **defeito que repete em família é defeito de método, não de arquivo**: a casa
> ainda não tem guarda que impeça um bloco de estilo novo de consumir token não declarado **no ato da
> escrita** — só suíte que o pega depois.

### 74.7 A pasta de prova `render-audit/prova-bt1/` — onde REPROVAR é o resultado desejado

Sete fixtures, uma por cláusula e uma por caminho de `[n/a]`. **Referência: `1 PASS · 4 FAIL ·
2 [n/a]`.**

| fixture | o que ela é | veredito esperado |
|---|---|---|
| `bt-ok.html` | `sticky` correto | **PASS** |
| `bt-fluxo.html` | barra solta no fluxo | **FAIL** BT1-a + BT1-b |
| `bt-sticky-morto.html` | `sticky` matado por ancestral `overflow:hidden` | **FAIL** BT1-b (e a guarda **nomeia o ancestral**) |
| `bt-fixed-cobre.html` | `fixed` | **FAIL** BT1-d |
| `bt-coberto.html` | `sticky` correto, coberto por empate de `z-index:60` | **FAIL** BT1-c |
| `bt-sem-controle.html` | nenhum controle de prova | **`[n/a]`** *artefato sem controle de prova* |
| `bt-rotulo-falso.html` | rótulos que **parecem** instrumento e não mudam nada | **`[n/a]`** *candidato não muda o `<html>`* |

**A pasta de prova pegou dois defeitos do próprio instrumento, antes de o acervo ser medido:**

1. **Falso positivo na BT1-d.** A versão 1 media "o irmão seguinte está debaixo da barra **depois de
   rolar**" — que é **exatamente o que um `sticky` legítimo faz**. O `bt-ok.html` reprovou. Conserto:
   **medir com a página NO TOPO**.
2. **`[n/a]` com o motivo ERRADO.** O `bt-coberto.html` saía como *"rótulo parece de instrumento e não
   é"*; a verdade era *"o controle está coberto"*. Conserto: passou a **reprovar BT1-c nomeando o
   elemento que intercepta**. Fica como regra: **`[n/a]` com motivo errado é PIOR que `[n/a]` mudo**,
   porque o motivo errado encerra a investigação.

### 74.8 Regra nova de FORMA DE ENTREGA: demonstração viva é EXTRAÍDA, nunca redigitada

Pedido do Rafael, verbatim:

> *"ao invés de me pedir para abrir o arquivo, banco-navegacao.html para verificar, abaixo do print,
> traxa a pagina viva para eu poder passar o mouse e testar, para nao ter que ir até o arquivo pra
> fazer o teste. **basta repetir o codigo daquela parte correto?** passe a fazer assim para todos os
> exemplos que precisa de eu passar o mouse ou clicar pra testar."*

*"Basta repetir o código daquela parte"* é a pergunta certa, e a resposta é **quase**. Trecho
**redigitado** na folha de conferência torna a folha uma **SEGUNDA FONTE**: ela pode mostrar um botão
que se comporta de um jeito enquanto o artefato se comporta de outro, e ninguém notaria — a classe de
defeito que este projeto chama de **dado sintético plausível**, o mais perigoso porque não chama
atenção e por isso não é conferido.

> **REGRA: DEMONSTRAÇÃO VIVA NUNCA É REDIGITADA — É EXTRAÍDA.** Nasce
> `validacao/extrai-vivo.mjs`, que abre o artefato real num Chromium, colhe o bloco de tokens, as
> regras que **alcançam** o trecho e o markup, e emite um HTML autossuficiente para ir dentro de um
> `<iframe srcdoc sandbox="allow-scripts">` da folha. *Se o artefato mudar e a folha for regerada, a
> demonstração muda com ele. Se as duas divergirem, é porque alguém editou a folha em vez de
> regerá-la.*

⚠ **FRONTEIRA DECLARADA: o iframe NÃO é o artefato.** Ele não tem o layout inteiro em volta, então
**não serve** para julgar composição, aperto de largura nem colisão — para isso o veredito é do
artefato e das guardas. Ele serve para o que foi pedido: **passar o mouse e clicar**.

**44º defeito de instrumento: a versão 1 do `extrai-vivo.mjs` lia CSS com REGEX.** Medido na hora de
provar a folha: **em TRÊS dos CINCO quadros o bloco de tokens não entrou** — `--seed-text-primary`
resolvia para vazio dentro do iframe e o fundo saía transparente. Causa: **chave dentro de comentário
CSS desalinha um parser de texto**, e esta casa acabou de escrever, no mesmo dia, comentários que
contêm `{ position: fixed }`. **A régua certa já existia na casa**: a `guarda-literal-de-cor.mjs`
percorre o **CSSOM** (`document.styleSheets` → `cssRules`) desde que nasceu — no CSSOM o comentário
não existe e o seletor já vem normalizado. Reescrito por CSSOM: **5 de 5 resolvem.** *Terceira vez na
mesma sessão em que a régua certa já estava escrita em outro arquivo.*

⚠ Duas armadilhas registradas dentro da ferramenta: **`CSSStyleRule` também tem `cssRules` no Chromium
moderno** (31º defeito) — por isso a recursão testa `style` **antes** de `cssRules`; e **a folha de
estilo da demonstração tem de vir DEPOIS do CSS extraído**, senão a regra `body` do artefato a
sobrescreve (medido: o fundo saía transparente).

**Fidelidade dos quadros, medida pela guarda HV1 oficial** (não por sonda própria — minha primeira
sonda de sobrevoo dentro do iframe relatou "0 de 19", e era **falsa**: `boundingBox()` dentro de um
iframe de origem opaca não dá coordenada usável): `vivo-paginacao-claro` **6/0/0**,
`vivo-paginacao-escuro` **6/0/0**, `vivo-linha-abrir` **10/0/0**, `vivo-btn-ghost` **4/1/0** — e esse
único "1" **reproduz um defeito real remanescente** de HV1-a no artefato, o que é a prova de que o
quadro é fiel.

### 74.9 Pendências abertas por esta seção

| # | Pendência | Por que fica aberta, com número |
|---|---|---|
| **BT-P3** | **O contrato BT2 — seletor de LARGURA DE PÁGINA em toda bancada — não foi medido por instrumento.** A `guarda-barra-fixa.mjs` declara não julgar a COMPOSIÇÃO da barra | BT1 e BT2 nasceram no mesmo gate (§64.1) e só um dos dois ganhou régua. Dos **33** artefatos com barra provada por comportamento, quantos têm seletor de largura é hoje **desconhecido** — e "desconhecido" é o estado que a BT-P2 tinha quando foi declarada fechada |
| **IN-P2** | **Nenhum censo diz quais `.mjs` desta casa leem CSS por TEXTO em vez de CSSOM.** O 44º defeito acabou de custar 3 de 5 quadros | A `guarda-literal-de-cor.mjs` e o `extrai-vivo.mjs` v2 usam CSSOM; os outros **não foram verificados**. Enquanto o censo não existe, o defeito pode estar dormindo em qualquer instrumento que leia folha de estilo |

---

