@bfs2/style
v1.3.79
Published
The SCSS foundation of the **Bold Foundation System (BFS)** — a design-token-driven stylesheet that ships compiled CSS, raw SCSS sources, theme overrides, mixins, and webfonts.
Readme
@bfs2/style
The SCSS foundation of the Bold Foundation System (BFS) — a design-token-driven stylesheet that ships compiled CSS, raw SCSS sources, theme overrides, mixins, and webfonts.
- npm: https://www.npmjs.com/package/@bfs2/style
- Scope:
@bfs2 - License: ISC
Table of contents
- What's in the package
- Installation
- Usage
- Design tokens
- Architecture
- Local development
- Scripts reference
- Build pipeline
- Customization
- Publishing
- Contributing
What's in the package
When installed from npm, the package exposes four top-level directories (declared in package.json files):
| Path | Contents |
|-------------|---------------------------------------------------------------------------------------------------|
| css/ | Compiled, autoprefixed, minified bfs-style.css (single bundle, drop-in ready) and its source map |
| scss/ | Reusable mixins (grid/mixins.scss, typography/mixins.scss, table/mixins.scss) for SCSS consumers |
| themes/ | Pre-compiled theme overrides (e.g. sites-bold-tool.css, sites-company-profile.css) |
| fonts/ | Webfont assets used by the base stylesheet (Inter family) |
Everything is generated from the src/ SCSS sources by the build pipeline. Consumers should pick one entry point — the compiled CSS or the SCSS sources — depending on whether they want a pre-built bundle or full control over the build.
Installation
npm install @bfs2/styleOr, with yarn / pnpm:
yarn add @bfs2/style
pnpm add @bfs2/styleUsage
Drop-in compiled CSS
The simplest way to consume the package is to import the pre-built bundle:
// Vite / webpack / Next.js / any bundler that resolves CSS imports
import '@bfs2/style/css/bfs-style.css';Or, in plain HTML:
<link rel="stylesheet" href="/node_modules/@bfs2/style/css/bfs-style.css" />This loads:
- The CSS variable layer (
--bfs-*custom properties for colors, spacing, typography, shadows, etc.) - Utility classes for colors, backgrounds, borders, outlines, dimensions, position, spacing
- The 12-column responsive grid system
- Reset and typography rules
- Icon, blur, and shadow utilities
Importing SCSS sources
For projects that compile SCSS themselves and want access to variables, functions, and mixins, import the source entry point:
@use '@bfs2/style/src/bfs-style';You can also import individual layers if you only need a subset:
@use '@bfs2/style/src/config/index' as config;
@use '@bfs2/style/src/colors/index' as colors;
@use '@bfs2/style/src/grid/index' as grid;
@use '@bfs2/style/src/typography/index' as typography;Note: SCSS source consumers must have
sassconfigured. Use--load-path=node_modules(or your bundler's equivalent) so imports resolve cleanly.
Using mixins
The build copies all reusable mixins.scss files into the published scss/ directory:
@use '@bfs2/style/scss/grid/mixins' as grid;
@use '@bfs2/style/scss/typography/mixins' as type;
@use '@bfs2/style/scss/table/mixins' as table;
.my-section {
@include grid.bfs-media-breakpoint-up('md') {
padding: 2rem;
}
}Available grid mixins include bfs-media-breakpoint-up, -down, -between, -only, plus column/container helpers (make-container, make-row, make-col, make-col-offset). Breakpoints follow the standard xs / sm / md / lg / xl / xxl scale:
| Name | Min width | |------|-----------| | xs | 0 | | sm | 576px | | md | 768px | | lg | 992px | | xl | 1200px | | xxl | 1440px |
Applying a theme
Themes are CSS files that override the --bfs-* custom properties. Load the base bundle first, then layer a theme on top:
<link rel="stylesheet" href="/path/to/@bfs2/style/css/bfs-style.css" />
<link rel="stylesheet" href="/path/to/@bfs2/style/themes/sites-bold-tool.css" />Or via bundler:
import '@bfs2/style/css/bfs-style.css';
import '@bfs2/style/themes/sites-bold-tool.css';Shipped themes:
sites-bold-tool.css— typography override for the Pro Tool sitessites-company-profile.css— typography override for the Company Profile sites
Loading fonts
The package ships the Inter family under fonts/inter/. If you import the compiled CSS, the @font-face declarations are already included — you only need to make sure the fonts/ directory is served at the same relative path as the CSS file (most bundlers handle this automatically when copying the package's static assets).
Design tokens
Design tokens are the source of truth for every visual value in the system. They live in tokens/tokens.json and are transformed by Style Dictionary into SCSS variables (and optionally JS constants).
The token pipeline:
Figma Variables API
│
▼
tools/figma-sync ─── writes ──▶ packages/style/tokens/tokens.json
│
▼
Style Dictionary (config.json)
│
▼
packages/style/src/_variables.scss
│
▼
bfs-style.scss → Sass + PostCSS → css/bfs-style.cssRegenerate SCSS variables from tokens:
npm run build:tokensSync tokens from Figma (requires FIGMA_API_TOKEN and FILE_ID in .env, run from repo root):
npx ts-node tools/figma-sync/src/index.tsToken scales
The system uses named scales rather than magic numbers. See src/config/index.scss for the canonical lists:
| Scale | Values |
|------------------|---------------------------------------------------------------------------------------------------|
| Sizes (default) | none, xs, sm, md, lg, xl |
| Sizes (extended) | xxxs, xxs, xs, sm, md, lg, xl, xxl, xxxl, xxxxl |
| Weights | light, regular, semi-bold, bold |
| Shadows | none, xs, sm, md, lg |
| Directions | top, bottom, right, left |
| Borders | default, actionable, input, error, warning, info, success, disabled (+ states) |
| Colors | brand-0{1,2,3} (with -lightest/-lighter/-light/-dark modifiers), accent-0{1,2}, semantic (success, warning, info, error), neutrals (gray-*, neutral-*), plus white and black |
All CSS custom properties are prefixed --bfs- (the prefix is configured by $prefix: 'bfs' in src/config/index.scss).
Architecture
packages/style/
├── src/ ← Source SCSS (authored)
│ ├── bfs-style.scss ← Main entry — @use's every layer in order
│ ├── config/ ← Tokens, prefix, named scales
│ ├── colors/ ← Color CSS variables + utility classes
│ ├── reset/ ← CSS reset
│ ├── backgrounds/ ← Background utilities
│ ├── borders/ ← Border utilities
│ ├── outlines/ ← Outline utilities
│ ├── grid/ ← 12-col grid + breakpoint mixins
│ ├── typography/ ← Type scale, heading classes, ratio-based sizing
│ ├── icons/ ← Icon classes
│ ├── dimensions/ ← Width/height utilities
│ ├── shadows/ ← Box-shadow utilities
│ ├── blurs/ ← Backdrop/filter blur utilities
│ ├── position/ ← Position utilities (higher specificity)
│ ├── space/ ← Margin / padding utilities (higher specificity)
│ ├── table/ ← Table styles
│ ├── themes/ ← Source for shipped theme overrides
│ └── assets/fonts/ ← Source webfonts (copied to fonts/ at build time)
│
├── scripts/ ← Build tooling (TypeScript)
│ ├── build.ts ← Compiles SCSS → CSS, autoprefixes, injects preamble
│ ├── copy.ts ← Copies fonts and mixins to publishable folders
│ ├── utils.ts ← CLI argument validation
│ └── copy-deployable-files.sh
│
├── tokens/
│ └── tokens.json ← Design tokens (source of truth, fed by Figma)
│
├── serve/ ← HTML playground pages for the dev server
│ ├── index.html
│ ├── colors.html
│ ├── grid.html
│ ├── typo-demo.html
│ └── …
│
├── css/ ← BUILT — published compiled bundle
├── scss/ ← BUILT — published reusable mixins
├── themes/ ← BUILT — published theme overrides
├── fonts/ ← BUILT — published webfonts
│
├── config.json ← Style Dictionary config
├── package.json
├── lerna.json
└── tsconfig.jsonThe order in which layers are @use'd inside src/bfs-style.scss is deliberate — position and space come last so their utility classes have higher specificity than layout-level styles. Do not reorder without understanding the cascade implications.
Local development
From the repo root (the monorepo uses npm workspaces):
# 1) install all workspace deps
npm install
# 2) start the style package's dev server
npm run start --workspace=packages/styleOr from inside packages/style:
npm install # only if not already done at the root
npm startThis runs three processes in parallel via npm-run-all:
clean— wipes.tmp/anddist/develop:watch— Chokidar watchessrc/**/*.scssand recompiles into.tmp/serve— BrowserSync serves theserve/HTML playground athttp://127.0.0.1:3000, with live-reload on.tmp/changes
Open the playground pages (grid.html, colors.html, typography.html, etc.) to visually verify changes as you edit SCSS.
Linting
npm run lint --workspace=packages/styleRuns Stylelint against src/**/*.scss using the shared config in tools/dev-tools.
Scripts reference
| Script | Description |
|-------------------------|----------------------------------------------------------------------------------------|
| npm start | Clean, watch-compile to .tmp/, and serve the playground via BrowserSync |
| npm run build | Clean, then compile production CSS into css/ and copy fonts/mixins into scss/, fonts/ |
| npm run build:tokens | Run Style Dictionary to regenerate src/_variables.scss from tokens/tokens.json |
| npm run build:production | build + npm publish --access public (used by maintainers to ship a release) |
| npm run clean | Remove dist/ and .tmp/ |
| npm run css:build | Direct invocation of scripts/build.ts (called by build) |
| npm run copy | Direct invocation of scripts/copy.ts (called by build) |
| npm run develop:watch | Watch src/**/*.scss and rebuild into .tmp/ on change |
| npm run develop:style | One-shot compile into .tmp/ |
| npm run serve | Start BrowserSync only |
| npm run lint | Stylelint |
| npm run deploy | build + run scripts/copy-deployable-files.sh (legacy/internal) |
| npm run pre-commit | Lint + lint-staged (wired into the repo's git hooks) |
Build pipeline
scripts/build.ts (invoked by npm run build) does four things, in order:
- Compile
src/bfs-style.scss→css/bfs-style.cssvia Sass (--style=compressed,--load-path=node_modules) - Compile each theme in
src/themes/*.scss→themes/*.css - Autoprefix the main CSS bundle via PostCSS + Autoprefixer (
--no-map --replace) - Inject preamble — replace
$VERSIONand$DATEtokens at the top ofbfs-style.csswith the currentpackage.jsonversion and an ISO timestamp
scripts/copy.ts then copies:
src/assets/fonts/**/*→fonts/src/**/mixins.scss(excludingsrc/**/lib/*) →scss/, preserving the directory structure (scss/grid/mixins.scss,scss/typography/mixins.scss,scss/table/mixins.scss)
Both scripts validate CLI arguments via scripts/utils.ts and exit non-zero on failure.
Customization
Creating a custom theme
A theme is simply a stylesheet that overrides --bfs-* custom properties. See src/themes/example.scss for the minimal shape:
:root {
--bfs-heading-1-color: #008000;
}For a fully-fleshed example with responsive overrides, look at src/themes/sites-bold-tool.scss. To ship a new theme:
- Create
src/themes/your-theme.scss - Add a
compileSass(...)call for it inscripts/build.ts - Run
npm run build - The compiled
themes/your-theme.csswill be included in the next publish
Overriding tokens at the consumer level
You don't need to fork the package to tweak values. Override any --bfs-* custom property in your own stylesheet, scoped to :root or to a container:
:root {
--bfs-color-brand-01: #ff5500;
--bfs-font-size-md: 17px;
}
.dark-section {
--bfs-color-background: #111;
}Extending the SCSS layer
If you need access to Sass variables, functions, or mixins that aren't exposed via CSS custom properties, consume from src/ rather than css/:
@use '@bfs2/style/src/config/index' as config;
.my-class {
// Use named scales from the config
}Publishing
Publishing requires being a member of the @bfs2 npm org with publish rights and a valid NPM_TOKEN in the environment. The root README.md contains the complete publish playbook — short version:
# 1) Bump version (from packages/style)
npm version patch # 1.3.77 → 1.3.78 (bug fixes)
npm version minor # 1.3.77 → 1.4.0 (new, backwards-compatible features)
npm version major # 1.3.77 → 2.0.0 (breaking changes)
# 2) Commit and tag (npm version inside a workspace does NOT auto-commit)
git add packages/style/package.json package-lock.json
git commit -m "chore: release @bfs2/style v1.3.78"
git tag v1.3.78
git push --follow-tags
# 3) Build and publish
npm run build:productionThe build:production script chains npm run build && npm publish --access public. The new version appears at https://www.npmjs.com/package/@bfs2/style within seconds.
Common publish errors
| Error | Cause | Fix |
|----------------------------------------------------------------------------------|----------------------------------------|--------------------------------------------------|
| You cannot publish over the previously published versions: 1.3.77 | Forgot to bump version | Run npm version patch first |
| 404 Not Found - PUT https://registry.npmjs.org/@bfs2%2fstyle | Auth token missing/expired/under-scoped | Reissue NPM_TOKEN and re-export |
| EOTP / One-time password required | npm account requires 2FA | Append --otp=123456, or use an automation token |
Contributing
- Create a branch off
main - Add or modify SCSS in
src/ - Verify visually with
npm startand the playground pages inserve/ - Run
npm run lintand fix any Stylelint findings - Run
npm run buildto confirm the production build is clean - Open a PR — do not bump the version or run
npm publishfrom a feature branch; releases are cut frommainby maintainers
Conventions
- All CSS custom properties use the
--bfs-prefix (configured insrc/config/index.scss) - Sass mixins/functions intended for consumer use are prefixed
bfs-(e.g.bfs-media-breakpoint-up) - Internal-only Sass lives under
src/**/lib/and is not copied into the publishedscss/directory - New design values should be added to
tokens/tokens.jsonand regenerated vianpm run build:tokens— do not hand-editsrc/_variables.scss - Keep
src/bfs-style.scsslayer ordering intact;positionandspacemust remain last for specificity reasons
