Ir ao conteúdo
SEED engenharia

Componentes

75. TP1 — A TIPOGRAFIA E OS RECURSOS DO ARTEFATO REALMENTE CARREGAM

estávelseed-componentes.md v2.00 · §75seção 154 de 18475-tp1-a-tipografia-e-os-recursos-do-artefato.md · MD5 aa54844d

Tí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-ui e afins — o navegador sempre resolve. @font-face embutido = a fonte viaja dentro do arquivo (ou vem de um woff2 declarado), 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.html depende de 47 recursos de rede: 45 imagens em lh3.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 com ERR_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 (CSSStyleRule também tem cssRules) 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 #FAD61D nã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 #F9B11C para #986900 — contraria o seed-tokens.md v1.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 #5B3E00 sobre feedback-warning-bg #FFF4E4 mede 9,05, enquanto feedback-warning-border e -solid continuam #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 o gauge-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).


Esc