The SCSS foundation for design systems.
Classes you can read, tokens for every theme, and plain CSS out.
npm install -D sass @nuvoui/coreGet startedEvery theme. One markup.
Light, dark, inverse, high contrast and right to left. The classes stay the same; only three attributes change.
Read it once. Know what it does.
The first row of that inbox, and the markup that builds it.
HTML
<label class="group flex x-center gap-3 px-4 py-3 border-b-1 hover:bg-hover cursor-pointer">
<input type="checkbox">
<span class="w-2 h-2 rounded-full no-shrink bg-brand"></span>
<span class="w-24 w-32@md no-shrink truncate font-semibold" dir="auto">Mara Lindqvist</span>
<span class="grow min-w-0 truncate" dir="auto">
<span class="font-semibold">Q4 roadmap review moved to Thursday</span>
<span class="hide inline@md text-muted">Pushing it to 14:00 so finance can join. Agenda is unchanged.</span>
</span>
<span class="hide flex@lg pill px-2 text-xs bg-blue-subtle text-blue">Planning</span>
<time class="w-16@md no-shrink text-end text-xs text-muted">09:42</time>
</label>Any value. One class.
The spacing scale has 1rem and 1.25rem. This row wants 1.125rem, and apply() takes it as written.
SCSS
@use "@nuvoui/core" as *;
.mail-row {
@include apply(
flex, x-center, gap(3),
px(4), py(1.125rem),
border-bottom(1), cursor(pointer),
bg(hover) hover
);
}Compiled CSS
.mail-row {
display: flex;
align-items: center;
gap: var(--nu-space-3);
}
.mail-row > * {
--nu-flex-gap: var(--nu-space-3);
}
.mail-row {
padding-inline: var(--nu-space-4);
padding-block: 1.125rem;
border-bottom-width: var(--nu-border-width-1);
border-bottom-style: var(--nu-border-style);
border-bottom-color: var(--nu-border-regular);
--nu-border-style: solid;
cursor: pointer;
}
.mail-row:hover {
background-color: var(--nu-bg-hover);
}It refuses mistakes.
Drop the unit and the build stops, before the mistake can reach a browser.
SCSS
@use "@nuvoui/core" as *;
.mail-row {
@include apply(
flex, x-center, gap(3),
px(4), py(1.125),
border-bottom(1), cursor(pointer),
bg(hover) hover
);
}Sass output
Error: "py: 1.125 is not a configured key. Valid keys: 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64. Write a unit for a custom value (1.125px, 1.125rem)."Specifications
NuvoUI core 2.0.1
- Output
- Plain CSS. Core ships no JavaScript and needs no runtime or PostCSS plugin.
- Language
- SCSS modules, loaded with @use. Requires Dart Sass 1.79.0 or later, below 2.0.
- Classes and mixins
- Every utility is also a mixin for apply(), with states and breakpoints. Utility classes are opt-in through $generate-utility-classes.
- Tokens
- Every scale is a --nu- custom property: colour, space, type, radius, shadow, motion.
- Themes
- Light, dark and inverse through data-theme, high-contrast overrides through data-contrast="high". Without data-theme, the operating system colour scheme decides.
- Colour
- Roles and palette generated in OKLCH, in stops 50, 100 to 900, and 950.
- Direction
- Logical utilities such as ps, me, start, border-s and text-start mirror under dir="rtl".
- Errors
- Unknown keys and colour names stop the compile and list the valid options. Text on a brand or status fill below 4.5:1 raises a warning.
- Licence
- MIT.
Start with one line.
npm install -D sass @nuvoui/coreRead the documentation