# Console Branding Architecture ## 1. Purpose - Provide tenant-aware branding (logo, colors, title) without rebuilding the UI. - Keep branding changes auditable, deterministic, and offline-friendly. - Allow defaults to be injected via config.json and overridden per tenant after login. ## 2. Scope - Branding data model and storage in Authority. - API surface for read/update/preview. - UI application of theme tokens and assets. - Offline export/import and audit handling. Non-goals: - Arbitrary CSS injection from untrusted sources. - Runtime font downloads from public CDNs (offline-first constraint). ## 3. Branding Data Model Authority stores a tenant-scoped branding record: - `brandingId` - `tenantId` - `displayName` (header title) - `logo` (data URI or asset reference) - `favicon` (data URI or asset reference) - `themeTokens` (CSS variable map for light/dark/high-contrast) - `updatedBy`, `updatedAtUtc` - `hash` (sha256 of canonical JSON for cache invalidation) Constraints: - Logo and favicon limited to 256KB each. - Only `image/svg+xml`, `image/png`, or `image/jpeg` accepted. - Theme tokens restricted to a whitelist (no arbitrary CSS). ## 4. Configuration Layering 1. **Static defaults** from `/config.json`. 2. **Tenant branding** from Authority after login. 3. **Session overrides** for preview mode (not persisted). If Authority is unreachable, the UI uses the static defaults. ## 5. API Surface ### 5.1 Read branding - `GET /console/branding` (active tenant) - Scopes: `ui.read`, `authority:branding.read` ### 5.2 Update branding (admin only) - `PUT /console/admin/branding` - Scopes: `ui.admin`, `authority:branding.write` - Requires fresh-auth ### 5.3 Preview branding - `POST /console/admin/branding/preview` - Scopes: `ui.admin`, `authority:branding.write` - Returns computed tokens and sanitized assets without persisting ## 6. UI Application - Branding service fetches `/console/branding` after login. - Applies CSS variables on `document.documentElement`. - Updates header/logo assets and document title. - Supports theme-specific overrides using `data-theme` selectors. ## 7. Audit and Offline - Branding updates emit `authority.branding.updated` events. - Branding bundles are exported with a detached signature for offline import. - Console shows last applied branding hash for verification. ## 8. References - `docs/ui/branding.md` - `docs/modules/ui/architecture.md` - `docs/modules/authority/architecture.md`