Theming

Customize colors, border radius, and typography by overriding CSS variables — no build step, no config files, no forks required.


Preview

Pick a preset accent color or pick your own to see how it applies across components in real time. The preview follows the current site theme — switch themes from the top nav to see how your accent looks in both light and dark mode.

NewAI-readyStable
GP
Project settingsConfigure your workspace below.
Completion72%
--vyre-color-semantic-accent#7c3aed
--vyre-color-semantic-accent-hover#6d28d9
--vyre-color-semantic-accent-foreground#ffffff
--vyre-color-semantic-accent-subtle#f5f3ff
--vyre-color-semantic-accent-subtle-border#ddd6fe

How it works

Every useVyre component reads from semantic CSS variables (--vyre-color-semantic-*). Because CSS custom properties cascade normally, any variable you define after the tokens import overrides the default — and every component instantly reflects the change.

/* 1. useVyre ships its tokens */
import "@usevyre/tokens/css";

/* 2. After that import, override any token in your own CSS */
/* globals.css (or wherever you import tokens) */
:root {
  --vyre-color-semantic-accent:               #2563eb;
  --vyre-color-semantic-accent-hover:         #1d4ed8;
  --vyre-color-semantic-accent-foreground:    #ffffff;
  --vyre-color-semantic-accent-subtle:        #eff6ff;
  --vyre-color-semantic-accent-subtle-border: #dbeafe;
}
Order matters. Your overrides must come after @import "@usevyre/tokens/css" (or after import "@usevyre/tokens/css" in your JS entry). Otherwise the defaults win.

Customizing the accent color

The accent is used by Button (primary), Badge (accent), focus rings, and any component that highlights a selected or active state. There are five tokens to override — all five must be set to keep hover, foreground, and badge states consistent.

Token Used for
--vyre-color-semantic-accent Primary fill — button background, link color, focus ring
--vyre-color-semantic-accent-hover Darker shade shown on hover/active states
--vyre-color-semantic-accent-foreground Text color rendered on top of accent background
--vyre-color-semantic-accent-subtle Very low-opacity tint — badge/chip backgrounds
--vyre-color-semantic-accent-subtle-border Border color for subtle accent containers

Blue

/* globals.css — after @import "@usevyre/tokens/css" */
:root {
  --vyre-color-semantic-accent:               #2563eb;
  --vyre-color-semantic-accent-hover:         #1d4ed8;
  --vyre-color-semantic-accent-foreground:    #ffffff;
  --vyre-color-semantic-accent-subtle:        #eff6ff;
  --vyre-color-semantic-accent-subtle-border: #dbeafe;
}

[data-theme="dark"] {
  --vyre-color-semantic-accent:               #60a5fa;
  --vyre-color-semantic-accent-hover:         #93c5fd;
  --vyre-color-semantic-accent-foreground:    #09090b;
  --vyre-color-semantic-accent-subtle:        rgba(96, 165, 250, 0.12);
  --vyre-color-semantic-accent-subtle-border: rgba(96, 165, 250, 0.25);
}

Green

/* globals.css — after @import "@usevyre/tokens/css" */
:root {
  --vyre-color-semantic-accent:               #16a34a;
  --vyre-color-semantic-accent-hover:         #15803d;
  --vyre-color-semantic-accent-foreground:    #ffffff;
  --vyre-color-semantic-accent-subtle:        #f0fdf4;
  --vyre-color-semantic-accent-subtle-border: #dcfce7;
}

[data-theme="dark"] {
  --vyre-color-semantic-accent:               #4ade80;
  --vyre-color-semantic-accent-hover:         #86efac;
  --vyre-color-semantic-accent-foreground:    #09090b;
  --vyre-color-semantic-accent-subtle:        rgba(74, 222, 128, 0.12);
  --vyre-color-semantic-accent-subtle-border: rgba(74, 222, 128, 0.25);
}

Rose

/* globals.css — after @import "@usevyre/tokens/css" */
:root {
  --vyre-color-semantic-accent:               #e11d48;
  --vyre-color-semantic-accent-hover:         #be123c;
  --vyre-color-semantic-accent-foreground:    #ffffff;
  --vyre-color-semantic-accent-subtle:        #fff1f2;
  --vyre-color-semantic-accent-subtle-border: #fecdd3;
}

[data-theme="dark"] {
  --vyre-color-semantic-accent:               #fb7185;
  --vyre-color-semantic-accent-hover:         #fda4af;
  --vyre-color-semantic-accent-foreground:    #09090b;
  --vyre-color-semantic-accent-subtle:        rgba(251, 113, 133, 0.12);
  --vyre-color-semantic-accent-subtle-border: rgba(251, 113, 133, 0.25);
}

Custom dark mode surface

By default the dark theme uses zinc-based neutrals. If your brand uses slate, gray, or a custom neutral palette, override the surface tokens under [data-theme="dark"].

/* Custom dark mode surface — e.g. slate instead of zinc */
[data-theme="dark"] {
  --vyre-color-semantic-background:     #0f172a; /* slate-950 */
  --vyre-color-semantic-surface:        #1e293b; /* slate-800 */
  --vyre-color-semantic-surface-raised: #334155; /* slate-700 */
  --vyre-color-semantic-surface-overlay:#475569; /* slate-600 */
  --vyre-color-semantic-border:         #334155;
  --vyre-color-semantic-border-subtle:  #1e293b;
  --vyre-color-semantic-border-strong:  #64748b;
}

Border radius

Override the radius scale globally. All components reference these tokens, so changing them here affects every component at once.

/* Sharp — no rounded corners */
:root {
  --vyre-border-radius-sm:   0;
  --vyre-border-radius-md:   0;
  --vyre-border-radius-lg:   0;
  --vyre-border-radius-xl:   0;
  --vyre-border-radius-2xl:  0;
  --vyre-border-radius-full: 0;
}

/* Rounder — softer look */
:root {
  --vyre-border-radius-sm:  0.5rem;   /* was 0.375rem */
  --vyre-border-radius-md:  0.75rem;  /* was 0.5rem   */
  --vyre-border-radius-lg:  1rem;     /* was 0.75rem  */
  --vyre-border-radius-xl:  1.25rem;  /* was 1rem     */
  --vyre-border-radius-2xl: 2rem;     /* was 1.5rem   */
}

Typography

useVyre ships with Geist loaded from Google Fonts. To use your own typeface, override the font-family tokens. The fonts themselves must be loaded separately (via <link>, a local @font-face, or a font provider).

/* Replace Geist with your own font */
:root {
  --vyre-typography-font-family-display: 'Inter', system-ui, sans-serif;
  --vyre-typography-font-family-body:    'Inter', system-ui, sans-serif;
  --vyre-typography-font-family-mono:    'Fira Code', monospace;
}

AI context for custom themes

When you override tokens, update your AI context file so agents generate CSS that matches your theme — not the default violet. Add a THEMING block to your CLAUDE.md or .cursor/rules:

You are working in a project that uses useVyre design system.

THEMING:
The project overrides useVyre's default accent (violet) with blue.
After "@usevyre/tokens/css" is imported, globals.css sets:
  --vyre-color-semantic-accent:               #2563eb  (light)
  --vyre-color-semantic-accent-hover:         #1d4ed8  (light)
  --vyre-color-semantic-accent-foreground:    #ffffff
  --vyre-color-semantic-accent-subtle:        #eff6ff
  --vyre-color-semantic-accent-subtle-border: #dbeafe
  [dark] --vyre-color-semantic-accent:        #60a5fa
  [dark] --vyre-color-semantic-accent-hover:  #93c5fd

Use these tokens in any custom CSS you write. Do NOT hardcode #7c3aed or #a78bfa.
Why this matters: Without this block, agents writing custom CSS will hardcode #7c3aed (the default violet) instead of using your overridden token. The THEMING block tells the agent which values are in effect at runtime.