Components
Theming & styling
Your own colours from a few settings, readable in dark and light for any hue; and className overrides that always win.
Violet
Ocean
Teal
Forest
Amber
Rose
Graphite
Intensity
GroceriesOn track
September$420 / $600
$180 left
Import
import { applyTheme, applyPreset, customize, PRESETS, DEFAULT_THEME, themeVars, cx } from '@rinzai/zen';Examples
Stylesheet
No script needed: themeVars gives the tokens as data, so a theme can be written into a stylesheet at build time or on the server.
PresetTeal Amber
:root, .dark {
--background: 0.155 0.014 195;
--foreground: 0.97 0.004 195;
--card: 0.195 0.014 195;
--card-foreground: 0.97 0.004 195;
--popover: 0.21 0.014 195;
--popover-foreground: 0.97 0.004 195;
--secondary: 0.25 0.014 195;
--secondary-foreground: 0.97 0.004 195;
--muted: 0.235 0.014 195;
--muted-foreground: 0.72 0.021 195;
--border: 0.28 0.021 195;
--input: 0.28 0.021 195;
--primary: 0.72 0.13 195;
--primary-foreground: 0.17 0.03 195;
--accent: 0.3 0.046 195;
--accent-foreground: 0.88 0.065 195;
--ring: 0.72 0.13 195;
--destructive: 0.64 0.2 25;
--destructive-foreground: 0.985 0 0;
--glow: 0.7 0.13 195;
--glow-2: 0.72 0.098 225;
--tint: 1 0 0;
--glow-strength: 0.55;
--topo-strength: 0.55;
}
.light {
--background: 0.985 0.006 195;
--foreground: 0.21 0.02 195;
--card: 1 0 0;
--card-foreground: 0.21 0.02 195;
--popover: 1 0 0;
--popover-foreground: 0.21 0.02 195;
--secondary: 0.955 0.008 195;
--secondary-foreground: 0.21 0.02 195;
--muted: 0.96 0.007 195;
--muted-foreground: 0.5 0.021 195;
--border: 0.91 0.011 195;
--input: 0.91 0.011 195;
--primary: 0.48 0.195 195;
--primary-foreground: 0.985 0 0;
--accent: 0.95 0.033 195;
--accent-foreground: 0.42 0.117 195;
--ring: 0.48 0.195 195;
--destructive: 0.55 0.22 25;
--destructive-foreground: 0.985 0 0;
--glow: 0.62 0.182 195;
--glow-2: 0.65 0.137 225;
--tint: 0.21 0.02 195;
--glow-strength: 0.4;
--topo-strength: 0.55;
}Overrides
className always wins: when it sets something a component already sets (size, padding, radius, colour…), the component's default is dropped. Your own components get the same with cx.
cx('px-3 py-1 rounded-lg', 'p-4 rounded-full') → p-4 rounded-full