Customize SoftUI to match your brand by overriding CSS custom properties. No build tools needed.
SoftUI is built entirely on CSS custom properties (--sui-*). Override them on :root to change the look of every component at once.
:root {
--sui-primary: #7C5CFC; /* Your brand color */
--sui-radius: 12px; /* Sharper or rounder corners */
--sui-font: 'Inter', sans-serif; /* Your font */
}
That's it. Every button, card, input, and component will update automatically.
The color system has 5 semantic colors, each with a hover variant.
:root {
/* Primary — buttons, links, active states */
--sui-primary: #5B54E0;
--sui-primary-hover: #4A44C4;
/* Success — confirmations, positive actions */
--sui-success: #1FA96E;
--sui-success-hover: #178A59;
/* Danger — errors, destructive actions */
--sui-danger: #D03A5C;
--sui-danger-hover: #B42E4C;
/* Warning — caution, pending states */
--sui-warning: #F5A623;
--sui-warning-hover: #DB921A;
/* Info — informational, neutral highlights */
--sui-info: #1A82D4;
--sui-info-hover: #146BAE;
}
Three background shades create the neumorphic depth. bg is the base, bg-light is slightly lighter, bg-dark is slightly darker.
:root {
--sui-bg: #E4E9F0; /* Base surface */
--sui-bg-light: #EDF1F7; /* Lighter (raised highlights) */
--sui-bg-dark: #D1D9E6; /* Darker (borders, tracks) */
}
These three values work together to create the soft shadow illusion. When changing them, keep them close in tone — the effect breaks if they're too far apart.
Neumorphic shadows use two colors: a dark shadow (bottom-right) and a light shadow (top-left). These are combined into preset shadow values.
:root {
/* Shadow colors */
--sui-shadow-light: #FFFFFF;
--sui-shadow-dark: #B8C0CC;
/* Raised (outward) shadows */
--sui-shadow-raised-sm: 3px 3px 8px var(--sui-shadow-dark),
-3px -3px 8px var(--sui-shadow-light);
--sui-shadow-raised: 6px 6px 14px var(--sui-shadow-dark),
-6px -6px 14px var(--sui-shadow-light);
--sui-shadow-raised-lg: 10px 10px 20px var(--sui-shadow-dark),
-10px -10px 20px var(--sui-shadow-light);
/* Inset (pressed) shadows */
--sui-shadow-inset: inset 3px 3px 8px var(--sui-shadow-dark),
inset -3px -3px 8px var(--sui-shadow-light);
--sui-shadow-inset-sm: inset 2px 2px 5px var(--sui-shadow-dark),
inset -2px -2px 5px var(--sui-shadow-light);
}
/* Tip: just changing --sui-shadow-light and --sui-shadow-dark
updates ALL shadows automatically */
Three text color tiers for hierarchy.
:root {
--sui-text: #2D3748; /* Primary text — headings, body */
--sui-text-muted: #5A6A7E; /* Secondary — descriptions, labels */
--sui-text-light: #6A7D94; /* Tertiary — hints, placeholders */
}
Five radius tokens control the roundness across all components.
:root {
--sui-radius-xs: 6px; /* Small elements (chips, badges) */
--sui-radius-sm: 10px; /* Inputs, buttons */
--sui-radius: 16px; /* Cards, modals */
--sui-radius-lg: 24px; /* Large containers */
--sui-radius-full: 9999px; /* Pills, circles */
}
/* Sharp look */
:root {
--sui-radius-xs: 2px;
--sui-radius-sm: 4px;
--sui-radius: 6px;
--sui-radius-lg: 8px;
}
/* Extra round */
:root {
--sui-radius-xs: 10px;
--sui-radius-sm: 14px;
--sui-radius: 20px;
--sui-radius-lg: 32px;
}
Change the font family used across all components.
:root {
--sui-font: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
}
/* Use Inter */
:root {
--sui-font: 'Inter', sans-serif;
}
/* Use system fonts only (no Google Fonts) */
:root {
--sui-font: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, Oxygen, Ubuntu, sans-serif;
}
/* Monospace font (used in Copy Button, Color Picker, code elements) */
:root {
--sui-font-mono: 'JetBrains Mono', 'Fira Code', monospace;
}
Some components expose their own CSS variables for fine-tuning.
/* Modal — backdrop blur amount */
.sui-modal-backdrop {
--sui-modal-blur: 6px; /* or use classes: sui-modal-blur-none/sm/md/lg/xl */
}
/* Stack — hover spread distance and multiplier */
.sui-stack-hover {
--sui-stack-gap: 180px; /* base spread distance (match your card width) */
--sui-stack-spread: 0.6; /* multiplier (0.15 to 1) */
}
Three speed tokens for animation timing.
:root {
--sui-transition-fast: 0.15s; /* Hover states, toggles */
--sui-transition-base: 0.25s; /* Most animations */
--sui-transition-slow: 0.35s; /* Page transitions, modals */
--sui-transition: all var(--sui-transition-base) ease;
}
/* Snappier feel */
:root {
--sui-transition-fast: 0.1s;
--sui-transition-base: 0.15s;
--sui-transition-slow: 0.25s;
}
/* Disable all transitions */
:root {
--sui-transition-fast: 0s;
--sui-transition-base: 0s;
--sui-transition-slow: 0s;
}
Dark mode overrides backgrounds, shadows, and text colors. Add data-theme="dark" to your <html> element.
<html data-theme="dark">
/* Dark mode variables (already built-in) */
[data-theme="dark"] {
--sui-bg: #2A2D35;
--sui-bg-light: #31343C;
--sui-bg-dark: #23262D;
--sui-shadow-light: #33363F;
--sui-shadow-dark: #1E2027;
--sui-text: #E2E8F0;
--sui-text-muted: #9BA5B8;
--sui-text-light: #8A94A6;
}
/* Custom dark theme */
[data-theme="dark"] {
--sui-bg: #1A1A2E;
--sui-bg-light: #222240;
--sui-bg-dark: #141427;
--sui-primary: #9B59B6;
}
Add a toggle button and a few lines of JS to let users switch themes. This also respects system preference and persists the choice.
<!-- Toggle button -->
<button onclick="toggleTheme()">Toggle Dark Mode</button>
<script>
function toggleTheme() {
var html = document.documentElement;
var isDark = html.getAttribute('data-theme') === 'dark';
html.setAttribute('data-theme', isDark ? 'light' : 'dark');
localStorage.setItem('sui-theme', isDark ? 'light' : 'dark');
}
// Restore saved preference on load
(function() {
var saved = localStorage.getItem('sui-theme');
if (saved) {
document.documentElement.setAttribute('data-theme', saved);
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-theme', 'dark');
}
})();
// Listen for system theme changes
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', function(e) {
if (!localStorage.getItem('sui-theme')) {
document.documentElement.setAttribute(
'data-theme', e.matches ? 'dark' : 'light'
);
}
});
</script>
Priority: saved user preference > system preference > default (light).
A complete brand override — just drop this in your CSS after importing SoftUI.
/* My Brand Theme */
:root {
/* Colors */
--sui-primary: #0066FF;
--sui-primary-hover: #0052CC;
--sui-success: #00C853;
--sui-danger: #FF1744;
/* Surfaces */
--sui-bg: #F0F2F5;
--sui-bg-light: #F8F9FA;
--sui-bg-dark: #E4E6EB;
--sui-shadow-light: #FFFFFF;
--sui-shadow-dark: #C8CCD4;
/* Typography */
--sui-font: 'Inter', sans-serif;
--sui-text: #1A1A1A;
/* Shape */
--sui-radius: 8px;
--sui-radius-sm: 4px;
--sui-radius-lg: 12px;
/* Speed */
--sui-transition-base: 0.2s;
}
SoftUI ships a tokens.json file with all design values. Use it to sync with Tailwind, Figma plugins, Style Dictionary, or your own design system.
/* Import tokens in JavaScript */
import tokens from 'softui-css/dist/tokens.json';
console.log(tokens.colors.primary); // "#5B54E0"
console.log(tokens.radius.default); // "16px"
console.log(tokens.typography.font); // "'Plus Jakarta Sans', ..."
/* Use with Tailwind CSS */
const tokens = require('softui-css/dist/tokens.json');
module.exports = {
theme: {
extend: {
colors: {
primary: tokens.colors.primary,
success: tokens.colors.success,
danger: tokens.colors.danger,
},
borderRadius: {
soft: tokens.radius.default,
'soft-sm': tokens.radius.sm,
'soft-lg': tokens.radius.lg,
}
}
}
};
/* tokens.json structure */
{
"colors": {
"primary": "#5B54E0",
"primary-hover": "#4A44C4",
"success": "#1FA96E",
"danger": "#D03A5C",
"warning": "#F5A623",
"info": "#1A82D4"
},
"backgrounds": { "bg": "#E4E9F0", "bg-light": "#EDF1F7", "bg-dark": "#D1D9E6" },
"backgrounds-dark": { "bg": "#2A2D35", "bg-light": "#31343C", "bg-dark": "#23262D" },
"text": { "text": "#2D3748", "text-muted": "#5A6A7E", "text-light": "#6A7D94" },
"shadows": { "shadow-light": "#FFFFFF", "shadow-dark": "#B8C0CC" },
"radius": { "xs": "6px", "sm": "10px", "default": "16px", "lg": "24px", "full": "9999px" },
"typography": { "font": "...", "font-mono": "..." },
"transitions": { "fast": "0.15s", "base": "0.25s", "slow": "0.35s" }
}
The token file mirrors the CSS custom properties — if you override a variable, update the token too for consistency.
This is a neumorphic modal dialog. It features backdrop blur, smooth animations, and focus trap. Press Escape or click outside to close.
Your session will expire in 5 minutes. Would you like to stay signed in?
This action cannot be undone. This will permanently delete the item and remove all associated data.
This modal takes up the entire viewport. Useful for immersive content, editors, or media viewers.
Press Escape or click the close button to dismiss.
By accessing and using this service, you accept and agree to be bound by the terms and provision of this agreement. In addition, when using these particular services, you shall be subject to any posted guidelines or rules applicable to such services. Any participation in this service will constitute acceptance of this agreement.
Permission is granted to temporarily download one copy of the materials on this website for personal, non-commercial transitory viewing only. This is the grant of a license, not a transfer of title, and under this license you may not modify or copy the materials, use the materials for any commercial purpose, attempt to reverse engineer any software, or remove any copyright notations.
The materials on this website are provided on an 'as is' basis. We make no warranties, expressed or implied, and hereby disclaim and negate all other warranties including, without limitation, implied warranties or conditions of merchantability, fitness for a particular purpose, or non-infringement of intellectual property.
In no event shall this company or its suppliers be liable for any damages (including, without limitation, damages for loss of data or profit, or due to business interruption) arising out of the use or inability to use the materials, even if we have been notified orally or in writing of the possibility of such damage.
The materials appearing on this website could include technical, typographical, or photographic errors. We do not warrant that any of the materials on its website are accurate, complete or current. We may make changes to the materials contained on its website at any time without notice.
We have not reviewed all of the sites linked to this website and are not responsible for the contents of any such linked site. The inclusion of any link does not imply endorsement. Use of any such linked web site is at the user's own risk.
We may revise these terms of service for this website at any time without notice. By using this website you are agreeing to be bound by the then current version of these terms of service. Any changes will be posted on this page with an updated revision date.
These terms and conditions are governed by and construed in accordance with applicable laws and you irrevocably submit to the exclusive jurisdiction of the courts in that location. If any provision of these terms shall be unlawful, void, or unenforceable, then that provision shall be deemed severable and shall not affect the validity of the remaining provisions.
Clicking outside this modal won't close it. Instead, the modal will shake to indicate it requires explicit action. Use the close button or press Escape to dismiss.
This modal has no backdrop blur. The background is visible but dimmed.
A subtle 3px backdrop blur. Content behind is slightly softened.
A heavy 12px backdrop blur. Background is barely recognizable.
Maximum 20px blur. Background is fully frosted.
This is a default right-side sheet. It slides in from the right edge of the screen with a blurred backdrop.
Sheets are great for navigation menus, settings panels, detail views, and forms that don't need to interrupt the main content flow.
This sheet slides down from the top. Great for announcements, notification panels, or search interfaces.
This is a small (280px) right-side sheet.
This is a large (480px) right-side sheet. Great for forms, detail views, or complex content.
Clicking outside this sheet won't close it. The sheet will shake to indicate it requires explicit action. Use the close button or press Escape.