# Build: RTSport Login Page — 2026-05-08 ## Status Orchestrator: ✅ Complete Backend: ✅ Done Frontend: ✅ Done ## Backend Progress - [x] Router implemented at `backend/login_router.py` - [x] Serves `GET /rtsport/login` via HTMLResponse - [x] Reads template from `shared/current/frontend/templates/login.html` - [x] Graceful 404 fallback if template missing - [x] Mounted in main_v2.py on blog_app ## Frontend Progress - [x] `templates/login.html` — dark theme, mobile-first, semantic HTML - [x] `static/css/login.css` — 272 lines, spinner animation, error banner, 44px tap targets - [x] `static/js/login.js` — IIFE, role-based redirect, error handling, no hardcoded domains ## Integration Notes - All endpoints match spec: POST /api/v1/auth/login/json - Response shapes match: access_token, role, school_id - Error handling matches: 401 → detail message - Shared constants consistent: role → route mapping ## Filesystem - `shared/current` → `build-20260508/` (atomic symlink swap) - `RTS_BASE` updated to `shared/current/frontend` (was hardcoded to build-20260501) - Login router imported from `shared/current/backend/` in main_v2.py ## Post-Deploy - [x] Symlink created - [x] RTS_BASE config fixed - [x] Login router mounted - [ ] Service restart (needs sudo) - [ ] ~/rtsport/ → current/ symlink (needs git migration decision)