Componentes
75. TP1 — A TIPOGRAFIA E OS RECURSOS DO ARTEFATO REALMENTE CARREGAM
seed-componentes.md v2.00 · §75seção 154 de 18475-tp1-a-tipografia-e-os-recursos-do-artefato.md · MD5 aa54844dTítulo completo no canon: TP1 — A TIPOGRAFIA E OS RECURSOS DO ARTEFATO REALMENTE CARREGAM · regra transversal (2026-08-20, décima parte, segunda rodada) · 06-validacao/guardas/guarda-tipografia-viva.mjs · e as duas decisões de cor que estão ESPERANDO GATE — estável
Em uma frase: Fonte, peso e arquivo têm de carregar DE VERDADE no artefato: vale o que o navegador resolveu, não o que o CSS pede.
Para quem chega sem contexto. Esta seção nasceu de uma pergunta do Rafael que era sobre outra coisa. Ele viu, num anexo, "uma imagem que não carregou" e perguntou se ela mudava a avaliação de contraste. Não mudava — e a resposta está em §75.1, com número. Mas a investigação achou uma dimensão de cobertura inteira que não existia: ninguém nesta casa jamais mediu se as famílias tipográficas e os recursos externos que um artefato declara realmente chegam.
Pergunta do decisor sobre um detalhe é o modo mais barato de descobrir uma dimensão de cobertura inteira que não existia.
Vocabulário. Pilha de
font-family= a lista de alternativas de uma declaração ('Montserrat', sans-serifé UMA pilha com uma família nomeada e uma genérica). Genérica =serif,sans-serif,cursive,monospace,system-uie afins — o navegador sempre resolve.@font-faceembutido = a fonte viaja dentro do arquivo (ou vem de umwoff2declarado), e por isso é portátil. Fonte de sistema = a família existe na máquina de quem olha, e por isso não é portátil.
75.1 A resposta à pergunta: a imagem quebrada NÃO muda o veredito#
Medido variando uma condição — o mesmo cartão renderizado (A) com as imagens quebradas e (B) com as imagens substituídas por um arquivo local do mesmo tamanho declarado:
| o que foi medido | A · imagem quebrada | B · imagem carregada | diferença |
|---|---|---|---|
| cor da tinta do texto amarelo | rgb(250,214,29) |
rgb(250,214,29) |
zero |
| tamanho / peso | 18px / 300 | 18px / 300 | zero |
| retângulo do texto dentro do cartão | 221,1px do topo · 248,9×55,8 | 221,1px do topo · 248,9×55,8 | zero |
| cor do fundo no pixel | #098475 |
#098475 |
zero |
O documento fica 1.099px mais alto com as 45 imagens presentes, e a caixa do logotipo muda 0,8px de altura — mas nenhum dos dois move o texto dentro do cartão. Logo os 3,22 do amarelo estão certos, com ou sem a imagem.
⚠ O que a pergunta não continha, e é maior. O
seed-design-system.htmldepende de 47 recursos de rede: 45 imagens emlh3.googleusercontent.com(Google Drive) e 1 folha do Google Fonts que traz duas famílias. Medido: 0 de 45 imagens e 0 de 2 famílias carregam, todas comERR_TUNNEL_CONNECTION_FAILED. Consequência: todo recorte daquele artefato que esta casa já mostrou ao decisor saiu com a tipografia de RESERVA. O número de contraste nunca mudou por isso — cor, tamanho e peso são declarados em CSS e não vêm da fonte —, mas a aparência que ele julgou não era a real. E aparência é o domínio dele, não do instrumento.
75.2 ⚠⚠ A RÉGUA ÓBVIA MENTE — e é por isso que a guarda existe#
document.fonts.check("18px 'Indie Flower'") devolveu true com a folha de fonte falhando. Ela
responde sobre a família resolvida, e a resolvida era a de reserva.
Guarda de fonte escrita com
check()mede sempre verde. Fica catalogado como armadilha de instrumento, ao lado do 31º defeito (CSSStyleRuletambém temcssRules) e do 44º (parser de CSS por regex).
As duas réguas honestas — e a guarda usa as duas, porque medir duas vezes é variar uma condição:
| régua | o que ela prova | medido no seed-design-system.html |
|---|---|---|
[...document.fonts].length |
portabilidade — o FontFaceSet só ganha entrada com @font-face de verdade carregado |
0 antes do reparo · 7 depois |
| largura em canvas do mesmo texto com a família e com uma família inexistente | se a família entrou de algum jeito (embutida ou de sistema) | 348 = 348 — idênticas, logo não carregou |
O cruzamento das duas é o que distingue @font-face de fonte de sistema, e essa distinção é o valor
principal da guarda.
75.3 Os contratos#
| # | Contrato | Veredito | Por quê |
|---|---|---|---|
| TP1-a | toda pilha de font-family resolve alguma coisa declarada — é FAIL só quando nenhuma família nomeada resolve e a pilha não termina numa genérica |
FAIL | aí o navegador escolhe sem nenhuma instrução do artefato, e a tipografia deixou de ser uma decisão |
| TP1-b | nenhum recurso externo falha | FAIL | não é sobre fonte: é sobre o artefato ser autossuficiente. Um artefato canônico que perde a marca quando o Drive muda uma permissão não é confiável |
| TP1-c | imagem declarada tem pixel (complete && naturalWidth>0) |
FAIL | o texto de alt que aparece no lugar dela é tinta que nenhuma régua desta casa mede — <img> não tem nó de texto próprio, logo a ausência não entra em nenhum placar de contraste |
[achado] PORTABILIDADE |
a pilha resolve, mas por fonte de sistema, sem @font-face |
contado, nunca FAIL | não é violação de contrato — é dependência da máquina de quem olha, e tem de aparecer no placar |
[achado] PRIMEIRA ESCOLHA |
a primeira família da pilha não resolve, mas uma alternativa resolve | contado, nunca FAIL | a pilha está funcionando, mas o artefato não está recebendo a fonte que pediu primeiro |
75.4 O placar, e a leitura correta dele#
Acervo (51 arquivos, 1440×900): 30 PASS · 21 FAIL · 0 [n/a] — 0 TP1-a · 21 TP1-b · 14 TP1-c.
Achados contados: 85 de portabilidade · 56 de primeira escolha.
Nenhum artefato perdeu o controle da tipografia (0 TP1-a). As 21 reprovações são de dependência
externa, e a atribuição por família muda o que elas significam:
| host que falha | quantos artefatos | quais | leitura |
|---|---|---|---|
assets.seed.eng.br |
13 | a família de e-mail (ea-*, en-*, et-*, seed-email-*) |
⚠ ISENÇÃO DECLARADA: e-mail não pode embutir ativo. Imagem remota é a norma do meio, e o cliente de e-mail bloqueia até o leitor liberar. Aqui o FAIL é esperado, e o host é da própria SEED |
fonts.googleapis.com |
7 | banco-cn, banco-componentes, banco-dados, banco-feedback, banco-navegacao, banco-superficies, banco-tokens |
este é o achado novo e real. Sete bancadas carregam a fonte da rede. Numa máquina sem Montserrat instalada e sem rede, elas caem para a genérica |
lh3.googleusercontent.com + drive.google.com + fonts.googleapis.com |
1 | seed-design-system.html |
o caso fundador: 46 recursos num só arquivo |
Pasta de prova render-audit/prova-tp1/ — referência 3 PASS · 3 FAIL · 0 [n/a], com
1 TP1-a · 2 TP1-b · 1 TP1-c e 3 achados de portabilidade · 1 de primeira escolha. Seis fixtures, uma
por cláusula e uma por caminho de achado. Nela, FAIL é o resultado desejado.
⚠⚠ CONTAMINAÇÃO DO AMBIENTE, DECLARADA. Para consertar a fidelidade dos recortes desta rodada, o contêiner recebeu
apt install fonts-montserrat. Montserrat passou a resolver como fonte de sistema, e é por isso que os 85 achados de portabilidade existem: artefatos que declaram Montserrat sem embuti-la aparecem como "resolvem" aqui e não resolveriam numa máquina limpa. A guarda imprime esse aviso em toda execução. Contaminação de ambiente que não é declarada é dado sintético plausível com outro nome.
75.5 ⚠⚠⚠ ESTA GUARDA ESTEVE ERRADA CINCO VEZES, E O NÚMERO DE PASSES É O ACHADO#
Fica registrado inteiro, porque a repetição é a lição:
| passe | o que ela media | quanto reprovou | por que estava errada |
|---|---|---|---|
| v1 | exigia que toda família nomeada resolvesse | 48 de 51 | font-family é pilha de alternativas por construção. SFMono-Regular e Menlo são fontes de macOS e não existem em Linux — isso não é defeito, é a pilha funcionando |
| v2 | passou a medir por pilha, mas ainda reprovava pilha sem família nomeada resolvida | 46 de 51 | pilha que termina em genérica tem fallback declarado e intencional: 'JetBrains Mono', ui-monospace, monospace diz "alguma monoespaçada serve" |
| v3 | corrigiu a genérica, mas lia as pilhas do CSSOM declarado | 22 de 51, com 3 TP1-a falsos | o CSSOM devolve var(--seed-font-sans) sem resolver, e a guarda tratava isso como "pilha que não resolve nada". Três bancadas reprovavam por defeito meu |
| v4 | passou a ler o computed style de cada elemento |
6 de 6 na pasta de prova | o computed de elemento que nenhuma regra do autor alcança devolve a fonte padrão da UA ("Times New Roman"), que não existe em Linux — e o padrão do navegador não é declaração do artefato |
| v5 | descobre o padrão da UA num iframe limpo e o exclui por igualdade exata | 3 de 6 na prova (a referência) e 21 de 51 no acervo | correta — e a prova de inércia confirmou: a matriz da pasta de prova ficou idêntica linha por linha |
A LIÇÃO, e ela vale para toda guarda nova desta casa: quando uma régua nova reprova EM BLOCO, a primeira hipótese não é "o acervo está ruim" — é "a régua está medindo outra coisa". Cinco vezes seguidas o erro foi o mesmo em forma diferente: medir algo adjacente ao que o contrato nomeia. E as cinco vezes foram pegas pela pasta de prova ou pela atribuição por família — nunca pelo placar verde.
75.6 As duas decisões de COR que esta seção NÃO fecha — elas esperam gate#
Registradas aqui porque a medição está feita e não deve ser refeita. Nada disto foi aplicado a nenhum artefato.
(i) O amarelo no cartão de post social — o pedido dele não era entregue por nenhuma opção#
Pedido verbatim: "opção B é melhor mesmo, mas o texto amarelo do tamanho do C" — isto é, manter o amarelo, em 18px. Duas descobertas mudaram a pergunta:
A onda decorativa passa por baixo da SEGUNDA linha do texto amarelo. Ela é
fill="#098475" opacity=".7". No cartão de hoje é invisível, porque o cartão também é #098475 —
mesma cor sobre mesma cor. Assim que o cartão escurece, a onda passa a clarear aquele pedaço.
Medido no pixel, linha por linha:
| opção | fundo do cartão | linha 1 | linha 2 (sobre a onda) | piso | o texto amarelo |
|---|---|---|---|---|---|
| HOJE | #098475 |
3,22 | 3,22 | 4,5 | reprova |
| (A) texto vira branco | #098475 |
4,60 | 4,60 | 4,5 | passa — perde o amarelo |
| (B) amarelo a 24px | #098475 |
3,22 | 3,22 | 3,0 | passa — o texto cresce |
(C) fundo #006C62 |
#006C62 |
4,43 | 3,52 | 4,5 | reprova |
(E) fundo #005048 |
#005048 |
6,56 | 3,92 | 4,5 | reprova só na linha 2 |
| (E++) só a onda escurece | #098475 |
3,22 | 6,94 | 4,5 | reprova só na linha 1 |
(E+) #005048 + onda #00352F a .7 |
#005048 |
6,56 | 8,54 | 4,5 | passa nas duas |
A linha #PROVEMOS EFICIÊNCIA já reprovava, e a régua não mostrava. Ela é branca com
opacity:.9. A régua lê a cor declarada (#fff) e informa 4,60; o pixel real é #e6f2f1 e
mede 4,01. Ou seja: (A) e (B) deixavam uma segunda reprovação no cartão, que a folha anterior
dava como limpo. Escurecer o cartão conserta essa linha de graça: 5,44 em #006C62 e 7,90 em
#005048.
RECOMENDAÇÃO ESCRITA — (E+): cartão
#005048(turquesa-800) e onda#00352F(turquesa-900) a 70%. O amarelo#FAD61Dnão muda de valor (é o acento oficial de marca), o tamanho fica 18px, zero hex novo, e tudo no cartão passa com margem: 6,56 · 8,54 · 7,90 · 9,37. E a onda fica mais visível — escurecer em vez de clarear é ganho de desenho. Alternativas descartadas, com número: (A) perde o amarelo e deixa o kicker em 4,01; (B) cresce o texto e deixa o kicker em 4,01; (C) para em 4,43/3,52; (E) para em 3,92 na segunda linha; (E++) para em 3,22 na primeira.
(ii) O dourado — a recomendação anterior CONTRARIAVA uma decisão já aprovada#
Ele escreveu: "escurecer o dourado está mudando a cor que realmente representa a empresa, ou mantem ou vc acha uma solução melhor".
ERRO REGISTRADO#
A recomendação (D) da folha v14.1 — escurecer
#F9B11Cpara#986900— contraria oseed-tokens.mdv1.5, de 2026-08-11, aprovado por gate visual dele, que diz verbatim: "Regra do dourado: permitido em área grande com rótulo direto; vetado como fill solitário sem rótulo (1.85 é insolúvel sem matar a cor da marca)." E a decisão de 2026-07-30: "amarelo#FAD61D= acento oficial de marca; dourado#F9B11C= cor de trabalho (warning, dataviz cat-2, detalhe fotográfico). Nunca os dois na mesma peça."Ele reconheceu de olho o que já estava escrito, e eu não conferi antes de recomendar. ⭐ Régua que sai daqui: antes de propor mudança de VALOR de cor de marca, leia a linha do canon sobre aquela cor — ela pode já ter decidido, com número. Alternativa descartada é alternativa que alguém já mediu; propor de novo o que foi vetado é desfazer trabalho aprovado.
A saída preserva o hex exato: o dourado não muda de valor, muda de PAPEL. Medido, com
#F9B11C intocado:
| o dourado como TINTA sobre… | razão | piso 4,5 | piso 3,0 (texto grande) |
|---|---|---|---|
| branco | 1,85 | ✗ | ✗ |
#FFF8E6 (o creme do próprio documento) |
1,75 | ✗ | ✗ |
verde de marca #098475 |
2,48 | ✗ | ✗ |
turquesa-700 #006C62 |
3,41 | ✗ | ✓ |
turquesa-800 #005048 |
5,06 | ✓ | ✓ |
turquesa-900 #00352F |
7,31 | ✓ | ✓ |
cinza-900 #242E34 |
7,48 | ✓ | ✓ |
como ÁREA, com rótulo #242E34 em cima |
7,48 | ✓ | ✓ |
Tamanho não salva o dourado: mesmo a 44px, com o piso caindo para 3,0, ele mede 1,85 sobre branco. Foi por isso que a folha anterior propôs escurecer — e por isso a proposta estava errada: a saída não é a cor, é a superfície.
Os cinco lugares onde o dourado pinta letra no seed-design-system.html, e a saída de cada um:
| lugar | o que é | hoje | saída |
|---|---|---|---|
| nome do EEny (38px, texto à mão) | peça de MARCA | 1,85 | (F) inverter a superfície do cartão → 7,48 · dourado intocado |
| herói "renova mundos." (44px) | peça de MARCA | 1,85 | (F) ou (G) → 7,48 |
.type-sample-h2 (28px) |
demonstração tipográfica | 1,85 | (G) o dourado vira área com rótulo escuro → 7,48 |
| badge e alerta de warning | UI de TRABALHO, não peça de marca | 1,75 | (W) os tokens que já existem → 9,05 |
.subtitle |
CSS morto — zero instância | — | nada a fazer (apagar exige confirmação dele) |
O caso do warning é diferente, e o canon já resolveu. Ali o dourado não representa a marca — sinaliza severidade. Os tokens existem e foram aprovados em 2026-08-09/11:
feedback-warning-text#5B3E00sobrefeedback-warning-bg#FFF4E4mede 9,05, enquantofeedback-warning-bordere-solidcontinuam#F9B11C. A cor de marca fica intacta na borda e no sólido; só a LETRA usa o degrau escuro da mesma rampa. Não é escurecer a cor da empresa — é usar o token de severidade que a casa já tinha, o mesmo critério que decidiu ogauge-range-warning.
75.7 Pendências que esta seção abre#
| # | Pendência | Por que fica, com número |
|---|---|---|
| RD-P1 | o seed-design-system.html depende de 46 recursos de rede; sete bancadas dependem do Google Fonts |
medido: 0 de 45 imagens e 0 de 2 famílias carregam sem rede. O conserto — embutir os ativos e as fontes — mexe em 45 pontos de um arquivo e em 7 bancadas, e merece rodada própria. ⚠ A família de e-mail está ISENTA e a isenção é declarada: e-mail não pode embutir ativo |
| CC-P11 | a contraste-composicao.mjs resolve um fundo por elemento e não vê texto que atravessa duas superfícies |
medido: ela deu 6,56 onde o pixel dá 3,92. Protótipo do conserto em 06-validacao/ferramentas/mede-fundo-por-linha.mjs, que mede por linha com Range.getClientRects() — a mesma técnica que a SH1 já usa para vazamento. Irmã da CC-P10 (gradiente) |
| CC-P12 | a régua lê a cor declarada e ignora opacity no elemento ou em ancestral |
medido: 4,60 declarado × 4,01 real no kicker deste cartão. Já era lição de método desde a nona parte; agora tem caso fundador e sigla |
| TP-P1 | a guarda-tipografia-viva.mjs não distingue recurso externo legítimo (e-mail) de indevido (bancada) — a atribuição por família foi feita à mão nesta rodada |
é a mesma família da peneira declarada da BT1: lista escrita à mão, que funciona e tem de sair impressa. O conserto é uma isenção por padrão de nome (`^(ea |
75.8 Peso ou estilo pedido SEM FACE — as três regras do gate FT-P2 (2026-09-15, veredito dele, MANIFESTO §226.1)#
A cláusula TP1-d desta guarda conta os elementos que pedem um peso ou estilo que a família carregada não tem. O censo de 2026-09-15 (scratchpad FT-P2, 53 de 53 HTML de telas, bancadas e e-mails) achou 260: 141 JetBrains Mono a 600, 24 <strong>/<b> em texto já 700 (o bolder pede 900), 76 itálicos, 10 Montserrat 800 residuais da SH-P9 e 9 Montserrat 300 na tela-documento. O que se vê em cada caso é a face vizinha, em silêncio: o negrito dentro de 700 não aparece, o Mono 600 rende 700, o 300 rende 400. Ele decidiu, verbatim: "V-FT2.1 strong: b · V-FT2.2 mono 600: c · V-FT2.3 itálico: b · V-FT2.4 light: b". As regras, na ordem:
| # | regra | forma no CSS | custo medido |
|---|---|---|---|
| TP1-d-1 | <strong>/<b> dentro de texto que já é 700 marca por COR, nunca por peso. A casa não carrega 800/900 (marca §4.3), então o bolder do navegador não tem face e o negrito é invisível. A ênfase é a tinta forte de marca, com o peso herdado. Onde o texto-pai é 600, o negrito 700 EXISTE e aparece: declara-se o 700 que se vê (0 px). |
strong, b { font-weight: inherit; color: var(--seed-text-brand-strong); } no escopo do título/rótulo 700 (.insight strong, .pagina h2 strong, .chip-cont b…); gerador que emite <strong> em título (gen-painel.py) segue a regra |
0 B; 501 px no #t-status e 789 px no #t-venc do painel, 262–646 px por h2 de bancada — só a tinta muda |
| TP1-d-2 | Rótulo em JetBrains Mono é Bold (700). O papel rótulo (--seed-txt-rotulo-weight: 600) é da Montserrat; a Mono não tem 600 e o navegador já subia para a 700. Declara-se o que se vê. O token continua 600. |
o font-weight: 700 entra na mesma regra que declara a família mono (ou na regra mono que herdava o 600) — uma por sítio, nunca 141 declarações; onde a regra de 600 era mais larga que o mono (tabela inteira, <dl> inteira), vai para o filho mono, para nenhum Montserrat 600 mudar |
0 B, 0 px em 17 de 17 arquivos (captura inteira antes × depois, ruído 0) |
| TP1-d-3 | Itálico não é carregado; o oblíquo sintético do navegador é o aceito. <em> continua (PN21e reserva o itálico para o sujeito do insight). |
nada muda no CSS | 0 B; trazer as três faces custaria +84.124 B no registry |
| TP1-d-4 | Corpo de documento em tela é Regular (400); o Light (300) fica para peça impressa (marca §4.1). | tela-documento: .doc, .doc p, .doc li { font-weight: 400 }; suite-documento DC-03 exige 400 |
0 B, 0 px (o 300 nunca foi carregado) |
Depois da aplicação o censo TP1-d é 79 em 53 de 53 HTML: os 76 itálicos aceitos (TP1-d-3) e 3 botões mono do shell-template.html (.controles .b-larg, fora do escopo do agente FT-P2 — pendência da sessão). Duas verdades a mais que a aplicação achou: (i) o bloco de tokens embutido nas nove bancadas com gerador é por LISTA (tokens_bloco.py) e --seed-text-brand-strong não estava nela — a regra nova em base-bancada.css caía em var() indefinido e a cor não pintava (medido: 0 px onde se esperava tinta); o nome entrou nos nove geradores. Toda regra nova em CSS compartilhado confere o token no bloco de cada consumidor. (ii) .kanban h3 do painel tem a mesma forma (mono 600 + b) e não entrou no censo porque a lente não está visível na carga — corrigido junto (achado da mesma forma se corrige em todos os lugares).