@erikakers/slate
v0.2.0
Published
The Slate design system as a Sass module: tokens, base layer and components, with type delegated to @erikakers/typography.
Maintainers
Readme
@erikakers/slate
The Slate design system as a Sass module. Three typefaces, one accent colour, and structure carried by hairlines and space rather than containers.
This package delegates its type rendering to @erikakers/typography. Slate passes its own inputs down and returns the configured typography module up, meaning a consumer has one type dependency: Slate.
Two things to know before starting
- The derived type scale does not pixel-match Slate. Display lands about 21% below Slate's drawn 56px. The site accepted this, and the package accepts it too.
- The fluid hero and display sizes are gone. Type is derived from typography, which scales mathematically rather than by fluid clamps.
Installation
npm install @erikakers/slate @erikakers/typographyThe pkg: importer requirement
Both packages are reachable only through their exports field, which exposes the sass condition. A bare @use '@erikakers/slate' with --load-path=node_modules will fail with Can't find stylesheet to import.
You must use Sass's Node package importer:
CLI:
sass --pkg-importer=node src/app.scss dist/app.cssJS API (Vite/Rollup/Node):
import * as sass from 'sass';
const result = sass.compile('src/app.scss', {
importers: [new sass.NodePackageImporter()]
});Astro (in astro.config.mjs):
export default defineConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler',
importers: [(new (await import('sass')).NodePackageImporter())]
}
}
}
}
});The two entry points
1. The emitting entry: @erikakers/slate/global
This is the one you want in your root stylesheet. It loads the system, configures it, and emits the CSS: the @font-face rules, the resets, the tokens, the base elements, the components, and the layout utilities.
// app.scss
@use 'pkg:@erikakers/slate/global';2. The silent entry: @erikakers/slate
This is for downstream partials. It forwards the tokens, functions, and mixins without emitting any CSS, avoiding duplicate output.
// _header.scss
@use 'pkg:@erikakers/slate' as slate;
.header {
padding: slate.$sp-5;
color: var(--slate-color-text);
}Configuration
You configure Slate the first time you load it, using with. The configuration you pass is applied to Slate, and Slate passes it down to typography.
@use 'pkg:@erikakers/slate/global' with (
$font-family-base: 'Petrona, serif',
$scale-ratio: 1.25
);Additive maps
Slate's $components, $utilities, and $generic variables are additive maps. They enable or disable chunks of CSS output. By default, every layer is emitted (true).
@use 'pkg:@erikakers/slate/global' with (
$components: (
'button': false, // Disables the button component CSS
'tag': true
)
);Typography dependence
Never name @erikakers/typography in a consumer. Slate already configured it. Loading pkg:@erikakers/typography directly will override Slate's configuration with typography's defaults, breaking the type scale silently. You reach the entire type API through Slate's @forward.
Fonts
Slate relies on three self-hosted fonts: Hanken Grotesk, Petrona, and Fragment Mono. The package contains the .woff2 files in fonts/.
You must copy these fonts to your public directory (e.g., public/fonts/ or dist/fonts/) during your build step. The @font-face rules emitted by Slate assume they live at /fonts/. If you put them elsewhere, override $slate-font-path:
@use 'pkg:@erikakers/slate/global' with (
$slate-font-path: '/assets/fonts/'
);Browser support
Modern baseline: color-mix, prefers-color-scheme, prefers-reduced-motion, :focus-visible, text-wrap: balance, and logical properties. There are no vendor prefixes and no fallbacks for older browsers.
Documentation
See SLATE.md for the system's design fundamentals, visual rationale, and rules for extending it. Long-form architecture and rationale are kept in the project wiki.
