Getting started
Theming
The kit ships two themes, Soft Dark and Soft Light, and dark is the default. Both use the same
token names, so switching is one attribute on <html>.
How it works
The stylesheet declares the dark palette in Tailwind v4's @theme block, which makes
it the default. The light palette redeclares the same custom properties under html[data-theme="light"]. These are the values in version 0.60.1:
@theme {
--color-ink: #0b1422;
--color-surface: #0c1728;
--color-fg: #e6e8ee;
--color-brand: #00d4ff;
/* ...and every other token */
}
html[data-theme='light'] {
--color-ink: #f6f7f9;
--color-surface: #ffffff;
--color-fg: #111827;
--color-brand: #005a77;
}Components use Tailwind utilities like bg-ink, text-fg and border-line. Tailwind v4 generates them from the variables, so the same <Button /> follows either theme with nothing else to set.
Switching themes
<ThemeToggle /> cycles through light, dark and the operating system's setting.
It sets data-theme on <html> and keeps the choice in localStorage:
To wire a control of your own, the same helpers are exported:
import { getTheme, setTheme, setThemePreference, toggleTheme } from '@lyeve-labs/ui-kit';
setTheme('light'); // explicit
setTheme('dark');
setThemePreference('system'); // follow the operating system
toggleTheme(); // returns the new theme
getTheme(); // 'dark' | 'light'Setting the theme before the first paint
Set the theme before the browser paints the page. A theme set any later shows the page in the wrong palette for a moment first. The kit exports the script that does it:
<script lang="ts">
import { themeBootScript } from '@lyeve-labs/ui-kit';
</script>
<svelte:head>
{@html '<' + 'script>' + themeBootScript() + '</' + 'script>'}
</svelte:head>Prefer the static snippet
app.html instead: see the installation guide. That way
the script runs even on the very first request, before SvelteKit hydrates.Customizing the palette
Override individual tokens by re-declaring them after you import the library stylesheet. Both themes are honored:
@import '@lyeve-labs/ui-kit/styles.css';
/* Bend the cyan accent towards your own brand */
@theme {
--color-brand: #ff5e9c;
--color-brand-light: #ff85b3;
--color-brand-deep: #f0508f;
}
html[data-theme='light'] {
--color-brand: #b51758;
--color-brand-light: #9f144d;
--color-brand-deep: #8b1244;
}Set all three brand tokens. Focus rings, the focus outline and a focused field's border draw in brand-deep, so a theme that leaves it out keeps the kit's cyan rings beside its own
brand.
Token reference
| Token | Role |
|---|---|
ink | App and page background. |
surface | Raised cards. |
surface-2 | Inputs, hovered rows, nested panels. |
line | Borders and dividers. |
line-strong | The border of a checkbox, radio or toggle. An empty one rests on line-strong at 60%, about 2:1, and firms to line-strong under the pointer, at 3:1 or more against
every surface. Fields, selects, buttons, segmented controls and option cards rest on line, and a field, a select or an option card firms to line-strong under the pointer. |
fg | Primary text. |
muted | Secondary text. |
faint | Labels, hints, disabled text. |
brand | Primary accent, cyan. |
brand-light | Hover and highlight. |
brand-deep | Pressed state. |
focus | Focus rings, the focus outline and a focused field's border. It is brand-deep, read where each control sits. |
violet | Secondary accent. |
band | A table's head row: the brand at 8% in the surface. |
success warn danger | Status colors. |