Colors Color palettes, semantic mappings, and dark mode support in Unified UI.
Unified UI uses a two-tier color system:
Base palettes — Raw color ramps from 50 → 950 (inspired by Tailwind's palette structure).
Semantic mappings — Intent-based aliases (primary, danger, success, etc.) that map to specific palette stops for light and dark modes.
All color values are stored as oklch() strings (e.g. "oklch(0.205 0 0)") for perceptual uniformity and wide-gamut display support. Tailwind's opacity modifier syntax works directly: bg-primary/50.
Components never reference base palette values directly. They use semantic
tokens through CSS custom properties (--primary, --danger, etc.), which
the theme layer resolves to the correct value for the active mode.
Each palette provides 11 stops from 50 (lightest) to 950 (darkest). All values use the oklch() color space.
The primary identity palette, based on an indigo scale. Used for primary actions, links, and focus states.
Stop Value Preview 50 oklch(0.962 0.018 272.314)100 oklch(0.93 0.034 272.788)200 oklch(0.87 0.065 274.039)300 oklch(0.785 0.115 274.713)400 oklch(0.673 0.182 276.935)500 oklch(0.585 0.233 277.117)600 oklch(0.511 0.262 276.966)700 oklch(0.457 0.24 277.023)800 oklch(0.398 0.195 277.366)900 oklch(0.359 0.144 278.697)950 oklch(0.257 0.09 281.288)
The workhorse palette for text, borders, backgrounds, and surfaces. Uses a pure achromatic zinc scale (zero chroma).
Stop Value Preview 50 oklch(0.985 0 0)100 oklch(0.97 0 0)200 oklch(0.922 0 0)300 oklch(0.87 0 0)400 oklch(0.708 0 0)500 oklch(0.556 0 0)600 oklch(0.439 0 0)700 oklch(0.371 0 0)800 oklch(0.269 0 0)900 oklch(0.205 0 0)950 oklch(0.145 0 0)
Unified UI ships 18 palettes in total. Beyond Brand and Zinc (Neutral), the following are available for semantic and decorative use:
Palette Purpose Key stops used Preview (500) Slate Cool neutral alternative Backgrounds, surfaces Gray True gray neutral Backgrounds, surfaces Blue Information, links info semantic colorGreen Success, confirmation success semantic colorAmber Warnings, caution warning semantic colorRed Errors, destructive actions danger semantic colorTeal Accent, decorative Illustrations, charts Indigo Brand-aligned accent Badges, highlights Purple Creative, premium features Tags, decorative accents Pink Social, engagement Notifications, reactions Cyan Data visualization Charts, metrics Emerald Nature, growth themes Progress indicators Yellow Highlights, attention Callouts, badges Fuchsia Creative, playful accents Marketing, gradients Sky Light informational Backgrounds, status badges Lime Positive, fresh accents Eco themes, progress bars
import {
brand,
blue,
green,
amber,
red,
teal,
neutral,
palettes,
} from "@work-rjkashyap/unified-ui/tokens" ;
// Individual palette
console. log (brand[ 600 ]); // "oklch(0.511 0.262 276.966)"
// All palettes bundled (useful for tooling / documentation)
console. log (Object. keys (palettes));
// ["slate", "gray", "zinc", "brand", "blue", "green", "amber", "red",
// "teal", "indigo", "purple", "pink", "cyan", "emerald", "yellow",
// "fuchsia", "sky", "lime"]
Semantic colors map intent to specific values. This indirection means you can rebrand the entire system by changing the semantic mapping — components never need to change.
The current default theme uses achromatic (neutral) values for primary/secondary to create a clean, minimal aesthetic. Status colors (success, warning, danger, info) use chromatic palettes for clear intent signaling.
Light Mode Dark Mode
Token Value Tailwind class Use case backgroundoklch(1 0 0)bg-backgroundPage background foregroundoklch(0.145 0 0)text-foregroundDefault text color surfaceoklch(0.985 0 0)bg-surfaceSubtle surface background surfaceRaisedoklch(1 0 0)bg-surface-raisedCards, elevated surfaces surfaceOverlayoklch(0.97 0 0)bg-surface-overlayOverlay backgrounds mutedoklch(0.97 0 0)bg-mutedMuted backgrounds mutedForegroundoklch(0.556 0 0)text-muted-foregroundSecondary text
Token Value Tailwind class Use case cardoklch(1 0 0)bg-cardCard backgrounds cardForegroundoklch(0.145 0 0)text-card-foregroundCard text popoveroklch(1 0 0)bg-popoverPopover backgrounds popoverForegroundoklch(0.145 0 0)text-popover-foregroundPopover text
Token Value Tailwind class Use case primaryoklch(0.205 0 0)bg-primaryPrimary buttons, links primaryForegroundoklch(0.985 0 0)text-primary-foregroundText on primary bg primaryHoveroklch(0.295 0 0)— Hover state primaryActiveoklch(0.371 0 0)— Active/pressed state primaryMutedoklch(0.97 0 0)bg-primary-mutedSoft primary background primaryMutedForegroundoklch(0.205 0 0)text-primary-muted-foregroundText on muted primary
Token Value Tailwind class Use case secondaryoklch(0.97 0 0)bg-secondarySecondary buttons secondaryForegroundoklch(0.205 0 0)text-secondary-foregroundText on secondary bg secondaryHoveroklch(0.922 0 0)— Hover state secondaryActiveoklch(0.87 0 0)— Active/pressed state
Token Value Tailwind class Use case accentoklch(0.97 0 0)bg-accentAccent backgrounds accentForegroundoklch(0.205 0 0)text-accent-foregroundAccent text
Intent Base Foreground Muted Muted Foreground Success green.600oklch(0.145 0 0)green.50green.700Warning amber.500oklch(0.145 0 0)amber.50amber.700Danger red.600oklch(0.985 0 0)red.50red.700Info blue.600oklch(0.985 0 0)blue.50blue.700
Token Value Tailwind class Use case borderoklch(0.922 0 0)border-borderDefault borders borderMutedoklch(0.97 0 0)border-border-mutedSubtle borders borderStrongoklch(0.708 0 0)border-border-strongEmphasized borders focusRingoklch(0.708 0 0)ring-focus-ringFocus indicators ringoklch(0.708 0 0)ring-ringGeneric ring color inputoklch(0.922 0 0)border-inputInput field borders inputForegroundoklch(0.205 0 0)text-input-foregroundInput text color inputPlaceholderoklch(0.556 0 0)— Placeholder text
Token Value Use case disabledoklch(0.97 0 0)Disabled backgrounds disabledForegroundoklch(0.556 0 0)Disabled text
Token Value Tailwind class Use case backgroundoklch(0.145 0 0)bg-backgroundPage background foregroundoklch(0.985 0 0)text-foregroundDefault text color surfaceoklch(0.205 0 0)bg-surfaceSubtle surface background surfaceRaisedoklch(0.269 0 0)bg-surface-raisedCards, elevated surfaces surfaceOverlayoklch(0.269 0 0)bg-surface-overlayOverlay backgrounds mutedoklch(0.269 0 0)bg-mutedMuted backgrounds mutedForegroundoklch(0.708 0 0)text-muted-foregroundSecondary text
Token Value Tailwind class Use case cardoklch(0.205 0 0)bg-cardCard backgrounds cardForegroundoklch(0.985 0 0)text-card-foregroundCard text popoveroklch(0.269 0 0)bg-popoverPopover backgrounds popoverForegroundoklch(0.985 0 0)text-popover-foregroundPopover text
Token Value Tailwind class Dark mode note primaryoklch(0.922 0 0)bg-primaryLight value on dark bg for contrast primaryForegroundoklch(0.205 0 0)text-primary-foregroundDark text on light primary primaryHoveroklch(0.845 0 0)— Slightly darker on hover primaryActiveoklch(0.768 0 0)— Darker on active primaryMutedoklch(0.269 0 0)bg-primary-mutedVery dark muted primary primaryMutedForegroundoklch(0.922 0 0)text-primary-muted-foregroundLight text on dark muted
Token Value Tailwind class Use case secondaryoklch(0.269 0 0)bg-secondarySecondary buttons secondaryForegroundoklch(0.985 0 0)text-secondary-foregroundText on secondary bg secondaryHoveroklch(0.371 0 0)— Hover state secondaryActiveoklch(0.439 0 0)— Active/pressed state
Token Value Tailwind class Use case accentoklch(0.371 0 0)bg-accentAccent backgrounds accentForegroundoklch(0.985 0 0)text-accent-foregroundAccent text
Intent Base Foreground Muted Muted Foreground Success green.500oklch(0.145 0 0)green.950green.300Warning amber.400oklch(0.145 0 0)amber.950amber.300Danger red.500oklch(0.985 0 0)red.950red.300Info blue.400oklch(0.145 0 0)blue.950blue.300
Token Value Tailwind class Use case borderoklch(1 0 0 / 10%)border-borderDefault borders borderMutedoklch(0.269 0 0)border-border-mutedSubtle borders borderStrongoklch(0.556 0 0)border-border-strongEmphasized borders focusRingoklch(0.556 0 0)ring-focus-ringFocus indicators ringoklch(0.556 0 0)ring-ringGeneric ring color inputoklch(1 0 0 / 15%)border-inputInput field borders inputForegroundoklch(0.985 0 0)text-input-foregroundInput text color inputPlaceholderoklch(0.556 0 0)— Placeholder text
Token Value Use case disabledoklch(0.269 0 0)Disabled backgrounds disabledForegroundoklch(0.439 0 0)Disabled text
Both light and dark modes define dedicated tokens for data visualization and sidebar UI.
Light Mode Dark Mode
Token Value Use case chart1oklch(0.646 0.222 41.116)Primary data series chart2oklch(0.6 0.118 184.704)Secondary data series chart3oklch(0.398 0.07 227.392)Tertiary data series chart4oklch(0.828 0.189 84.429)Quaternary data series chart5oklch(0.769 0.188 70.08)Quinary data series
Token Value Use case sidebaroklch(0.985 0 0)Sidebar background sidebarForegroundoklch(0.145 0 0)Sidebar text sidebarPrimaryoklch(0.205 0 0)Sidebar primary accent sidebarPrimaryForegroundoklch(0.985 0 0)Text on sidebar primary sidebarAccentoklch(0.97 0 0)Sidebar accent background sidebarAccentForegroundoklch(0.205 0 0)Sidebar accent text sidebarBorderoklch(0.922 0 0)Sidebar borders sidebarRingoklch(0.708 0 0)Sidebar focus ring
Token Value Use case chart1oklch(0.488 0.243 264.376)Primary data series chart2oklch(0.696 0.17 162.48)Secondary data series chart3oklch(0.769 0.188 70.08)Tertiary data series chart4oklch(0.627 0.265 303.9)Quaternary data series chart5oklch(0.645 0.246 16.439)Quinary data series
Token Value Use case sidebaroklch(0.205 0 0)Sidebar background sidebarForegroundoklch(0.985 0 0)Sidebar text sidebarPrimaryoklch(0.488 0.243 264.376)Sidebar primary accent sidebarPrimaryForegroundoklch(0.985 0 0)Text on sidebar primary sidebarAccentoklch(0.269 0 0)Sidebar accent background sidebarAccentForegroundoklch(0.985 0 0)Sidebar accent text sidebarBorderoklch(1 0 0 / 10%)Sidebar borders sidebarRingoklch(0.439 0 0)Sidebar focus ring
All semantic color pairings are designed to meet WCAG AA contrast requirements:
Normal text (< 18px or < 14px bold): 4.5:1 minimum contrast ratio
Large text (≥ 18px or ≥ 14px bold): 3:1 minimum contrast ratio
Non-text elements (borders, icons, form controls): 3:1 minimum per SC 1.4.11
Light mode uses a near-black primary (oklch(0.205 0 0)) on white for maximum contrast — a clean monochrome aesthetic.
Dark mode inverts this relationship with a near-white primary (oklch(0.922 0 0)) on a dark background.
Status colors use darker stops (600) in light mode and lighter stops (400–500) in dark mode to maintain legibility against their respective backgrounds.
Disabled states exceed WCAG requirements (which exempt disabled controls) with a ≥ 3:1 target for usability.
Unified UI ships a contrast-checking utility you can use in tests or at build time:
import {
checkHexContrast,
meetsAA,
contrastRatio,
} from "@work-rjkashyap/unified-ui/utils" ;
// Check a specific pair
const result = checkHexContrast ( "#4F46E5" , "#FFFFFF" );
console. log (result.ratio); // 6.35
console. log (result.aa); // true (normal text)
console. log (result.aaLarge); // true (large text)
// Quick boolean check
console. log ( meetsAA ( 6.35 , "normal" )); // true
// Raw ratio calculation
console. log ( contrastRatio ( "#000000" , "#FFFFFF" )); // 21
import {
auditContrast,
DS_LIGHT_CRITICAL_PAIRS,
DS_DARK_CRITICAL_PAIRS,
} from "@work-rjkashyap/unified-ui/utils" ;
// Audit all critical light mode pairs
const lightResults = auditContrast ( DS_LIGHT_CRITICAL_PAIRS );
const failures = lightResults. filter (( r ) => ! r.passes);
if (failures. length > 0 ) {
console. error ( "Contrast failures:" , failures);
}
// Page background with default text
< div className = "bg-background text-foreground" >
< h1 >Page Title</ h1 >
< p className = "text-muted-foreground" >Secondary description text</ p >
</ div >
// Card surface
< div className = "bg-surface-raised border border-border rounded-md p-4" >
Card content
</ div >
// Success alert
< div className = "bg-success-muted text-success-muted-foreground" >
Operation completed successfully.
</ div >
// Danger button
< button className = "bg-danger text-danger-foreground hover:bg-danger/90" >
Delete
</ button >
// Warning badge
< span className = "bg-warning-muted text-warning-muted-foreground" >
Caution
</ span >
Because color values are complete oklch() values, you can use Tailwind's opacity modifier syntax directly:
// 50% opacity primary background
< div className = "bg-primary/50" />
// 20% opacity border
< div className = "border border-border/20" />
// 80% opacity text
< p className = "text-foreground/80" >Slightly transparent text</ p >
All semantic colors are available as CSS variables for use in custom styles. Values are complete oklch() colors — use them directly:
.custom-element {
background-color : var ( --primary );
color : var ( --primary-foreground );
border-color : var ( --border );
}
/* With opacity via oklch alpha */
.custom-overlay {
background-color : oklch (from var ( --primary ) l c h / 0.1 );
}
// Semantic mappings (what components use)
import { semanticLight, semanticDark } from "@work-rjkashyap/unified-ui/tokens" ;
console. log (semanticLight.primary); // "oklch(0.205 0 0)"
console. log (semanticDark.primary); // "oklch(0.922 0 0)"
// Raw palettes (for tooling, docs, custom themes)
import {
brand,
blue,
green,
amber,
red,
neutral,
} from "@work-rjkashyap/unified-ui/tokens" ;
console. log (brand[ 600 ]); // "oklch(0.511 0.262 276.966)"
console. log (red[ 500 ]); // "oklch(0.704 0.191 22.216)"
console. log (neutral[ 100 ]); // "oklch(0.97 0 0)"
// All palettes bundled
import { palettes } from "@work-rjkashyap/unified-ui/tokens" ;
// Includes: slate, gray, zinc, brand, blue, green, amber, red,
// teal, indigo, purple, pink, cyan, emerald, yellow, fuchsia, sky, lime
Don't use raw palette values in components. Always use the semantic
tokens (bg-primary, not a hardcoded oklch value). Semantic tokens
automatically adapt to light/dark mode and can be rebranded without touching
component code.