Skip to content

feat(home): deixa o login explicitamente opcional na home (#17) - #85

Merged
caioross merged 1 commit into
mainfrom
auto/issue-17-login-optional
Jul 26, 2026
Merged

feat(home): deixa o login explicitamente opcional na home (#17)#85
caioross merged 1 commit into
mainfrom
auto/issue-17-login-optional

Conversation

@caioross

@caioross caioross commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Contexto

#17: o hero promete "Sem cadastro, sem firula" e o header exibia "entrar com Google" sem nenhuma pista de que era opcional. A persona O Iniciante (D#14) travou exatamente aí — "fiquei na dúvida se eu precisava logar pra jogar".

Confirmei no código que não precisa: o login só pré-preenche o nick (HomeView.tsx:76useAuth.ts:21,30). É puro ruído de comunicação, não de fluxo.

O que mudou e por quê

Dois toques pequenos, um para cada viewport:

  1. Header (HomeView.tsx)title + aria-label no botão explicitando "opcional — dá para jogar sem conta", mais um rótulo visível "opcional" ao lado. O rótulo usa o hidden sm:inline já convencional no próprio header (mesmo padrão do nome do usuário logado), então no mobile o header não ganha nenhum elemento novo — o risco de regressão de layout é estruturalmente zero, não uma aposta. O rótulo é aria-hidden porque o aria-label do botão já anuncia a informação (evita leitura duplicada).

  2. Card do nick (HomeView.tsx) — uma linha de microcopy no tom do repo (// é só o nick — sem conta, sem e-mail) logo abaixo do input. Isso cobre o mobile, onde o rótulo do header fica escondido, e fica no ponto em que o jogador de fato age. Sem ela, o AC "fica visualmente claro" valeria só no desktop.

Acceptance criteria (#17)

  • Fica visualmente claro que jogar não exige login (rótulo "opcional" no desktop + microcopy no card, que cobre mobile).
  • O botão do Google continua funcional — não foi removido nem alterado no comportamento (onClick={auth.signInWithGoogle} intacto).
  • prefers-reduced-motion respeitado: nenhuma animação nova (os elementos adicionados não têm motion/transição).
  • Sem regressão de layout no header em mobile — garantido por construção via hidden sm:inline.
  • pnpm typecheck + pnpm build verdes.

Validação (resultado real)

pnpm typecheck                                    ✓ sem erros
pnpm build                                        ✓
pnpm test                                         ✓ 54 testes / 3 arquivos
node scripts/validate-persistence.mjs             ✓ 49 passaram, 0 falharam
node .claude/skills/cr-typing-engine/scripts/validate-metrics.mjs  ✓ 37 passaram, 0 falharam

pnpm lint = N/A (sem config ESLint no repo; a CI não roda lint).

Verificação visual: tentada, bloqueada — e o que fiz no lugar

Correção de uma promessa que este PR fazia: eu disse que ia anexar screenshot do preview da Vercel. O preview build passou (SUCCESS), mas a URL está atrás do deployment protection da Vercel (cai na tela de login) e a criação de link de bypass falhou (Unable to create shareable URL). Não faço login em conta sua, então não há screenshot — e prefiro corrigir a promessa a entregar uma verificação que não fiz.

No lugar, verifiquei o HTML pré-renderizado e o bundle client gerados pelo pnpm build neste worktree:

  • Microcopy do card do nick → presente no HTML pré-renderizado de /. É o elemento que cobre o mobile, então o AC crítico está provado no output real, não só no código-fonte.
  • Rótulo "opcional" + aria-label/titleausentes do HTML pré-renderizado, e isso está correto: o bloco inteiro de auth é gated por auth.available = hasBrowserSupabase(), que é falso em build-time. Confirmei que o próprio texto "entrar com Google" também tem 0 ocorrências no HTML — ou seja, não é efeito da minha mudança, é o gate pré-existente. Os três strings estão no bundle client (.next/static/chunks/app/page-*.js), então renderizam junto com o botão que anotam, exatamente na mesma condição.

O que não está coberto: conferência de pixel (o "opcional" ao lado do botão em ~360–640px reais). Se quiser, abra o preview logado e um screenshot fecha isso em 10s — ou eu ajusto na hora se estiver apertado.

Riscos

  • Muito baixo. Copy/markup only: nenhum fluxo de auth, nenhuma lógica, nenhuma dependência. Zero contato com a área sagrada (o input da corrida).
  • Único ponto de gosto: o texto do microcopy. Se preferir outra palavra ("não precisa de conta", "login é opcional"), é uma linha.

Closes #17

O hero promete "Sem cadastro, sem firula" e o header trazia "entrar com Google"
sem nenhuma pista de que era opcional. A persona Iniciante (D#14) travou nessa
contradição: "fiquei na dúvida se eu precisava logar pra jogar". Não precisa —
entrar só pré-preenche o nick (`HomeView:76` + `useAuth:21,30`).

- Header: `title` + `aria-label` explicitando "opcional — dá para jogar sem
  conta", mais um rótulo visível "opcional" ao lado do botão. O rótulo usa o
  `hidden sm:inline` já convencional no header, então o mobile não ganha nenhum
  elemento novo (zero risco de regressão de layout) e é `aria-hidden` para não
  duplicar o que o `aria-label` do botão já anuncia.
- Card do nick: uma linha de microcopy ("é só o nick — sem conta, sem e-mail")
  logo abaixo do input. Cobre justamente o mobile, onde o rótulo do header fica
  escondido, e fica no ponto em que o jogador de fato age.

Botão do Google intacto e funcional; nenhuma animação nova (reduced-motion
inalterado); nenhum fluxo de auth tocado — puro esclarecimento de copy/UI.

Closes #17
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
code-racer Ready Ready Preview, Comment Jul 26, 2026 1:29pm

@caioross

Copy link
Copy Markdown
Owner Author

Parecer do PR Doctor — APROVADO (§7.3 normal)

Diff lido inteiro (26+/6−, 1 arquivo). Classificação: normal — copy/markup only em HomeView.tsx; não toca api/rooms/**, supabase.ts, anti-cheat, migrations, CI nem dependências.

Conferi ponto a ponto:

  • Comportamento de auth intacto: onClick={auth.signInWithGoogle} idêntico; nenhum fluxo novo. O PR só anota o botão existente.
  • A11y correta, não decorativa: o aria-label carrega a informação e o <span>opcional</span> é aria-hidden — evita leitura duplicada no leitor de tela. title cobre o hover no desktop.
  • Mobile de verdade: o rótulo do header é hidden sm:inline (padrão já usado no próprio header), então o mobile não ganha elemento novo — quem cobre o mobile é a microcopy sob o input do nick, que é onde o jogador age. É o que faz o AC "fica visualmente claro" valer nos dois viewports, e não só no desktop.
  • Área sagrada e prefers-reduced-motion: zero contato com o input da corrida, zero animação nova.
  • Closes #17 legítimo: os 4 critérios de aceite da issue são cumpridos por este diff (clareza visual, botão preservado, sem regressão de layout no header mobile, gate verde).

Sobre a "verificação visual" no corpo: o PR corrigiu a própria promessa em vez de entregar screenshot que não tirou (preview atrás do deployment protection da Vercel) e provou o que dava para provar no output real do build — microcopy presente no HTML pré-renderizado; rótulo/aria-label no bundle client sob o mesmo gate auth.available que já esconde o próprio botão do Google. Honestidade de verificação é exatamente o padrão que a frota quer; nada a reparar.

CI verde (typecheck+test+build), MERGEABLE/CLEAN. Squash-merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Onboarding: botão "entrar com Google" contradiz "sem cadastro" — deixar login explicitamente opcional

1 participant