Customization
Theming & Dark Mode
Overview
Vextro uses a two-tier token system defined in vextro.css. All semantic tokens use the --vx-* prefix and store space-separated RGB values for opacity support. Tailwind utility classes are mapped from these tokens via the @theme inline block.
| Tier | Purpose | Example |
|---|---|---|
| Primitives | Base zinc-based neutral scale | --neutral-500: 113 113 122 |
| Semantic | --vx-* prefixed UI colors | --vx-primary-rgb: 37 99 235 |
Semantic tokens map directly to Tailwind utilities: --vx-fg powers text-fg, --vx-surface powers bg-surface, --vx-edge powers border-edge.
Token Reference
Foreground (Text Hierarchy)
| Token | Tailwind Class | Light | Dark |
|---|---|---|---|
--vx-fg | text-fg | neutral-900 | neutral-100 |
--vx-fg-secondary | text-fg-secondary | neutral-600 | neutral-300 |
--vx-fg-muted | text-fg-muted | neutral-500 | neutral-400 |
--vx-fg-faint | text-fg-faint | neutral-400 | neutral-500 |
--vx-fg-inverse | text-fg-inverse | white | neutral-900 |
Surface (Background Hierarchy)
| Token | Tailwind Class | Light | Dark |
|---|---|---|---|
--vx-surface | bg-surface | white | neutral-900 |
--vx-surface-subtle | bg-surface-subtle | neutral-50 | neutral-800 |
--vx-surface-muted | bg-surface-muted | neutral-100 | neutral-700 |
--vx-surface-emphasis | bg-surface-emphasis | neutral-200 | neutral-600 |
--vx-surface-inverse | bg-surface-inverse | neutral-900 | neutral-100 |
Edge (Border Hierarchy)
| Token | Tailwind Class | Light | Dark |
|---|---|---|---|
--vx-edge | border-edge | neutral-200 | neutral-700 |
--vx-edge-muted | border-edge-muted | neutral-100 | neutral-750 |
--vx-edge-emphasis | border-edge-emphasis | neutral-300 | neutral-600 |
Status Colors
Each status color has base, hover, subtle, and muted variants.
| Token | Tailwind Class | Description |
|---|---|---|
--vx-primary-rgb | text-primary | Brand accent (blue) |
--vx-success | text-success | Positive actions (green) |
--vx-warning | text-warning | Caution states (amber) |
--vx-danger | text-danger | Errors, destructive (red) |
--vx-info | text-info | Informational (cyan) |
Variants follow the pattern --vx-{status}-hover, --vx-{status}-subtle, --vx-{status}-muted. Tailwind classes follow: bg-success-subtle, text-danger-hover, border-warning-muted, etc.
Customizing the Theme
Override tokens in your app CSS after importing Vextro styles. Only override the tier you need.
@import "vextro/styles.css";
:root {
--vx-primary-rgb: 124 58 237; /* violet accent */
--vx-primary-hover: 109 40 217;
--vx-primary-subtle: 245 243 255;
}
.dark, [data-theme="dark"] {
--vx-primary-rgb: 139 92 246;
--vx-primary-hover: 167 139 250;
--vx-primary-subtle: 46 16 101;
} All tokens use space-separated RGB values (e.g. 124 58 237) so they work with opacity modifiers: rgb(var(--vx-primary-rgb) / 0.5).
Dark Mode
Dark mode activates via the .dark class or [data-theme="dark"] attribute. Vextro overrides every semantic token inside this selector. Theme transitions use a smooth 200ms duration, respecting prefers-reduced-motion.
The token names stay the same between modes -- only the values change. This means components automatically adapt without any mode-specific logic.
Tailwind Integration
The @theme inline block maps --vx-* tokens to Tailwind utilities:
@theme inline {
--color-fg: rgb(var(--vx-fg));
--color-surface: rgb(var(--vx-surface));
--color-edge: rgb(var(--vx-edge));
--color-primary: rgb(var(--vx-primary-rgb));
/* ... */
} This generates Tailwind classes like text-fg, bg-surface, border-edge, text-primary. Use these classes in templates instead of referencing CSS variables directly.
In scoped <style> blocks where Tailwind classes are not available, use rgb(var(--vx-*)):
.my-element {
color: rgb(var(--vx-fg));
background: rgb(var(--vx-surface-muted));
border-color: rgb(var(--vx-edge));
} Best Practices
- To ensure dark mode compatibility, reference
--vx-*tokens instead of hardcoded hex colors in component styles. - Avoid CSS variable fallbacks with light-mode defaults (e.g.
var(--color, #f3f4f6)) — add missing tokens to the token system instead. - Prefer semantic Tailwind classes (
text-fg,bg-surface,border-edge) over fixed Tailwind colors for automatic theme adaptation. - In scoped
<style>blocks, use thergb(var(--vx-*))format to reference tokens. - SVG data URIs with embedded colors should include a
.darkoverride for the alternate palette. - Components should be verified in both light and dark mode to ensure full theme compatibility.