Custom theme
This is the same <kai-chat> that powers every other example, reskinned into “Aurora” — a neon-on-noir identity with a magenta accent, a cyan focus ring, and sharp corners. Nothing pierces the Shadow DOM: a map of inherited --kai-* custom properties on the host does all of it. Toggle the site’s theme to watch a second, matched palette take over.
How it works
Section titled “How it works”The --kai-color-* and --kai-radius tokens are inherited CSS custom properties. Set them on the <kai-chat> element (or any ancestor) and they propagate into the Shadow DOM through var() fallbacks — no stylesheet import, no internal classes touched.
A bold look comes from overriding more than the accent. Aurora moves every surface, the focus ring, the inline-code tint, and the corner radius together so the result reads as a deliberate design, not a recolored default:
<kai-chat id="chat" chat-title="Aurora"></kai-chat>
<script type="module"> import '@kitn.ai/ui/elements';
const chat = document.getElementById('chat');
// Scope the whole Aurora map to this element only. const aurora = { '--kai-color-background': 'hsl(252 40% 6%)', // deep-noir surface '--kai-color-card': 'hsl(250 36% 10%)', // message bubbles / panels '--kai-color-foreground': 'hsl(250 30% 96%)', '--kai-color-primary': 'hsl(322 90% 58%)', // magenta accent '--kai-color-primary-foreground': 'hsl(250 40% 7%)', '--kai-color-ring': 'hsl(186 95% 56%)', // cyan focus glow '--kai-color-border': 'hsl(250 30% 20%)', '--kai-color-code-foreground': 'hsl(186 90% 66%)', // cyan inline code '--kai-radius': '0.25rem', // sharp corners }; for (const [token, value] of Object.entries(aurora)) { chat.style.setProperty(token, value); }
// Wire messages + kai-submit as usual. chat.messages = []; chat.addEventListener('kai-submit', (e) => { /* stream reply */ });</script>The aurora glow and the framed shell around the chat are host-side chrome — plain CSS on a wrapper that sits outside the element. The component never knows it’s there.
Cover both modes
Section titled “Cover both modes”A single token value applies in whichever mode the page is in, so a theme that’s intentional in both needs separate maps — one for light, one for dark. Each is self-contained, with the accent and ring darkened for light mode to keep text and focus at WCAG AA:
/* dark — neon on near-black indigo */.dark kai-chat { --kai-color-background: hsl(252 40% 6%); --kai-color-card: hsl(250 36% 10%); --kai-color-primary: hsl(322 90% 58%); --kai-color-ring: hsl(186 95% 56%); --kai-color-code-foreground: hsl(186 90% 66%);}
/* light — same identity, inverted onto a cool studio white */kai-chat { --kai-color-background: hsl(240 40% 98%); --kai-color-card: hsl(0 0% 100%); --kai-color-primary: hsl(322 82% 46%); /* darker → AA on light */ --kai-color-ring: hsl(192 90% 38%); /* darker → visible on light */ --kai-color-code-foreground: hsl(192 90% 32%);}The demo above sets these from JavaScript, re-applying the matching map whenever the page’s theme flips — handy when your overrides live in code rather than a stylesheet.
Next steps
Section titled “Next steps”- Theming guide — the full token reference, the
--kai-color-*alias system, scoped subtree theming, and dark-mode setup. - Drop-in chat — the streaming loop that backs any
<kai-chat>instance. kai-chatreference —proseSize,codeTheme, andcodeHighlightfor non-color appearance control.