Add the op.console login and forced first-login password-change flow to
the panel. RequireAuth bounces an unauthenticated visitor to /login;
both /login and /change-password render outside the app shell with their
own centered chrome.
- TierProvider now derives auth state (deriveAuth) and exposes refresh()
so a successful login re-fetches identity without a full reload; only a
genuine 401 marks the session unauthenticated, so a transient /me
failure keeps a healthy Zero-Trust principal in the app.
- api.login/logout/changePassword send Content-Type: application/json on
bodied requests to satisfy the backend guard; humanizeError maps the
auth error codes to stable copy.
Covered by vitest unit tests for deriveAuth branch coverage and the
login/change-password wire-shape contracts.
Vite + TypeScript + Tailwind single-page console presenting the three operator tiers and consuming the external felis-api face. Build output and design notes are not tracked.