# BOTSU application shell Task 3 introduces the first source-built BOTSU portal inside Cinny while preserving all existing Matrix routes. ## Routes - `/botsu/` — member application catalogue - `/botsu/services/` — fixed catalogue of authorized BOTSU services - `/botsu/embed/:appId/` — validated iframe host for catalogue entries - `/home/` — existing Cinny discussions route, unchanged A `B` entry in Cinny's global sidebar opens `/botsu/`. The shell is inside the authenticated `ClientRoot`, so it does not bypass Matrix login or initialization. ## Catalogue The member catalogue exposes: 1. Discussions — native and available 2. Documents — native and planned 3. Tables — iframe and planned 4. Files — native and planned 5. Transfers — external and available 6. Services — native and available Administration is a separate `admin` entry. Task 3 intentionally passes only the `member` role because a Matrix room power level is not a global BOTSU role. Task 4 will provide the authenticated identity and role mapping. Until then, administration is hidden and marked planned. Planned applications remain visible as product direction but render a disabled `Bientôt` state. They cannot produce a navigation, iframe, or external launch plan. ## Launch policy Every app declares one launch mode: - `native` — an internal absolute path beginning with one `/`; - `iframe` — an HTTPS URL whose exact origin is in the iframe allowlist; - `external` — an HTTPS URL whose exact origin is in the external allowlist. The launcher rejects malformed URLs, HTTP URLs, embedded credentials, unknown origins, protocol-relative native paths, raw or encoded backslashes/control characters, normalized cross-origin paths, and unsupported launch modes. Iframe plans currently allow only `https://tabs.botsu.net` and apply: - `sandbox="allow-forms allow-same-origin allow-scripts"` - `referrerPolicy="no-referrer"` - no top-navigation or popup permission External plans always use `_blank` with `rel="noopener noreferrer"`. No Matrix access token, session, user ID, or arbitrary URL is passed to an embedded application. ## Theme controls The shell consumes `@botsu/ui` and stores only validated visual preferences under `botsu.theme.v1` in browser local storage. Members can change: - black or white mode; - Inter, system, or monospace font; - accent color; - border width; - corner radius; - glass opacity; - backdrop blur. Blocked or full local storage does not prevent the in-memory theme from working. Reset returns to the monochrome brutalist default. Accent colors must retain at least 3:1 contrast against the active canvas; an inaccessible choice falls back to white on black or black on white. Interactive text uses a separately derived `on-accent` foreground with the stronger available contrast. ## Verification Task 3 gates: ```bash npm test npm run typecheck:ui npm run typecheck:botsu npm run build:client ``` The inherited full Cinny typecheck/lint debt remains documented separately. ESLint and Prettier are run directly on all new `src/botsu` files.