fix(pwa): barra de status segue o tema e reveal de troca mais fluido#67
Merged
Conversation
No PWA a barra de status ficava verde (cor de destaque) em vez de acompanhar o tema. O <meta name="theme-color"> e o theme_color do manifest apontavam para o accent; agora o meta reflete, em runtime, o fundo do tema resolvido (claro/ escuro, já tingido pelo accent/preset) e o manifest abre na cor do fundo escuro. A cor de destaque continua identificando ícones e manifest. O circular reveal parecia lento e hesitante: usava ease-in-out, que quase não cresce nos primeiros quadros. Passa a emphasized decelerate (ease-out) e 320ms, que abre rápido e assenta suave. - theme-color.ts: fonte única do <meta theme-color>; lê o fundo renderizado (normaliza oklch via canvas 2D) e mantém sincronizado via ThemeColorSync (observa tema, accent, preset e tinge do documentElement). - browser-accent.ts deixa de tocar no theme-color (segue dono só de ícones e do link do manifest).
Ajustes após validar as decisões contra o padrão de 2026 (as escolhas centrais — meta única em runtime, ler o fundo do DOM, canvas para oklch, View Transitions com ease-out — já estavam alinhadas): - ThemeColorSync passa a usar useSyncExternalStore, o hook próprio para ler uma fonte mutável externa (o fundo do documentElement), com o MutationObserver como subscribe e snapshot cacheado. Tearing-safe sob concurrent rendering; o guia do React desaconselha o padrão anterior (useEffect + observer disparando o efeito). - theme-color.ts separa writeThemeColorMeta de readResolvedBackgroundColor. - Documenta o alcance por plataforma: em runtime a meta só é lida pelo Chromium; a partir do Safari/iOS 26 o WebKit deriva a cor do fundo do <body> no primeiro paint (carimbo de frescor), então "não muda no iPhone" não é bug. - Corrige comentários que afirmavam "o app abre escuro por padrão": com defaultTheme="system", um usuário com SO claro abre claro. A cor fixa do manifest é âncora de marca para a splash, com o flash inicial como limitação de plataforma conhecida. - e2e força prefers-color-scheme divergente do tema (emulateMedia), provando que o runtime vence a media query do SO — o motivo de não usar meta media estática.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
O que e por quê
No app instalado (PWA), a barra de status do sistema ficava verde — a cor de destaque — em vez de acompanhar o tema claro/escuro. E a animação de troca de tema (circular reveal) parecia lenta e hesitante no celular.
Barra de status
A cor da barra de status de um PWA vem do
theme_colordo manifest (na abertura) e do<meta name="theme-color">(em runtime). Ambos apontavam para o accent.<meta name="theme-color">passa a refletir o fundo do tema resolvido (claro/escuro, já tingido pelo accent/preset). Fonte única emtheme-color.ts, sincronizada porThemeColorSync(observa tema, accent, preset e o tinge dodocumentElement).oklchpara#rrggbbvia canvas 2D — o<meta>não aceitaoklchde forma confiável, e o Chromium serializagetComputedStyleemoklch.manifest.jsonabre comtheme_color/background_colorno fundo escuro (o app abre escuro), não no accent. Ícones e link do manifest continuam seguindo o accent.browser-accent.tsdeixa de ser dono dotheme-color(segue dono só dos ícones e do link do manifest).Circular reveal
O reveal partia do raio 0 com
ease-in-out— que quase não cresce nos primeiros quadros, passando sensação de lentidão. Passa a emphasized decelerate (ease-out,cubic-bezier(0.05, 0.7, 0.1, 1)) e 320 ms: abre rápido e assenta suave. Mantém a decisão de produto de não respeitarprefers-reduced-motion.Como verificar
e2e/theme-color.spec.ts: com accent rosa saturado, a barra fica escura no tema escuro e clara no claro — nunca o accent.theme-color.test.ts(conversão oklch→hex e sincronização) emanifest.json/route.test.ts.Gates locais verdes: lint,
tsc, 310 testes unit, react-doctor (changed) sem issues, e2e do theme-color enext build.