Built out the player management system using XState. I created a playerMachine that handles the full lifecycle: checking localStorage for cached credentials, fetching a new token if needed, caching the result, and then fetching user details from the API.

I also reorganized the codebase, moving all the state machines into a dedicated machines folder. The apiMachine was refactored to use sendParent for communicating results back to parent machines, and I split out apiPollMachine into its own file for the polling use case.

The Player component now properly shows a loading state until the machine reaches the “loaded” state, and the “new player” button works again - it sends a CLEAR_PLAYER event that removes the cached credentials and restarts the authentication flow.