Theming
The widget uses CSS custom properties (variables) for all visual styling. It provides full style isolation - your page styles won't leak in, and the widget styles won't leak out.
How It Works
The theming system has three layers, applied in order of priority:
- CSS Defaults - Base values defined in the widget's
:hoststyles - Backend Theme API - Runtime overrides fetched from the SayTV API
- Consumer Overrides - Inline
styleattribute on the<saytv-chat>element (highest priority)
Dark Mode
Set the theme attribute to switch between light and dark:
html
<saytv-chat app-id="your-app-id" theme="dark"></saytv-chat>The dark theme automatically overrides backgrounds, text colors, borders, and shadows.
Custom Colors
Override any CSS variable via inline styles:
html
<saytv-chat
app-id="your-app-id"
theme="light"
style="
--stv-color-primary: #4f46e5;
--stv-color-accent: #10b981;
--stv-bg-primary: #fafafa;
--stv-text-primary: #111827;
"
></saytv-chat>CSS Custom Properties Reference
Brand Colors
| Property | Light Default | Description |
|---|---|---|
--stv-color-primary | #7e171c | Primary brand color |
--stv-color-primary-dark | #5d1014 | Darker primary variant |
--stv-color-accent | #0143d9 | Accent / interactive color |
--stv-color-accent-yellow | #f8dc22 | Secondary accent |
--stv-color-danger | #e03333 | Error / destructive actions |
--stv-color-success | #1fa84a | Success indicators |
--stv-color-info | #3b82f6 | Informational elements |
--stv-color-warning | #f59e0b | Warning indicators |
Backgrounds
| Property | Light | Dark | Description |
|---|---|---|---|
--stv-bg-primary | #fafaf8 | #0e0e12 | Main background |
--stv-bg-secondary | #f2f0ec | #161619 | Secondary surfaces |
--stv-bg-light | #f5f3ef | #1c1c22 | Elevated surfaces |
--stv-bg-hover | #efede8 | #212128 | Hover state |
--stv-bg-input | #ffffff | #1a1a20 | Input fields |
--stv-bg-disabled | #eae8e3 | #252530 | Disabled elements |
--stv-bg-overlay | rgba(0,0,0,0.5) | - | Modal overlays |
Text
| Property | Light | Dark | Description |
|---|---|---|---|
--stv-text-primary | #0d0d0f | #f0eff5 | Primary text |
--stv-text-secondary | #4a4852 | #b0aebe | Secondary text |
--stv-text-muted | #8b8a96 | #706e80 | Muted / hint text |
--stv-text-light | #ffffff | - | Text on dark backgrounds |
--stv-text-hashtag | #1d4ed8 | - | Hashtag text |
--stv-text-link | #0143d9 | - | Link text |
--stv-text-danger | #e03333 | - | Error text |
Borders
| Property | Light | Dark | Description |
|---|---|---|---|
--stv-border-color | #e5e2db | #2a2932 | Default borders |
--stv-border-light | #edebe5 | #252430 | Subtle borders |
--stv-border-focus | #0143d9 | - | Focus ring color |
--stv-border-error | #e03333 | - | Validation error |
Border Radius
| Property | Default | Description |
|---|---|---|
--stv-border-radius-xs | 0.25rem | Extra small (4px) |
--stv-border-radius-sm | 0.375rem | Small (6px) |
--stv-border-radius-md | 0.625rem | Medium (10px) |
--stv-border-radius-lg | 1rem | Large (16px) |
--stv-border-radius-xl | 1.5rem | Extra large (24px) |
--stv-border-radius-full | 50% | Circle |
Typography
| Property | Default | Description |
|---|---|---|
--stv-font-primary | System sans-serif stack | Body font family |
--stv-font-heading | System rounded stack | Heading font family |
--stv-font-mono | "SF Mono", "Fira Code", monospace | Monospace font |
--stv-font-size-xs | 0.6875rem | 11px |
--stv-font-size-sm | 0.8125rem | 13px |
--stv-font-size-base | 0.875rem | 14px |
--stv-font-size-md | 1rem | 16px |
--stv-font-size-lg | 1.25rem | 20px |
--stv-font-size-xl | 1.5rem | 24px |
--stv-font-weight-normal | 400 | Normal weight |
--stv-font-weight-medium | 500 | Medium weight |
--stv-font-weight-semibold | 600 | Semibold weight |
--stv-font-weight-bold | 700 | Bold weight |
--stv-line-height-tight | 1.25 | Compact line height |
--stv-line-height-normal | 1.5 | Default line height |
Custom Fonts
To use custom fonts, override the font family variables:
html
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<saytv-chat
app-id="your-app-id"
style="--stv-font-primary: 'Inter', sans-serif;"
></saytv-chat>The font @import or <link> must be on the host page since the Shadow DOM can inherit font-face declarations from the parent document.
Spacing
| Property | Default | Description |
|---|---|---|
--stv-spacing-xs | 0.25rem | 4px |
--stv-spacing-sm | 0.5rem | 8px |
--stv-spacing-md | 1rem | 16px |
--stv-spacing-lg | 1.5rem | 24px |
--stv-spacing-xl | 2rem | 32px |
--stv-spacing-2xl | 3rem | 48px |
Shadows
| Property | Light | Dark |
|---|---|---|
--stv-shadow-sm | 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04) | Stronger |
--stv-shadow-md | 0 4px 12px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.05) | Stronger |
--stv-shadow-lg | 0 8px 24px rgba(0,0,0,0.1), 0 4px 8px rgba(0,0,0,0.06) | Stronger |
--stv-shadow-xl | 0 16px 48px rgba(0,0,0,0.14), 0 8px 16px rgba(0,0,0,0.08) | Stronger |
Transitions
| Property | Default | Description |
|---|---|---|
--stv-transition-fast | 150ms ease | Hover, focus states |
--stv-transition-normal | 250ms ease | General animations |
--stv-transition-slow | 400ms ease | Page transitions |
Extended Tokens
| Property | Default | Description |
|---|---|---|
--stv-button-border-radius | var(--stv-border-radius-md) | Button corners |
--stv-input-border-radius | var(--stv-border-radius-lg) | Input field corners |
--stv-footer-label-size | 0.6875rem | Footer nav label size |
--stv-skeleton-duration | 1.8s | Loading skeleton animation |
Examples
Brand Customization
html
<saytv-chat
app-id="your-app-id"
style="
--stv-color-primary: #7c3aed;
--stv-color-primary-dark: #5b21b6;
--stv-color-accent: #06b6d4;
--stv-border-radius-md: 12px;
--stv-border-radius-lg: 16px;
"
></saytv-chat>Rounded Theme
html
<saytv-chat
app-id="your-app-id"
style="
--stv-border-radius-xs: 0.5rem;
--stv-border-radius-sm: 0.75rem;
--stv-border-radius-md: 1rem;
--stv-border-radius-lg: 1.5rem;
--stv-border-radius-xl: 2rem;
--stv-button-border-radius: 9999px;
--stv-input-border-radius: 9999px;
"
></saytv-chat>Compact Spacing
html
<saytv-chat
app-id="your-app-id"
style="
--stv-spacing-xs: 0.125rem;
--stv-spacing-sm: 0.25rem;
--stv-spacing-md: 0.5rem;
--stv-spacing-lg: 0.75rem;
--stv-spacing-xl: 1rem;
"
></saytv-chat>