Step 4 of docs website/DEMO_MODE.md §10 (website#222).
- DemoLockInterceptor on the main client peeks every 403 body. On
code DEMO_LOCKED it reports the server's sentence to DemoNotices, and the
shell shows it as one snackbar, like the web's toast (DM19). A newer refusal
replaces the one showing. Screens added later get it without doing anything.
- ApiResult.HttpError carries the body's code (read only on a 403, peeked so
the body is not consumed); isDemoLocked(). ErrorKind.DEMO_LOCKED is mapped
ahead of the status in toUiState and toShardUiState, and is not retryable.
- Screens whose 403 copy blames the role now say the demo sentence instead:
the four admin view models, Characters' account creation, and the contact
form's line (the contact form is locked on the demo).
- Home draws the strip from GET /public/settings' demo block: the wipe time in
UTC, the published usernames, and the site's sign-in page for the passwords.
The app does not list the passwords (DM20). A real shard sends no block, so
it draws nothing.
Checked on an emulator against website main (69998ec) with DEMO_MODE=true and
seed:demo: the strip on Home; demo-player's username change refused with the
snackbar under the screen's own line; demo-admin's site-mode switch refused
with the demo sentence in place of "You don't have permission".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY