* refactor(ui): centralize proxy base URL resolution into tested resolver
The API base URL join logic was hand-rolled inside networking.tsx and
re-derived inline at hundreds of call sites, with no test coverage and a
latent double-slash bug when the base carried a trailing slash. This pulls
the join into a single pure resolveApiBase() with full unit coverage and
routes the existing resolution through it, also de-duplicating the env
precedence ladder that was copied in two places.
* test(ui): assert root-path redirect joins prefix exactly once
The existing toContain check accepts a doubled separator; tighten it to a
strict prefix match plus a no-double-slash assertion so a regression in the
resolveApiBase origin+SERVER_ROOT_PATH join is caught end-to-end.