Skip to content
VEXA

Theming

Three themes ship from one semantic token contract. Colors are HSL triplets exposed as CSS custom properties, so they work with or without Tailwind.

Live theme playground

Switch the theme applied to these previews in real time. Only this surface changes — the rest of the page keeps your chosen theme.

ActivePendingFailedOutline

Live theming

Every surface re-resolves its tokens instantly.

Invoice #A-2291

Due in 14 days

€4,820.00
SentNet 14

Semantic HSL tokens

Every visual decision goes through a --vexa-* token. Never hardcode a color; never repeat a raw value.

Values are stored as space-separated HSL triplets ("H S% L%") so one token drives solid fills, translucent overlays, and rings via hsl(var(--token) / <alpha>). In Tailwind v4 the tokens map to utilities like bg-vexa-surface, text-vexa-foreground, and border-vexa-border.

tokens
/* Plain CSS — HSL triplet + alpha */
.cta {
  background: hsl(var(--vexa-primary));
  color: hsl(var(--vexa-primary-foreground));
  border-color: hsl(var(--vexa-border) / 0.6);
}

/* Tailwind v4 — mapped utilities */
<div class="rounded-vexa-md border border-vexa-border bg-vexa-surface text-vexa-foreground" />

The three themes

Light is the default at :root. The dark themes activate through a single data attribute on <html> (or any scoped element).

  • LightNeutral, editorial, high clarity.
    Default at :root — no attribute needed.
  • ObsidianNear-black, low-emission, high contrast.
    data-theme="obsidian"
  • GraphiteBalanced dark-gray surfaces for dense tools.
    data-theme="graphite"

Token reference (Obsidian)

The semantic color tokens resolved in the default Obsidian theme. Foreground/background pairs are validated against WCAG 2.2 AA.

--vexa-background
--vexa-foreground
--vexa-surface
--vexa-surface-raised
--vexa-muted
--vexa-muted-foreground
--vexa-border
--vexa-input
--vexa-primary
--vexa-primary-foreground
--vexa-secondary
--vexa-secondary-foreground
--vexa-accent
--vexa-accent-foreground
--vexa-success
--vexa-success-foreground
--vexa-warning
--vexa-warning-foreground
--vexa-danger
--vexa-danger-foreground
--vexa-focus
--vexa-ring

Customize

Because tokens are plain CSS variables, you override them per product without touching component source. Redefine a token at :root or under a [data-theme] block and every primitive follows.

css
/* Override tokens per product — no component edits needed. */
:root {
  --vexa-primary: 262 60% 45%; /* your brand ink */
}

[data-theme="obsidian"] {
  --vexa-primary: 262 70% 66%;
}
Keep meaning out of color alone, and re-validate contrast after any change — VEXA ships a check-contrast script for exactly this.