@boostdev/design-system-foundation
v1.0.4
Published
BoostDev design system foundation — CSS tokens, reset, base styles and utilities
Readme
@boostdev/design-system-foundation
Stop hard-coding design values. This package gives you a complete set of CSS tokens (colours, spacing, typography, grid, shadows, z-index, animations), a browser reset, base styles, and layout utility classes. Import once, theme freely, and get accessible colour contrast for free. Zero runtime dependencies. Works with any framework.
How to use these tokens
Token pairs: the most important rule
Every surface colour has a content (text/icon) colour named with on-. Always use them together:
.badge {
background-color: var(--bds-color_grey--subtle);
color: var(--bds-color_on-grey--subtle); /* the paired token */
}Pairing guarantees WCAG AA contrast in both light and dark mode automatically. The theme adapts
via [data-theme="dark"] attribute or prefers-color-scheme with no extra code from you.
The same intent-driven design applies across all token groups:
| Group | Rule |
|---|---|
| Colours | Use --bds-color_X as background, --bds-color_on-X as text/icon |
| Space | Use the named scale (--bds-space_xs to --bds-space_xxxxl), never raw px values |
| Z-index | Use named roles (--bds-z-index_nav, --bds-z-index_toast), never raw integers |
| Shadow | Use the elevation scale (--bds-shadow_s to --bds-shadow_2xl), never custom shadows |
| --bds-BASE__ tokens | Never use in component CSS. These are internal primitives. |
Token naming anatomy
All tokens are prefixed with --bds- to prevent collisions with other CSS custom properties.
Colour tokens — use the color_ group segment:
--bds-color_{name}--{variant}Examples: --bds-color_bg, --bds-color_on-bg, --bds-color_green--subtle, --bds-color_error
All other tokens — include the group segment:
--bds-{group}_{name}--{variant}Examples: --bds-space_m, --bds-font_size--body, --bds-shadow_l, --bds-z-index_nav
Internal palette (never reference directly):
--bds-BASE__{group}--{name}Examples: --bds-BASE__color--green--700, --bds-BASE__space--100
Installation
pnpm add @boostdev/design-system-foundation
npm install @boostdev/design-system-foundation
yarn add @boostdev/design-system-foundationUsage
Full bundle
Import everything — tokens, reset, base styles, and utilities — in one line:
@import "@boostdev/design-system-foundation/css";Tokens only
For apps that manage their own reset and base styles:
@import "@boostdev/design-system-foundation/css/tokens";Individual layers
Import only what you need:
@import "@boostdev/design-system-foundation/css/tokens";
@import "@boostdev/design-system-foundation/css/reset";
@import "@boostdev/design-system-foundation/css/base";
@import "@boostdev/design-system-foundation/css/utilities";Granular token imports
Import individual token groups to avoid loading token categories you don't use:
@import "@boostdev/design-system-foundation/css/tokens/color";
@import "@boostdev/design-system-foundation/css/tokens/space";
/* skip grid, animations, z-index if not needed */Available token groups: color, space, font, grid, border, shadow, animations, z-index.
Note: Token files export CSS custom properties (
--bds-brand,--bds-space_xs, etc.). These cannot be statically tree-shaken because build tools cannot determine which variables your CSS or HTML references at runtime. Granular imports let you opt out of entire categories you don't use.
Purging unused utility classes
The utility classes (.utl-*, .visually-hidden, .light-scheme, .dark-scheme, .night-scheme) can be
removed from production builds using PurgeCSS. Add it to your Nuxt or Vite config:
// nuxt.config.ts
export default defineNuxtConfig({
postcss: {
plugins: {
'@fullhuman/postcss-purgecss': {
content: ['./src/**/*.{vue,ts,tsx,html}'],
safelist: [/^--/] // never purge CSS custom properties
}
}
}
})// vite.config.ts
import purgecss from '@fullhuman/postcss-purgecss'
export default {
css: {
postcss: {
plugins: [
purgecss({
content: ['./src/**/*.{vue,ts,tsx,html}'],
safelist: [/^--/]
})
]
}
}
}React Native
React Native does not support CSS custom properties or rem units. Import pre-resolved token
objects from the /native sub-path instead:
import { colors, spacing, font, border, zIndex, animation, palette } from '@boostdev/design-system-foundation/native';
import { useColorScheme } from 'react-native';
function MyComponent() {
const scheme = useColorScheme(); // 'light' | 'dark' | null
const theme = colors[scheme ?? 'light'];
return (
<View style={{ backgroundColor: theme.bg, padding: spacing.m }}>
<Text style={{ color: theme.onBg, fontSize: font.size.body }}>Hello</Text>
</View>
);
}All token values are resolved to primitives (numbers in dp/pt, hex strings) — no CSS units:
| Export | Contents |
|---|---|
| palette | Full color palette as hex strings (e.g. palette.green500) |
| colors.light / colors.dark | Semantic colors per theme (e.g. colors.light.bg) |
| spacing | Scale from xxxs (2) to xxxxl (40), in dp — base (mobile) breakpoint values |
| font.family / .weight / .size / .lineHeight / .tracking | Typography tokens |
| border.radius | Border radii: xs (4), s (12), m (16) |
| zIndex | Z-index scale and named roles |
| animation.duration | fast (150ms) and normal (350ms) as numbers |
| animation.easing | default ('ease-out') |
Note:
spacingvalues are fixed at the base (mobile) breakpoint.spacing.m,spacing.l, andspacing.xlare all16at mobile — they diverge at wider viewports in CSS but React Native does not support responsive tokens.
Font tracking values are stored as unitless EM coefficients — multiply by fontSize to get the
absolute letterSpacing value for React Native: tracking.tight * font.size.body.
TypeScript
import { cn } from '@boostdev/design-system-foundation';
import type { SemanticColor, SemanticOnColor, Color, OnColor, AllColors } from '@boostdev/design-system-foundation';cn() composes class name strings, filtering out falsy values:
cn('button', isActive && 'button--active', [extraClass])
// → "button button--active extraClass"Overriding tokens
All tokens are defined inside @layer tokens.base and @layer tokens.semantic. The package
declares the following layer order:
tokens.base → tokens.semantic → tokens.override → reset → base → utilitiesTo configure the design system foundation for your project, create a tokens.config.css and place your
overrides inside @layer tokens.override. This slots into the cascade at the correct position —
after the defaults, before reset and base styles pick up the values.
/* tokens.config.css */
@layer tokens.override {
:root {
/* define implementation tokens that the base layer intentionally omits */
--bds-brand: var(--bds-BASE__color--orange);
--bds-on-brand: var(--bds-BASE__color--black);
--bds-cta: var(--bds-BASE__color--orange);
--bds-on-cta: var(--bds-BASE__color--black);
}
}Then import it after the package:
@import "@boostdev/design-system-foundation/css";
@import "./tokens.config.css";Token reference
Colors
Two-tier system: palette tokens (--bds-BASE__color--*) map to semantic tokens (--bds-color_*).
Override semantic tokens to retheme; override palette tokens to change the raw colors.
Semantic tokens (recommended override surface):
| Token | Default |
|---|---|
| --bds-color_interactive | blue — for UI elements (borders, fills) |
| --bds-color_interactive_on-bg | blue-700 — for text on default background (WCAG AA) |
| --bds-color_bg / --bds-color_on-bg | white / black |
| --bds-color_bg--subtle / --bds-color_on-bg--subtle | grey–100 / black |
| --bds-color_error | red–500 — for UI indicators |
| --bds-color_error_on-bg | red–700 — for text on default background (WCAG AA) |
| --bds-color_warning | orange–700 |
| --bds-color_success / --bds-color_success--subtle | green–300 / green–100 |
| --bds-color_important | blue–700 |
Note:
--bds-color_brand,--bds-color_cta, and--bds-color_activeare not part of the generic design system. Define them in your owntokens.overridelayer. Use the deprecated import during migration.
Per-colour scales with --subtle, base, and --strong variants (each paired with --bds-color_on-*):
green, blue, orange, grey, red
Dark mode is supported via [data-theme="dark"] and prefers-color-scheme: dark.
Typography
| Token | Description |
|---|---|
| --bds-font_size--display | Responsive display size (3.5–6rem) |
| --bds-font_size--heading-1 | Responsive h1 (2–3rem) |
| --bds-font_size--heading-2 | Responsive h2 (1.5–2rem) |
| --bds-font_size--heading-3 | h3 (1.25rem) |
| --bds-font_size--body | Body text (1rem) |
| --bds-font_weight--bold | 700 |
| --bds-font_weight--semibold | 600 |
| --bds-font_weight--medium | 400 |
| --bds-font_weight--light | 300 |
Spacing
--bds-space_xxxs → --bds-space_xxxxl, responsive across breakpoints.
Grid
--bds-grid_template-columns, --bds-grid_gap, --bds-grid_span-* — 4 / 8 / 12 column grid, responsive.
Container
These tokens control the .utl-main-grid container. Override them in tokens.override to customise layout behaviour:
| Token | Description |
|---|---|
| --bds-container_max-width | Responsive max-width (grows from xs → xl breakpoints) |
| --bds-container_max-width--narrow | Fixed narrow container width (48rem) |
| --bds-container_min-width | Minimum container width (min-content) |
| --bds-container_spacing-inline | Horizontal padding applied by .utl-main-grid |
Other
- Borders:
--bds-border_radius--xs/s/m,--bds-outline_default - Shadows:
--bds-shadow_sthrough--bds-shadow_2xl - Animations:
--bds-animation_transition,--bds-animation_duration--fast/normal - Z-index:
--bds-z-index_base/above/below/s/m/l/xl/nav/dropdown/popover/toast
Utility classes
| Class | Description |
|---|---|
| .utl-main-grid | Responsive main content grid |
| .utl-page-grid | Full-width stacked page layout |
| .utl-column | Grid column span helper (set --bds-utl-column__size to a --bds-grid_span-* value) |
| .utl-heading1/2/3 | Heading size utilities |
| .visually-hidden | Accessible hide (screen reader only) |
| .light-scheme / .dark-scheme / .night-scheme | Force color scheme on an element |
Development
Building
pnpm build:native # regenerate src/native/tokens.ts from CSS sources
pnpm build:customdata # regenerate CSS Custom Data JSON for IDE hover support
pnpm build # build:native + tsup + build:customdata (dist/)
pnpm test # run all tests including native token integration tests
pnpm typecheck # TypeScript type check (src/ and scripts/)Adding new tokens
- Add CSS custom properties to the relevant file in
src/tokens/ - Add
@propertydeclarations tosrc/tokens/properties.cssfor color/length tokens - Run
pnpm build:nativeto regeneratesrc/native/tokens.ts - Run
pnpm build:customdatato regenerate.vscode/css-custom-data.jsonanddist/css-custom-data.json - Commit all changed files
The CSS files are the single source of truth. The native tokens file and CSS custom data are auto-generated — do not edit them by hand.
IDE support
The package ships a VS Code CSS Custom Data file
that adds hover documentation to all public custom properties. When you hover --bds-space_m in a CSS
file you'll see 1rem (16px) instead of the raw var(...) declaration.
For developers in this repo — the .vscode/settings.json is already configured. Reload VS Code
after running pnpm build:customdata for the first time.
For consuming projects — add this to your .vscode/settings.json:
{
"css.customData": ["./node_modules/@boostdev/design-system-foundation/dist/css-custom-data.json"]
}The file is also exported as @boostdev/design-system-foundation/css-custom-data for tooling that
reads package exports.
Migrating from v0.x to v1.0.x
All token names changed in v1.0.0 and were refined in v1.0.2. Import the deprecated aliases during migration to keep existing code working:
@import "@boostdev/design-system-foundation/css/tokens/deprecated";Then migrate references at your own pace and remove the import when done.
Key renames at a glance:
| v0.x | v1.0.2 |
|---|---|
| --color_bg | --bds-color_bg |
| --color_on-bg | --bds-color_on-bg |
| --color_green--subtle | --bds-color_green--subtle |
| --color_error | --bds-color_error |
| --color_brand | removed — define in tokens.override |
| --color_cta | removed — define in tokens.override |
| --space_m | --bds-space_m |
| --font_size--body | --bds-font_size--body |
| --shadow_s | --bds-shadow_s |
| --grid_span-50 | --bds-grid_span-50 |
| --BASE__color--white | --bds-BASE__color--white |
Publishing a new version
npm version patch # or minor / major
git push --follow-tagsGitLab CI will build and publish to npm automatically on version tags.
