Vite builds with base='/turnstone/' so asset paths in index.html are
/turnstone/assets/*. Serving FastAPI at root / meant direct hits to
port 8534 got index.html for asset requests (blank page).
- All routes now under /turnstone (APIRouter prefix + StaticFiles mount
at /turnstone/assets + SPA catch-all at /turnstone/{path})
- Root / redirects to /turnstone/
- Caddy block reverted to no-strip: both direct LAN and Caddy access
hit the same paths, no per-host routing differences
Python http.server can't do SPA routing and Caddy was forwarding
/turnstone/* paths that the static server couldn't resolve.
- app/rest.py: mount web/dist/assets as StaticFiles; add SPA catch-all
route that serves index.html for any unmatched path
- manage.sh: start/stop/status simplified to single process on :8534;
remove UI_PORT / UI_PID_FILE; drop http.server invocation
- Caddyfile: replace split API/:8534 + SPA/:8535 block with a single
strip_prefix + reverse_proxy to :8534