Customization
foxui is designed to be opinionated by default but easy to customize. Colors, border radius, and fonts can all be changed with CSS variables — no build step required.
Colors
foxui uses two color scales: base (neutrals) and accent (brand color). The default is pink accent on stone base.
Switching colors
Add a color class to any element to retheme it and all its children:
<!-- Change accent color --> <div class="blue"> <Button>Now blue</Button> <Badge>Also blue</Badge> </div> <!-- Change base color --> <div class="zinc"> <Button variant="secondary">Zinc neutral</Button> </div>
Available accent colors: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose
Available base colors: gray, zinc, neutral, stone, slate, taupe, mist, olive, mauve
Theme Picker
Try it out — pick an accent and base color:
Accent Color
Base Color
Changing globally
To change the color for your entire app, add the class to your <html> or <body> element:
<html class="__ACCENT__ __BASE__">
Custom colors
Override the CSS variables directly for full control:
:root { --accent-500: oklch(0.65 0.2 250); /* set all shades 50-950 for best results */ }
Border Radius
All components use three radius tokens that you can override:
--ui-radius—1rem(16px) — Buttons, inputs, cards, boxes--ui-radius-lg—1.25rem(20px) — Modals, sidebars, large containers--ui-radius-sm—0.75rem(12px) — Inner elements, menu items, small controls
Changing globally
:root { --ui-radius: 0.5rem; --ui-radius-lg: 0.75rem; --ui-radius-sm: 0.25rem; }
Using presets
Add a class to any ancestor element:
<!-- Sharp corners --> <div class="sharp"> <Button>Sharp</Button> </div> <!-- Fully rounded (pill) --> <div class="pill"> <Button>Pill</Button> </div>
Scoped overrides
Like colors, radius can be scoped to any subtree:
<Button>Default radius</Button> <div class="sharp"> <Button>Sharp radius</Button> <Badge>Also sharp</Badge> </div>
Fonts
foxui ships with Geist as the default font. You can change fonts two ways: apply a preset class, or define your own.
Using presets
Add a class to any ancestor element to scope the font — same pattern as colors and radius:
<!-- Default (Geist) --> <Button>Geist</Button> <!-- Use system fonts --> <div class="system-font"> <Button>System font</Button> </div> <!-- Use a serif --> <div class="serif-font"> <Button>Serif</Button> </div> <!-- Use a monospace font everywhere --> <div class="mono-font"> <Button>Mono</Button> </div>
Built-in presets: geist (default), system-font, serif-font, mono-font
Defining your own font class
Create a class that sets the font variables — works anywhere in the DOM tree:
@import '@fontsource-variable/inter'; .inter { --ui-font-sans: 'Inter Variable', sans-serif; }
Then use it like any other class:
<div class="inter"> <Button>Inter font</Button> <Badge>Also Inter</Badge> </div>
Changing globally
To change the default font for your entire app, override the variables on :root or add the class to <html>:
/* via CSS variable */ :root { --ui-font-sans: 'My Custom Font', sans-serif; }
<!-- via class --> <html class="system-font">
The variables
--ui-font-sans— Body text, UI elements (default: Geist)--ui-font-mono— Code blocks, monospace text (default: Geist Mono)
Combining customizations
All customization layers compose together:
<!-- Blue accent, sharp corners, custom font --> <div class="blue sharp"> <Button>Fully customized</Button> </div>
:root { --ui-font-sans: 'My Custom Font', sans-serif; --ui-radius: 0.5rem; --ui-radius-lg: 0.75rem; --ui-radius-sm: 0.25rem; }