feat(web+appview): theme caching layer (ATB-56)
Add in-memory TTL cache for resolved theme data on the web server to
avoid redundant AppView API calls on every page request.
- New ThemeCache class (theme-cache.ts): TTL entries for policy (single)
and themes (keyed by uri:colorScheme to keep light/dark isolated)
- resolveTheme now accepts an optional ThemeCache; checks cache before
each fetch, populates after successful CID validation; stale CID on
cache hit falls through to a fresh fetch rather than serving stale data
- createThemeMiddleware creates one ThemeCache at startup (shared across
all requests); accepts configurable cacheTtlMs (default 5 min)
- THEME_CACHE_TTL_MS env var exposed via WebConfig.themeCacheTtlMs
- AppView theme endpoints now set Cache-Control: public, max-age=300;
GET /api/themes/:rkey also sets ETag from the theme record CID