ActivePetProvider read localStorage in a useEffect, but
ActivePetInitializer (a descendant, so its effect fires first — React
runs effects child-before-parent) checked activePetId in its own
effect and overwrote localStorage with the owner's first pet whenever
it still saw the initial null — which was always, on every reload,
since the provider's own effect hadn't run yet. The switched-to pet
never had a chance to be read back.
Reads localStorage synchronously via a lazy useState initializer
(window-guarded for SSR) instead, so activePetId is already correct
on the client's first render and the race can't happen.