- NavigationExtensions: centralized NavigateToLogin/NavigateToLoginForce
helpers that include returnUrl query parameter
- LoginService: SemaphoreSlim guard on Reauthenticate to prevent
concurrent refresh races (timer + API handler)
- MainLayout: expiry-driven keepalive loop — parses JWT, schedules
reauthentication 2 min before token expiry; starts on login,
stops on logout/force-logout
- Login page: reads returnUrl from query via SupplyParameterFromQuery,
navigates there (or /) on success
- All NavigateTo(/login) call sites updated to use returnUrl:
App, MainLayout, NavMenu, Jobs, Settings, AdminUsers
- Cosplayers: fix eternal spinner when logged out (set isLoading=false),
update message to 'No media available' with hint about public content