The 0.0.4 architecture set design tokens on every chat component's
:host. Two consequences that broke the documented theming contract:
1. Direct-on-host token settings shadow CSS inheritance from :root,
regardless of specificity. So a consumer's
`:root { --ngaf-chat-primary: blue; }` (specificity 0,0,1) was
ignored — `[_nghost-c123] { --ngaf-chat-primary: dark; }` (0,1,0,
targeting the chat element directly) won.
2. `:host([data-ngaf-chat-theme="dark"])` only matched the component's
own host, not ancestors. And every child component (chat-input,
chat-message, chat-window, ...) re-set light tokens on its own
:host, shadowing parent attribute switches anyway.
Fix: stop setting tokens on :host. Inject the defaults onto `:root`
once via a shared `<style id="ngaf-chat-root-tokens">` element,
appended to <head> on first chat-component module evaluation
(idempotent, SSR-guarded). Wrap the rule set in `@layer ngaf-chat`
so consumer's unlayered `:root { ... }` wins regardless of source
order — the standard CSS pattern for framework defaults.
Theme switching now works on any ancestor: setting
`[data-ngaf-chat-theme="dark"]` on `<html>`, `<body>`, or any wrapper
flips dark via inherited custom properties (no more :host override
plumbing needed).
Validated end-to-end against the published smoke app:
- Default light tokens load on :root ✓
- `:root { --ngaf-chat-primary: rgb(80, 0, 200); }` consumer override
applies to chat element (chatPrimary becomes rgb(80, 0, 200)) ✓
- `document.body.setAttribute('data-ngaf-chat-theme', 'dark')` flips
the entire chat to dark ✓
Bumps @ngaf/chat to 0.0.5.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>