This is a dense reference for LLMs working in Vextro-consuming projects. It documents the complete styling system including CSS custom properties, Tailwind utility class mapping, dark mode mechanism, and override patterns.
Token Architecture
Vextro uses a three-layer token system:
- Primitives — Base color scale (
--neutral-50 through --neutral-950), zinc-based, space-separated RGB
- Semantic — Meaningful tokens with
--vx-* prefix (--vx-fg, --vx-surface, --vx-primary-rgb)
- Tailwind —
@theme inline maps tokens to utility classes (text-fg, bg-surface, border-edge)
All color tokens use space-separated RGB format for opacity support: rgb(var(--vx-fg) / 0.5).
Primitive Neutral Scale
| Token | Light RGB | Hex Approx |
|---|
--neutral-50 | 250 250 250 | #fafafa |
--neutral-100 | 244 244 245 | #f4f4f5 |
--neutral-200 | 228 228 231 | #e4e4e7 |
--neutral-300 | 212 212 216 | #d4d4d8 |
--neutral-400 | 161 161 170 | #a1a1aa |
--neutral-500 | 113 113 122 | #71717a |
--neutral-600 | 82 82 91 | #52525b |
--neutral-700 | 63 63 70 | #3f3f46 |
--neutral-750 | 52 52 56 | #343438 |
--neutral-800 | 39 39 42 | #27272a |
--neutral-850 | 30 30 33 | #1e1e21 |
--neutral-900 | 24 24 27 | #18181b |
--neutral-950 | 9 9 11 | #09090b |
Semantic Foreground Tokens
| Token | Light Value | Dark Value | Tailwind Class |
|---|
--vx-fg | var(--neutral-900) | 244 244 245 | text-fg |
--vx-fg-secondary | var(--neutral-600) | 212 212 216 | text-fg-secondary |
--vx-fg-muted | var(--neutral-500) | 161 161 170 | text-fg-muted |
--vx-fg-faint | var(--neutral-400) | 113 113 122 | text-fg-faint |
--vx-fg-inverse | 255 255 255 | 24 24 27 | text-fg-inverse |
Semantic Surface Tokens
| Token | Light Value | Dark Value | Tailwind Class |
|---|
--vx-surface | 255 255 255 | 24 24 27 | bg-surface |
--vx-surface-subtle | var(--neutral-50) | 39 39 42 | bg-surface-subtle |
--vx-surface-muted | var(--neutral-100) | 63 63 70 | bg-surface-muted |
--vx-surface-emphasis | var(--neutral-200) | 82 82 91 | bg-surface-emphasis |
--vx-surface-inverse | var(--neutral-900) | 244 244 245 | bg-surface-inverse |
Semantic Edge (Border) Tokens
| Token | Light Value | Dark Value | Tailwind Class |
|---|
--vx-edge | var(--neutral-200) | 63 63 70 | border-edge |
--vx-edge-muted | var(--neutral-100) | 52 52 56 | border-edge-muted |
--vx-edge-emphasis | var(--neutral-300) | 82 82 91 | border-edge-emphasis |
Status Color Tokens
Each status color has 4 variants: base, hover, subtle (background tint), muted (stronger tint).
Primary (Blue — brand/accent)
| Token | Light RGB | Dark RGB | Tailwind |
|---|
--vx-primary-rgb | 37 99 235 | 59 130 246 | text-primary, bg-primary |
--vx-primary-hover | 29 78 216 | 96 165 250 | bg-primary-hover |
--vx-primary-active | 30 64 175 | 37 99 235 | bg-primary-active |
--vx-primary-subtle | 239 246 255 | 23 37 84 | bg-primary-subtle |
--vx-primary-muted | 191 219 254 | 30 58 138 | bg-primary-muted |
Success (Green)
| Token | Light RGB | Dark RGB | Tailwind |
|---|
--vx-success | 22 163 74 | 34 197 94 | text-success, bg-success |
--vx-success-hover | 21 128 61 | 74 222 128 | bg-success-hover |
--vx-success-subtle | 240 253 244 | 5 46 22 | bg-success-subtle |
--vx-success-muted | 187 247 208 | 22 101 52 | bg-success-muted |
Warning (Amber)
| Token | Light RGB | Dark RGB | Tailwind |
|---|
--vx-warning | 217 119 6 | 245 158 11 | text-warning, bg-warning |
--vx-warning-hover | 180 83 9 | 251 191 36 | bg-warning-hover |
--vx-warning-subtle | 255 251 235 | 69 26 3 | bg-warning-subtle |
--vx-warning-muted | 253 230 138 | 120 53 15 | bg-warning-muted |
Danger (Red)
| Token | Light RGB | Dark RGB | Tailwind |
|---|
--vx-danger | 220 38 38 | 239 68 68 | text-danger, bg-danger |
--vx-danger-hover | 185 28 28 | 248 113 113 | bg-danger-hover |
--vx-danger-subtle | 254 242 242 | 69 10 10 | bg-danger-subtle |
--vx-danger-muted | 254 202 202 | 127 29 29 | bg-danger-muted |
Info (Cyan)
| Token | Light RGB | Dark RGB | Tailwind |
|---|
--vx-info | 2 132 199 | 14 165 233 | text-info, bg-info |
--vx-info-hover | 3 105 161 | 56 189 248 | bg-info-hover |
--vx-info-subtle | 236 254 255 | 8 51 68 | bg-info-subtle |
--vx-info-muted | 165 243 252 | 12 74 110 | bg-info-muted |
Layout Constants
| Token | Value | Description |
|---|
--page-bg | rgb(var(--vx-surface-subtle)) | Page background (light) |
--page-bg-dark | rgb(var(--neutral-950)) | Page background (dark) |
--header-height | 60px | Top header height |
--sidebar-width | 270px | Sidebar width |
--radius | 0.5rem | Base border radius |
Spacing Scale (4px grid)
| Token | Value | Tailwind Class |
|---|
--space-0 | 0px | p-space-0, m-space-0, gap-space-0 |
--space-1 | 4px | p-space-1, m-space-1, gap-space-1 |
--space-2 | 8px | p-space-2, etc. |
--space-3 | 12px | p-space-3, etc. |
--space-4 | 16px | p-space-4, etc. |
--space-5 | 20px | p-space-5, etc. |
--space-6 | 24px | p-space-6, etc. |
--space-8 | 32px | p-space-8, etc. |
--space-10 | 40px | p-space-10, etc. |
--space-12 | 48px | p-space-12, etc. |
--space-16 | 64px | p-space-16, etc. |
Shadows
| Token | Value | Tailwind Class |
|---|
--shadow-sm | 0 1px 2px 0 rgb(0 0 0 / 0.05) | shadow-sm |
--shadow-md | 0 4px 6px -1px rgb(0 0 0 / 0.1) | shadow-md |
--shadow-lg | 0 10px 15px -3px rgb(0 0 0 / 0.1) | shadow-lg |
Animation Timings
| Token | Value | Tailwind Class |
|---|
--transition-fast | 150ms | duration-fast |
--transition-base | 200ms | duration-base |
--transition-slow | 300ms | duration-slow |
Easing Functions
| Token | Value | Tailwind Class |
|---|
--ease-out | cubic-bezier(0.16, 1, 0.3, 1) | ease-out |
--ease-in-out | cubic-bezier(0.65, 0, 0.35, 1) | ease-in-out |
--ease-default | cubic-bezier(0.25, 1, 0.5, 1) | ease-default |
Border Radius
| Tailwind Class | Computed Value |
|---|
rounded-xl | calc(var(--radius) + 4px) = 0.75rem |
rounded-lg | var(--radius) = 0.5rem |
rounded-md | calc(var(--radius) - 2px) = 0.375rem |
rounded-sm | calc(var(--radius) - 4px) = 0.25rem |
Custom Text Sizes
| Tailwind Class | Size |
|---|
text-2sm | 0.8125rem (13px) |
text-2xs | 0.6875rem (11px) |
Dark Mode Mechanism
Dark mode is activated by either:
.dark class on a parent element
[data-theme="dark"] attribute
The custom variant is defined as: @custom-variant dark (&:where(.dark, .dark *));
All semantic tokens are overridden inside .dark, [data-theme="dark"] selector. Theme transitions use 200ms duration with cubic-bezier(0.25, 1, 0.5, 1) easing on color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, and box-shadow.
Component CSS Classes
| Class | Description |
|---|
.layout-wrapper | Root flex container, min-height: 100dvh |
.vextro-sidebar | Sidebar shell, width: var(--sidebar-width) |
.layout-sidebar | Desktop sidebar (hidden on mobile) |
.layout-header | Mobile header (hidden on desktop) |
.main-wrapper | Main content flex container |
.content-card | White card surface with border and rounded corners |
.content-scroll | Scrollable content area with thin scrollbar |
.kt-scrollable-y-auto | Scrollable utility with custom scrollbar styling |
Override Patterns
To customize the token system in your app, override CSS custom properties after importing Vextro’s stylesheet:
/* app/src/styles/global.css */
@import "vextro/styles/vextro.css";
:root {
/* Change the accent color to green */
--vx-primary-rgb: 22 163 74;
--vx-primary-hover: 21 128 61;
--vx-primary-active: 20 83 45;
--vx-primary-subtle: 240 253 244;
--vx-primary-muted: 187 247 208;
/* Increase sidebar width */
--sidebar-width: 300px;
}
.dark,
[data-theme="dark"] {
--vx-primary-rgb: 34 197 94;
--vx-primary-hover: 74 222 128;
--vx-primary-active: 22 163 74;
--vx-primary-subtle: 5 46 22;
--vx-primary-muted: 22 101 52;
}
Best Practices
- To ensure dark mode compatibility, use semantic tokens (
--vx-fg, --vx-surface, etc.) instead of hardcoded hex or rgb colors.
- Avoid CSS variable fallbacks with light-mode defaults (e.g.,
var(--color, #f3f4f6)) — if a token is missing, add it to the token system instead.
- Prefer Tailwind semantic classes (
text-fg, bg-surface, border-edge) over fixed Tailwind colors (text-gray-500, bg-white).
- In scoped
<style> blocks, reference tokens as rgb(var(--vx-fg)), rgb(var(--vx-surface)), etc.
- SVG data URIs with embedded colors should include
.dark class overrides for the alternate palette.
- For opacity support, use the
rgb(var(--vx-fg) / 0.5) format since all tokens store space-separated RGB values.
- Components should be verified in both light and dark mode to ensure full theme compatibility.