Tela de login com o Claude: como pedir um formulário de acesso que já sai usável

Montar uma tela de login com o Claude dá certo quando você para de descrever a tela e passa a descrever os estados dela. O caso feliz sai sozinho; o que some é erro, carregando, senha visível, colar do gerenciador e recuperação. A receita: contexto e estética primeiro, campos com autocomplete="username" e autocomplete="current-password" (critério WCAG 1.3.5, nível AA), mensagem de erro genérica no padrão do OWASP, botão bloqueado contra duplo envio, opção de exibir a senha (NIST SP 800-63B) e uma revisão final em que o próprio modelo lista o que deixou de fora
Fala aí, beleza? Tela de login é o pedido mais inocente que existe pra uma IA, e é exatamente onde a coisa quebra
Você digita "faz uma tela de login", vem um card centralizado, dois campos, um botão bonitinho e um fundo caprichado
Aí você clica no botão sem preencher nada e não acontece nada
Erra a senha e não aparece mensagem nenhuma
Não tem olhinho pra revelar a senha, não tem "esqueci minha senha", não tem estado de carregando
O modelo não é burro, o pedido é que veio pela metade: você descreveu uma tela parada, e login não é tela parada, é uma máquina de estados
Por isso a tela de login com o Claude é o melhor estudo de caso que existe pra aprender a pedir interface: ela concentra, num espaço minúsculo, tudo que a IA costuma cortar quando você só pede "o formulário"
Bora montar o pedido camada por camada? 🙂
O que você precisa antes de pedir a tela
Primeiro: onde essa interface aparece?
No Claude.ai, a interface gerada renderiza nos Artifacts, aquela janela lateral que abre do lado da conversa e mostra o resultado rodando em vez de só o bloco de código
E aqui vem uma boa notícia: Artifacts é suportado em Free, Pro, Max, Team e Enterprise, ou seja, tu não precisa de plano topzera pra fazer o exercício deste post
Só tem um detalhe que trava muita gente logo na largada: pra criar e usar artifacts é preciso ter execução de código e criação de arquivos habilitadas nas configurações
O caminho é Settings > Capabilities (Free, Pro, Max) ou Organization settings > Capabilities (Team, Enterprise)
Tome cuidado! esse caminho é do Claude.ai, não do Claude Code
Misturar menu de um produto com o outro é um clássico, e se tu tá tentando entender o que cada plano libera em cada produto da casa, vale a mesma lógica que usei pra destrinchar o modelo de acesso do Claude Cowork
Domine o Claude Code do básico ao avançado
Você vai aprender a criar sistemas completos com Claude Code, sem precisar ser programador. Inscreva-se para ter acesso a um desconto de lançamento e bônus especiais!
E no Claude Code?
Se teu ambiente é o terminal, existe um plugin oficial da Anthropic pra esse tipo de trabalho: o plugin frontend-design, voltado a gerar interfaces com direção estética definida ANTES do código
O código dele vive no repositório anthropics/claude-code, dentro de plugins/frontend-design/skills/frontend-design/SKILL.md
O gerenciador de plugins do Claude Code abre com o comando /plugin, que mostra a interface em abas, e os plugins de marketplace aparecem na aba Discover
A parte massa: ele ativa sozinho quando você pede a construção de uma interface, sem comando dedicado
Os exemplos citados pela própria página do plugin são dashboard, landing page e painel de configurações com dark mode
Ou seja: dá pra levar a mesma ideia de "estética primeiro" pro terminal, e o passo a passo daqui pra baixo continua valendo igualzinho
Passo a passo: montando o pedido da tela de login
A regra do jogo é uma só: cada passo adiciona UMA camada ao prompt
Você não vai escrever um prompt gigante de uma vez, vai empilhar
E eu deixo o trecho pronto pra colar em cada etapa, beleza?
1. Descreva contexto e estética antes de falar em código
Modelo bom de interface trabalha melhor quando sabe pra QUEM é a tela, não só o que a tela tem
Preciso de uma tela de login para um painel interno de uma clínica
veterinária. Público: recepcionistas usando notebook simples, luz
forte no balcão. Estética: fundo sólido claro, card centralizado,
contraste alto, nada de degradê e nada de vidro fosco. Antes de
escrever qualquer código, me devolva em 5 linhas a direção visual
que você vai seguir.
Repara no final: você pede a direção estética em texto ANTES do código
Isso te dá um ponto de correção barato, porque discordar de 5 linhas é muito mais rápido do que discordar de uma tela pronta
O erro comum deste passo: pedir "design moderno e bonito"
Isso não é briefing, é torcida
2. Liste os campos com os atributos de acessibilidade no pedido
Aqui é onde o pedido genérico entrega HTML genérico
A WCAG tem um critério, o 1.3.5 Identify Input Purpose, nível AA, que exige que o propósito dos campos de formulário seja programaticamente determinável
E a técnica oficial pra login é bem concreta: autocomplete="username" no campo de usuário e autocomplete="current-password" no campo de senha
Então pede isso com nome e sobrenome:
Campos: e-mail (input type="email", id="email", name="email",
autocomplete="username") e senha (input type="password",
id="senha", name="senha", autocomplete="current-password").
Cada campo com <label for="..."> visível, nada de placeholder
no lugar de label. Não use autocomplete="off".
O resultado esperado é este esqueleto:
<label for="email">E-mail</label>
<input type="email" id="email" name="email" autocomplete="username">
<label for="senha">Senha</label>
<input type="password" id="senha" name="senha" autocomplete="current-password">
"Mas e se eu quiser desligar o preenchimento automático?"
Deixa quieto: o atributo autocomplete="off" costuma ser desconsiderado pelos navegadores em campos de login e senha, justamente pra não quebrar gerenciador de senha
Ou seja, tu escreve, o navegador ignora, e tu fica com a falsa sensação de ter controlado alguma coisa
O erro comum deste passo: aceitar campo sem label, só com placeholder
Fica lindo no print e some assim que o usuário começa a digitar
3. Peça a mensagem de erro genérica, e diga o que NÃO escrever
Esse é o estado que mais some no caso feliz
E quando aparece, costuma aparecer errado: "usuário não encontrado", que é um presente pra quem tá testando lista de e-mails
O OWASP recomenda mensagem genérica no login, pra não revelar se o usuário existe
A resposta apontada como correta é esta: Login failed; Invalid user ID or password.
E as respostas apontadas como incorretas são justamente as espertinhas: Login failed, invalid user ID, Login failed; account disabled e Login for User foo: invalid password
Estado de erro de credencial: uma única mensagem genérica,
equivalente a "Login failed; Invalid user ID or password.",
exibida acima do formulário e associada aos campos.
Nunca diferencie "usuário não existe" de "senha errada",
nunca diga que a conta está desativada.
O erro não pode apagar o que o usuário já digitou no e-mail.
O erro comum deste passo: pedir só "mostre erro se falhar"
O modelo vai inventar o texto, e o texto que ele inventa quase sempre é o específico demais
4. Peça carregando e trave o botão contra duplo envio
Internet ruim + botão que não muda de estado = usuário clicando cinco vezes
Estado de carregando: ao enviar, o botão fica desabilitado,
troca o texto por "Entrando..." e exibe um indicador visual.
Os campos ficam somente leitura enquanto isso.
Bloqueie envios repetidos: um clique enquanto está carregando
não dispara nada. Ao voltar erro, o botão volta ao estado normal.
Repara no último pedido, que é o que quase ninguém escreve: voltar do carregando
Tela que entra em "Entrando…" e nunca sai é um bug clássico de interface gerada às pressas
O erro comum deste passo: pedir o spinner e esquecer o caminho de volta
5. Peça exibir senha e garanta que dá pra colar
Aqui tem duas referências que vale citar dentro do próprio prompt, porque elas mudam o comportamento do modelo
O NIST, no SP 800-63B, diz que verificadores SHOULD permitir a funcionalidade de colar, e SHOULD oferecer a opção de exibir o segredo em vez de pontos e asteriscos até que ele seja enviado
A WCAG 2.2 trouxe o critério 3.3.8 Accessible Authentication (Minimum), nível AA, e ele é atendido quando a tela não bloqueia colar e não impede o preenchimento automático
Botão de exibir/ocultar senha dentro do campo, alternando entre
type="password" e type="text", com rótulo acessível que muda
junto ("Mostrar senha" / "Ocultar senha").
Não bloqueie colar em nenhum campo. Não bloqueie preenchimento
automático do gerenciador de senhas. Nada de onpaste return false.
E o que NÃO fazer tem nome e número: a W3C registra a falha F109, que é exigir a entrada caractere a caractere em campos separados
Sabe aquele visual de código dividido em quatro quadradinhos, um dígito em cada? É bonito e é falha documentada dos critérios 3.3.8 e 3.3.9, porque impede colar em uma ação e vira teste de função cognitiva
Se pedir isso pro Claude, ele faz, e faz bonito
Aí a culpa é sua e não dele 😛
O erro comum deste passo: pedir "campo de código estilizado" sem dizer que precisa aceitar colar de uma vez
6. Peça recuperação de senha e o estado de sucesso
O fluxo de "esqueci minha senha" some do artifact com uma facilidade impressionante
E o estado de sucesso some ainda mais, porque no caso feliz a mente do modelo já foi embora pra próxima tela
Inclua link "Esqueci minha senha" próximo ao campo de senha,
alcançável por teclado e com foco visível.
Estado de sucesso: mensagem curta de confirmação e a interface
travada para novo envio enquanto redireciona.
Mostre também o estado de campo vazio: qual mensagem aparece
se o usuário enviar sem preencher, e onde ela aparece.
O erro comum deste passo: tratar sucesso como "não fazer nada"
Se a tela não dá sinal de que deu certo, o usuário assume que deu errado
7. Mande o modelo revisar os próprios estados
Esse é o passo que eu mais gosto, porque ele é preguiçoso e funciona
Em vez de você caçar o que faltou, você obriga o modelo a listar
Antes de me entregar, liste em tabela todos os estados desta tela
(inicial, campo vazio, erro de credencial, carregando, sucesso,
senha visível, foco por teclado) e marque quais estão implementados
no código que você acabou de escrever e quais não estão.
Se algum não estiver, implemente e me diga o que mudou.
A lista que volta é o teu checklist de teste
O erro comum deste passo: aceitar a resposta "tudo implementado" sem abrir a tela e testar
Pede a lista, depois testa na mão o que a lista promete
O que aprendi montando essa tela na mão (e por que isso melhora o pedido)
Eu já fiz esse mesmo projeto do jeito antigo: tela de login do zero, só HTML e CSS, sem validação e sem back-end nessa etapa (isso ficou pra um momento futuro)
E olha, foi montando na mão que eu ganhei o vocabulário que hoje eu uso no prompt
Porque o pedido vago nasce de não saber nomear as decisões
Deixa eu ligar cada coisa que apareceu na construção manual com uma frase concreta pra colar no pedido:
- Testar o CSS antes do HTML. No vídeo eu mudo uma cor só pra confirmar que o arquivo de estilo tá realmente linkado, porque num projeto maior um caminho errado no link só dá dor de cabeça muito tempo depois. No prompt isso vira: "me entregue os arquivos separados e me diga como confirmar que o CSS está carregando"
- Estrutura declarada. Eu montei um container que engloba tudo, um h1 de título, o formulário com os campos, um bloco separado pras redes sociais e outro pro link de registro. Separei redes sociais e registro em divs próprias justamente pra controlar o espaçamento entre eles e o formulário. No prompt: "descreva a árvore de blocos antes do código"
- Label com for apontando pro id. Eu trato o label como a etiqueta que identifica o campo, e isso é exatamente o que o passo 2 aqui em cima pede
- Type email como PRIMEIRA camada. Eu uso o input de type email como uma validação inicial, e falo na boa que não é validação forte: a checagem de verdade depende do servidor. No prompt: "deixe claro no comentário do código o que é validação de navegador e o que precisa do servidor"
- O atributo name existe por um motivo. Coloquei name em cada input porque é por ele que o valor do campo é resgatado no back-end. Prompt: "todo input com name definido"
- Senha mascarada é nativo. O type de senha já transforma o texto nas bolinhas, sem gambiarra de JavaScript
- Texto do botão pelo value. No input de submit, o texto do botão veio pelo atributo value, e não escrito dentro do elemento
- Reset antes de qualquer estilo. Comecei zerando margem e padding, aplicando box-sizing border-box e padronizando fonte e cor de todos os elementos. E mostro na prática: sem o box-sizing border-box, a largura do input não bate com a dos outros elementos, e a regra de reset já resolve isso. Prompt: "comece o CSS por um reset com box-sizing border-box"
- Imagem de fundo grande. Ao aplicar a imagem por url relativa ela ficou descentralizada de tão grande, e o background-size cover resolveu. Dá pra reposicionar no eixo Y com background-position, e eu mantive um enquadramento diferente do projeto final por gosto mesmo
- Outline none. Removi a borda azul que aparece no input em foco por achar feia. Hoje eu peço diferente: "se remover o outline padrão, entregue um indicador de foco visível no lugar", porque quem navega por teclado depende disso
- rem em vez de px. Defini tamanhos de fonte em rem, condicionados à fonte do elemento raiz, pra tela se adaptar a telas menores como as de celular. Prompt: "tipografia em rem, não em pixel"
- Ícones por CDN. Puxei os ícones de redes sociais por uma fonte de ícones via CDN, e a dica é conferir se o ícone apareceu antes de seguir. Se não apareceu, o caminho é revisar o link do CDN. E se o link tá certo e mesmo assim nada: confere a grafia exata da classe copiada, porque o nome da classe do ícone varia
Perceba o padrão: nenhuma dessas frases é "prompt mágico"
É só o nome certo da decisão certa, e você só sabe o nome porque já tomou a decisão na mão uma vez
Quer ver a construção manual que serve de referência pro pedido? Tá logo abaixo
É um mini-projeto curto, feito pra praticar HTML e CSS do zero, que entrega uma tela de login elegante e reaproveitável em qualquer projeto: bastaria trocar a imagem de fundo e as cores pra encaixar em outro lugar
Validações reais e back-end ficam pra etapa posterior
Adaptando o mesmo pedido para outras telas de acesso
A parte boa é que a lista de estados é transferível
Você montou uma vez, reusa em todas as telas do fluxo de acesso, mudando só o miolo
| Tela | O que muda nos campos | Mensagem crítica | Estado de sucesso |
|---|---|---|---|
| Login | e-mail + senha, com autocomplete="current-password" |
erro genérico, sem dizer se o usuário existe | entrou, botão travado enquanto redireciona |
| Cadastro | mais campos, senha nova em vez de senha atual | erro por campo, dizendo o que corrigir | conta criada e próximo passo explícito |
| Recuperação de senha | só o e-mail | resposta igual pra e-mail existente ou não | "se existir conta, o link foi enviado" |
| Verificação de código | um campo único de código | código inválido ou expirado, separados | verificado, com destino claro |
| Painel de configurações | campos variados, muitos toggles | o que foi salvo e o que não foi | salvo, com confirmação visível |
Repara na diferença de filosofia entre login e cadastro
No login, a mensagem tem que ser genérica de propósito, pra não entregar quem tem conta
No cadastro, o erro precisa ser específico, senão o usuário fica adivinhando qual regra de senha ele quebrou
Na recuperação, mesma lógica do login: a resposta é a mesma pra e-mail cadastrado ou não
E na verificação de código, lembra da falha F109: campo único que aceita colar de uma vez, nunca quatro quadradinhos de um caractere cada
Já no painel de configurações, o estado que some é outro: sair da tela com alteração não salva
É o mesmo raciocínio de quando eu mostrei como pedir uma confirmação de saída, só que aplicado ao formulário inteiro
Conclusão
O ganho aqui não vem de escrever prompt mais longo
Vem de trocar a descrição da TELA pela descrição dos ESTADOS dela
Recapitulando o que empilhamos: contexto e estética antes do código, campos com autocomplete="username" e autocomplete="current-password" (critério WCAG 1.3.5, nível AA), erro genérico no padrão do OWASP, carregando com caminho de volta e botão travado, exibir senha e liberar colar (NIST SP 800-63B e o critério 3.3.8 da WCAG 2.2, nível AA), recuperação e sucesso, e a revisão em que o próprio modelo lista o que faltou
Próximo passo? Transforma essa lista num checklist de estados que tu cola em todo pedido de interface, não só na tela de login com o Claude
E testa o resultado do jeito chato: cola uma senha direto do gerenciador e força um erro de credencial de propósito
Se a senha colou e a mensagem que apareceu foi a genérica, tu pediu direito 😀
até o próximo post!
Perguntas frequentes
Preciso estar no plano pago do Claude pra testar a tela de login nos Artifacts?
Não. Artifacts está disponível em todos os planos: Free, Pro, Max, Team e Enterprise. O que costuma travar é outra coisa: em Settings > Capabilities (Free, Pro, Max) ou Organization settings > Capabilities (Team, Enterprise) você precisa habilitar execução de código e criação de arquivos antes de gerar o artifact.
Posso pedir pro Claude bloquear colar no campo de senha da tela de login?
Não peça, e se o Claude sugerir isso sozinho, recuse. A WCAG 2.2 tem o critério 3.3.8 Accessible Authentication (Minimum), nível AA, que só é atendido quando a tela não bloqueia colar e permite gerenciador de senhas. O NIST, no SP 800-63B, segue a mesma linha: recomenda permitir colar e até oferecer a opção de exibir a senha digitada.
Por que a tela de login que o Claude gera vem sem mensagem de erro e sem estado de carregando?
Porque o pedido descreveu uma tela parada, e login é uma máquina de estados. Se você não listar erro de credencial, carregando, sucesso e campo vazio, o modelo entrega só o caso feliz. A saída é empilhar cada estado no prompt e, no fim, mandar o próprio Claude listar em tabela quais estados ele implementou e quais não.
Que autocomplete eu peço pros campos de e-mail e senha da tela de login?
autocomplete="username" no campo de usuário e autocomplete="current-password" no campo de senha. É a técnica ligada ao critério 1.3.5 Identify Input Purpose da WCAG, nível AA, que exige que o propósito do campo seja programaticamente determinável.
Vale a pena colocar autocomplete="off" pra impedir preenchimento automático na tela de login?
Na prática, não resolve muito. Os navegadores costumam ignorar autocomplete="off" justamente em campos de login e senha, pra não quebrar o gerenciador de senhas do usuário. Pedir isso no prompt só te dá a falsa sensação de ter controlado esse comportamento.
Qual mensagem de erro eu devo pedir pro Claude escrever quando o login falha?
Peça uma mensagem genérica, que não revele se o e-mail existe ou não. O OWASP aponta como correta a frase "Login failed; Invalid user ID or password." e cita como erradas variações que entregam detalhe demais, tipo avisar só "invalid user ID" ou informar que a conta está desativada.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
As diferenças de var, let e const
Como fazer redirecionamento com PHP
Neste artigo você vai aprender a como fazer redirecionamento com PHP, utilizaremos abordagens fáceis de entender e de aplicar Fala programador(a), beleza? Bora aprender mais […]
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação A popularidade da automação de processos com o n8n está em alta, principalmente […]
