Ir ao conteúdo
SEED engenharia

Componentes

83. TELA A19 — AUTENTICAÇÃO

estávelseed-componentes.md v2.00 · §83seção 165 de 18483-tela-a19-autenticacao-entrar-recuperar-criar.md · MD5 6f4db173

Título completo no canon: TELA A19 — AUTENTICAÇÃO (entrar · recuperar · criar conta) · estável (2026-08-23) · fecha a CD-P5 · tela 05-html-de-referencia/telas/tela-autenticacao.html v0.5 (v0.4 = material, MA-P3; v0.5 = logo vertical, MR-P18) · instrumento 06-validacao/suites/suite-autenticacao.mjs (24 PASS · 0 FAIL · 0 [n/a] desde 2026-09-14: AU-12 reescrito, AU-16 e AU-17 novos; era 21 PASS)

Em uma frase: Autenticação vive FORA do shell (não há app antes de entrar): cartão centrado de 420 px, logo vertical oficial acima dele, senha pelo §66.

O que esta seção NÃO cobre: O que acontece depois do login — sessão, provedor, recuperação real — é produto, não design system. — se é disto que você precisa, não preencha em silêncio: gere o pedido de cobertura (https://ds.seed.eng.br/pedidos/).

Casca (SH17, §46.4, 2026-09-14): esta é uma das duas telas que vivem FORA do shell §46 no produto — não há app antes de entrar. Marca (MR-P18, MANIFESTO §218.2, tela v0.5): a identidade acima do cartão é a LOGO VERTICAL oficial completa, uma variante por tema (§5.1 da marca: digital com largura ≥ 120 px = logo completa; claro = principal, escuro = mono-negativo), nunca símbolo + nome escrito; as classes dos <style> dos dois SVGs embutidos são prefixadas por variante, porque <style> de SVG embutido é global na página (AU-16). Produto que usa o DS sem a marca SEED (LC-66, leva 50): no lugar da logo vai o nome do produto em texto, papel titulo-tela, tinta text-primary, como texto comum (<p>, nunca um segundo h1) — regra inteira em marca-seed.md §5.7; AU-12, AU-13 e AU-16 não se aplicam a esse produto (decisão delegada a ele, «pode fazer», 2026-10-31, exposta a veto).

O que é: a primeira tela da F7.6 (ordem aprovada no consolidado de 2026-08-22: A19 → A20 → A17 → A18 → A14 → A13). Promovida por gate visual do Rafael em 2026-08-23 com UMA correção, verbatim: "a tela de login deve ter o icone da seed no lugar do botao turquesa. fazendo essa correção, está aprovado" — aplicada antes da promoção (ver AU-13). A tela não inventa componente: compõe o §66 (credenciais CD1–CD16), o §2/§3.5 (form-field e norma de senha), o §1 (botão), o §1.13/1.13-b (live region) e o gabarito A19 da F7.1 (seed-composicao.md §3: um cartão centrado, coluna única, 420px máx, par sombra+anel; <600px vira largura total com calha mínima). Leitura de referência: 09-pesquisa/leitura-f76-bordas.md (2026-08-22) — ClickUp público (login/forgot/signup, MEDIDO) + shadcn login-01 (MEDIDO, a stack do SIGA). Onde a norma decide, a spec mede contra a norma (precedente do §66.0); a leitura serviu à COMPOSIÇÃO.

83.1 Contratos (a suíte mede todos por comportamento, nunca por regex)#

  • AU-01 — <form> REAL por vista (4: entrar · recuperar · código · criar) e nenhum botão de submit nasce desabilitado (§2.6; o ClickUp nasce desabilitado a 1,4:1 de contraste e reprova nesta régua).
  • AU-02 — e-mail: type=email + autocomplete=username + inputmode=email + autocapitalize=none + spellcheck=false (CD2/§2.6) — nos TRÊS formulários que pedem e-mail.
  • AU-03 — senha de entrar = current-password; senha de criar = new-password; nenhuma senha tem maxlength (CD4). Código de verificação = one-time-code + inputmode=numeric + pattern/maxlength legítimos (CD11 — código tem forma fechada, o oposto da senha).
  • AU-04 — revelar senha é button[type=button] com aria-pressed/aria-controls (CD6), a visibilidade é ANUNCIADA na live region (CD7), o SUBMIT devolve a type=password (CD8) e a senha NASCE oculta (CD9).
  • AU-05 — todo input tem <label for> VISÍVEL (§2) — placeholder nunca é rótulo (defeito do vizinho, lido e rejeitado).
  • AU-06 — erro de CREDENCIAL: o container role=alert existe no DOM vazio e oculto ANTES do conteúdo (1.13-b) e a mensagem fala do PAR ("E-mail ou senha incorretos"), nunca de qual metade errou (CD13). Erro de FORMATO diz e aponta o campo (blur, B4; aria-invalid sempre com valor explícito, §2.9).
  • AU-07 — código em UM campo, nunca N caixinhas (CD10).
  • AU-08 — o prazo do código é DECLARADO em texto (mono para o número) e o reenvio existe como ação terciária (CD12).
  • AU-09 — criar conta sem "confirme a senha" (CD5/SC 3.3.7); força da senha em texto + forma, nunca bloqueia o envio (CD14).
  • AU-39..AU-42 (2026-10-23, folha 9 M4 = "a" e M4b = "a", AU-P5, PR-P182; tela v0.9) — CPF obrigatório em TODA conta: o "Criar conta" (entre e-mail e senha) e o convite do cliente (entre nome e senha) passam a pedir o CPF, com a mesma máscara do canon 2.7, os mesmos dígitos verificadores, as mesmas mensagens e a finalidade escrita ao lado ("Usamos o CPF para garantir um cadastro único." — texto da sessão, exposto a veto; o do parceiro segue com "e para o pagamento"); o "Criar conta" ganha o resumo role="alert" ("Corrija: CPF."). A senha do "Criar conta" sobe de 8 para 12 caracteres, como o convite, o parceiro e o servidor: a regra escrita ("Use 12+ caracteres…") e a força (abaixo de 12 = "Fraca"; 12 e 13 = "Razoável"; 14 ou mais = "Forte"; os 14 já eram o limite do "Forte"). A FORÇA continua só informando e nunca bloqueia (CD14); o piso de 12 caracteres é regra de FORMATO (CD4, CD13) e, desde a AU-43 (AU-P7, leva 46), a tela recusa o envio de senha com menos de 12 caracteres ou vazia, como o convite e o parceiro já faziam; o servidor segue recusando de verdade (senha vazada, política). CPF já cadastrado (AU-P4, M3b = "a"): a mensagem "Não foi possível concluir o cadastro com este CPF. Se você já tem conta, entre ou recupere a senha." confirma que existe conta (sem dizer de quem) — já era o texto da tela, provado pela AU-31.
  • AU-43 (2026-10-25, AU-P7, leva 46; tela v0.10; refeita na leva 47 — AU-P8..P11, tela v0.11; estendida na leva 48 — AU-P12..P14, tela v0.12) — o "Criar conta" recusa senha curta. Com menos de 12 caracteres (ou vazia), o envio do "Criar conta" é recusado: o campo da senha ganha aria-invalid="true", a borda de erro na cor do texto de erro de campo (--seed-field-error-text, 2 px, 7,18:1 no claro e 7,56:1 no escuro medidos), a mensagem "Erro: a senha precisa ter pelo menos 12 caracteres." (a MESMA do convite e do parceiro) e o resumo role="alert" diz "Não foi possível criar a conta. Corrija: senha. A senha precisa ter pelo menos 12 caracteres." (ou "Corrija: CPF, senha." quando os dois falham; o resumo é refeito a cada correção de campo, some quando não resta item e, no envio recusado, recebe o foco — §2.10 item 2). O campo aponta para a mensagem por aria-describedby SÓ enquanto o erro existe (o erro entra e sai do atributo junto com o hidden): sem isso o leitor de tela diria um erro falso ao focar o campo (achado médio da revisão independente, medido na árvore de acessibilidade do Chromium). A senha valida no blur quando há 1 ou mais caracteres (B4) e no envio; sair para o botão de revelar não conta como saída do campo, e ir ao botão de envio POR PONTEIRO (mouse, toque, caneta) também não — o envio valida e o erro de campo (24 px) não pode empurrar o botão entre o apertar e o soltar (medido: o clique a 4, 12 ou 22 px do topo do botão de 44 px se perdia); pelo teclado, Tab até o envio acusa o erro. Depois do primeiro erro é revalidado a cada tecla até chegar a 12; apagar de novo não o reacende sozinho. (A frase da leva 46, "no envio, não no blur", era texto da sessão e contradizia o B4; foi refeita, exposta a veto.) O envio nunca nasce desabilitado (§2.6) e a força segue informando (CD14). Com o envio recusado a tela NÃO anuncia "Envio simulado". Guardas: suite-autenticacao.mjs AU-43a..AU-43f e AU-44a..AU-50h (121 PASS no total na tela v0.12, eram 88 na v0.11; medidos em navegador e em jsdom) e a cobaia de navegador, 28 de 28 nos dois temas. Divergência com o canon anterior, exposta a veto: a AU-39..42 dizia que a tela não impede enviar senha curta; foi texto da sessão (não palavra dele), apoiado no CD14. A mensagem e o resumo também são da sessão, não do canon de microcopy. O convite e o parceiro seguem o mesmo padrão desde a v0.11 (AU-P10): o erro de senha só entra no aria-describedby enquanto visível, e o convite recusado não anuncia "Envio simulado" (AU-P8); os outros 8 campos das telas tinham o mesmo vício (AU-P12, fechada na leva 48: ver abaixo). Leva 48 (AU-P12, AU-P13, AU-P14; tela v0.12): (1) O aria-describedby de um campo cita o elemento do erro apenas enquanto o erro está visível, e o cita ANTES da ajuda (§2.9; veredito dele, folha 15, Q4 = a); um erro oculto nunca entra na descrição. Sem ajuda e sem erro visível, o atributo não existe (medido nos 9 campos, en-email incluído: 9 de 9 FAIL antes, 9 de 9 PASS depois). (2) Em formulário com três ou mais campos, o envio recusado move o foco ao resumo (role="alert" com tabindex="-1"); o resumo é refeito a cada correção e some, esvaziado, quando a lista acaba (§2.10 item 2). O alerta de outra natureza que ocupa o mesmo container (senha vazada, CPF já cadastrado) não é refeito. (3) Sair de um campo para o botão de envio por ponteiro (mouse, toque, caneta) não valida no blur: o erro de campo (24 px) empurraria o botão entre o mousedown e o mouseup e o clique se perderia. Pelo teclado o blur acusa, como manda o B4. A exceção vale para qualquer campo que valida no blur nos três formulários, não só a senha do "Criar conta" (a sonda mediu 9 de 9 cliques perdidos também com o CPF e com o nome; decisão da sessão, exposta a veto). Prova: suíte 121 PASS · 0 FAIL, 33 casos novos (26 FAIL contra a tela v0.11 antes do conserto), 16 de 16 mutações reprovadas. Aberto (AU-P15): a vista "Entrar" tem o mesmo vício do clique perdido e não foi tocada; o re-anúncio do resumo por leitor de tela, o Safari, o iOS e o aparelho de toque real: NÃO MEDI. (A AU-P15 fechou na leva 49, tela v0.13: ver o bloco v1.99 do cabeçalho.) Leva 50 (AU-P16 a; tela v0.14): na vista Entrar, quando o e-mail acusa erro de formato, o envio anuncia na região viva o texto do erro do próprio campo em vez de «Envio simulado», move o foco ao campo de e-mail e NÃO recusa o envio: o botão segue habilitado e o e-mail corrigido e reenviado volta a dizer «Envio simulado» (o gabarito não sabe de credencial, CD13). Veredito dele, folha 17, Q5 = a, 2026-10-30 23:28 UTC (MANIFESTO §326.8; a opção a da folha: «anunciar o erro em vez de «Envio simulado» quando o campo acusa, mover o foco ao campo, sem recusar o envio»). O blur do e-mail pelo teclado também anuncia o erro, e o gesto do ponteiro solto fora do botão (AU-P15) refaz a mesma validação e anuncia. Uma vez por gesto (decisão da sessão, exposta a veto): o erro anunciado no blur não se repete no envio seguinte, até o foco voltar ao campo (o foco que vai ao campo lê o erro pelo aria-describedby). Prova: suite-autenticacao.mjs 161 PASS · 0 FAIL · 2 [n/a] (142 antigos + 19 novos, AU-57a..n e AU-58a..e; 14 dos 19 reprovavam na tela v0.13), 8 de 8 mutantes reprovados; AU-51a e AU-51c passam a aceitar como sinal de envio entregue o evento submit único com «Envio simulado» OU o erro do campo (decisão da sessão, exposta a veto). NÃO MEDI: leitor de tela real (os casos medem a escrita na região viva, não a fala), Safari e Firefox.
  • AU-10 — lang=pt-BR, um <main>, um h1 por vista (o ClickUp tem ZERO h1/main na tela de login), uma vista visível por vez, e a troca de vista move o foco ao h1 da vista nova.
  • AU-11 — live region única role=status aria-atomic, visualmente oculta e separada do nó visível (§1.13).
  • AU-12 — o símbolo da marca é o ASSET OFICIAL, byte-idêntico: os paths de 03-assets/simbolos/simbolo-principal.svg (tema claro) e simbolo-mono-negativo.svg (tema escuro — tabela fundo×variante do marca-seed.md §5.1) foram INJETADOS POR SCRIPT na tela, nunca redigitados; a suíte confere o path âncora contra o arquivo do asset.
  • AU-13 (veredito do gate) — a identidade acima do cartão é o símbolo oficial + "SEED engenharia" em texto. A sigla geométrica genérica das telas internas NÃO serve à porta do produto.
  • AU-14 — Caps Lock ligado no campo de senha gera AVISO visível (warning, nunca danger) e anunciado, que morre no blur (CD15).

83.2 Decisões de composição (com a leitura que as sustenta)#

Cartão, não canvas aberto (gabarito F7.1; shadcn confirma; o CU diverge) · "Esqueceu a senha?" na LINHA do rótulo da senha, à direita (shadcn) · SSO ("Continuar com o Google") DEPOIS do formulário e do divisor "ou" — o método primário da casa é o e-mail corporativo · botão de recuperação nomeia o EFEITO ("Enviar link de recuperação") e o de criação nomeia o MÉTODO ("Criar conta com e-mail") — dispositivos lidos no CU e adotados · título da recuperação é PERGUNTA ("Esqueceu a senha?") · confirmação de envio NEUTRA ("Se o e-mail existir na conta…") — não revela existência de conta · termos como texto de continuação (redação final = produto/jurídico, LGPD) · v0.2 sem faixa de marca: a âncora da tela é o botão primário turquesa (PN21-05: UMA âncora por página); o CP19 (faixa) segue PERMITIDO pelo gabarito como variante, se um gate futuro a pedir.

83.3 Fronteiras (produto/Supabase — nada disto é do DS)#

Sessão, redirecionamento, rate-limit, política de senha (§3.5/NIST), "lembrar-me", MFA/2FA de produto, seleção de workspace multi-empresa (SI17-e), redação legal dos termos e os E-MAILS do fluxo (EM15: o template canônico em HTML puro é exatamente o que o Supabase Auth aceita — quando a decisão vier, é colar). O deep-link #vista=…&tema=…&estado=… da tela é INSTRUMENTO de avaliação (headless/suíte), não spec — em produto, vista é rota.

83.4 O que a produção pegou (instrumento e método)#

  1. Container query não estiliza o próprio container — a primeira versão punha container-type no .palco e mirava .palco dentro do @container: nunca disparava. Pego por MEDIÇÃO em navegador real a 390px (padding seguia 24px); o container subiu para o body. Medido depois: calha 12px, cartão 366px, scrollWidth = viewport.
  2. O screenshot do Chrome CLI a 390px inventou um overflow (link "vazando" da tela) que o navegador real desmente — REINCIDÊNCIA da armadilha catalogada no marco v1.9: render de prova é navegador real/puppeteer, nunca o CLI --screenshot.
  3. Ambiente de suíte nesta máquina: o G: (Drive File Stream) rejeita junction e node_modules dentro do stream é inviável; o jsdom vive em %TEMP%\claude\jsdom-env e a suíte o resolve por caminho (env JSDOM_DIR). ⚠ As suítes antigas (import 'jsdom' puro) seguem sem rodar aqui — pendência de ambiente AU-P1.
  4. Defeito pego no pré-olhar: link "Esqueceu a senha?" herdava o AZUL default do UA no tema escuro (seletor de cor não cobria .linha-rotulo a) — consertado e reconferido.

83.5 Pendências que a seção deixa#

  • AU-P1 — ambiente: as ~60 suítes antigas não rodam nesta máquina (jsdom fora do repo; ver 83.4-3). Decidir o padrão da casa: env JSDOM_DIR em todas, ou ambiente node dedicado fora do stream.
  • AU-P2 — a variante COM faixa de marca (CP19) não foi desenhada; gatilho: gate futuro pedir a versão de marketing da porta.
  • AU-P3 — o fluxo multi-empresa pós-login (seleção de workspace, SI17-e) é tela de PRODUTO; se o SIGA pedir, nasce como extensão desta seção com leitura própria.

TelaSEED · Gabarito A19 — Autenticação (v0.14 · estável 2026-08-23 · HV1 retroativo)abrir em página própria ↗
Esc