Split out of the TRACK-81 brand audit.
Problem
A full page load of a missing, forbidden or broken portal page renders Go's plain-text body (not found, forbidden, internal error) in the browser's default monospace font, with no shell, sidebar or brand. For example, open /{owner}/projects/NOPE directly.
The cause is that writeUIStoreError and writeUIInternalError write plain-text http.Error responses. Those are right for htmx fragments, where htmx doesn't swap 4xx/5xx bodies, but not for browser navigations. Unknown URLs already get the branded error-panel inside the shell (uiNotFound). Known routes whose lookup fails don't.
Expected
- A browser page navigation (a
GET that accepts text/html and isn't an htmx request) that fails with one of these plain-text errors renders error-panel inside the shell, with the same status code and the signed-in sidebar.
- htmx,
fetch, image, websocket and API requests keep today's plain-text bodies.