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 compartilha fontSize/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
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.
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 12permite 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 alinhamentotextarea ↔ overlay colorido ↔ gutter depende dos três casarem.
A spec já pede isso:
docs/UI-AAA-OVERHAUL.md§III, "Responsivo (mobile — crítico, hojefrágil)" → "Fonte do código maior (16px+) para o teclado virtual".
Acceptance criteria
(pointer: coarse)ou largura < 768px), o editornasce com
fontSize >= 16; em desktop o default de 15px pode permanecer.descer abaixo do limiar de zoom pelo menu de opções (desktop mantém
MIN_FONT = 12).<pre>espelho + gutter continua alinhado char-a-char emqualquer tamanho válido (nenhum drift visual no realce da linha ativa,
:277+).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 (áreasagrada: a decisão de tamanho é resolvida no mount/resize, nunca no
onChange).typecheck+build+ Vitest).Dica de abordagem
Fatia de uma rodada. Resolver o default no mount (e em
resize, com debounce) viawindow.matchMedia("(pointer: coarse)")— e derivarMIN_FONTefetivo do mesmo sinal, emvez de espalhar condicional pela UI. Cuidado com hidratação:
matchMedianão existe noservidor; inicialize com o valor de desktop e ajuste num
useEffect(o primeiro paint com15px é aceitável — o zoom do iOS só dispara no foco). Evite
user-scalable=nono viewport:mata o pinch-zoom e é problema de acessibilidade — a correção certa é a fonte.