Repository navigation
Description
Contexto
O editor da corrida nasce com fonte de 15px — abaixo do limiar de 16px que faz o
Safari/iOS dar zoom automático ao focar um campo de texto. Na prática: o jogador de
celular toca no editor, a página dá um zoom que ele não pediu, e a corrida começa com a
viewport deslocada (o código-alvo sai de vista). O zoom acontece no primeiro toque —
aumentar a fonte depois pelo menu de opções não desfaz o estrago.
Origem: [Feedback] O Mobile · 2026-07-18 (Discussion #45), fricção nº2 — ICE ≈ 75
(Impacto 3 × Confiança 5 × Facilidade 5), candidata nº1 do [Plano] W30 (#47).
Evidência no código (origin/main):
src/components/CodeEditor.tsx:38—const [fontSize, setFontSize] = useState(15);src/components/CodeEditor.tsx:15-16—MIN_FONT = 12/MAX_FONT = 20(o piso de 12
permite o jogador descer abaixo do limiar de zoom manualmente, no mobile)src/components/CodeEditor.tsx:45—lineHeight = Math.round(fontSize * 1.7), e
:217— a gutter compartilhafontSize/lineHeight, então o alinhamento
textarea ↔ overlay colorido ↔ gutter depende dos três casarem.
A spec já pede isso: docs/UI-AAA-OVERHAUL.md §III, "Responsivo (mobile — crítico, hoje
frágil)" → "Fonte do código maior (16px+) para o teclado virtual".
Acceptance criteria
- Em viewport touch/estreita (ex.:
(pointer: coarse)ou largura < 768px), o editor
nasce comfontSize >= 16; em desktop o default de 15px pode permanecer. - No mesmo contexto, o piso do controle "tamanho da fonte" é 16 — não é possível
descer abaixo do limiar de zoom pelo menu de opções (desktop mantémMIN_FONT = 12). - O trio textarea +
<pre>espelho + gutter continua alinhado char-a-char em
qualquer tamanho válido (nenhum drift visual no realce da linha ativa,:277+). - Nenhuma mudança na lógica de digitação:
handleInput/comparação char-a-char, WPM,
precisão e anti-cheat intactos —node scripts/validate-metrics.mjsverde. -
prefers-reduced-motioninalterado; nenhum trabalho novo por keystroke (área
sagrada: a decisão de tamanho é resolvida no mount/resize, nunca noonChange). - Gate do HANDBOOK §6 verde (
typecheck+build+ Vitest).
Dica de abordagem
Fatia de uma rodada. Resolver o default no mount (e em resize, com debounce) via
window.matchMedia("(pointer: coarse)") — e derivar MIN_FONT efetivo do mesmo sinal, em
vez de espalhar condicional pela UI. Cuidado com hidratação: matchMedia não existe no
servidor; inicialize com o valor de desktop e ajuste num useEffect (o primeiro paint com
15px é aceitável — o zoom do iOS só dispara no foco). Evite user-scalable=no no viewport:
mata o pinch-zoom e é problema de acessibilidade — a correção certa é a fonte.
Activity
caioross commentedon Jul 26, 2026
Resolvido em PR #88. Editor nasce em 16px no toque (piso 16; desktop segue 15 com piso 12), via sinal único de viewport aplicado no primeiro paint — divergi da dica do
useEffectporque o editor dáfocus()no mount e o zoom do iOS dispara no foco. Trio textarea/pre/gutter verificado alinhado em 12/15/16/20px. Gate: typecheck+build+65 testes+validate-metrics (37/37) verdes.feat(mobile): corrida jogável no touch — alvo e caret visíveis juntos (…
fix(mobile): editor nasce em 16px no toque para o iOS não dar zoom ao…
feat(mobile): corrida jogável no touch — código-alvo e caret visíveis…