jk-sass-lib
v1.0.2
Published
Personal Sass design system — tokens, mixins, and functions.
Readme
jk-sass-lib
A personal Sass design system — tokens, mixins, and functions built for reuse across projects.
Installation
npm install jk-sass-libRequires Dart Sass 1.33+. The legacy node-sass compiler is not supported.
Quick start
Import the full library into your stylesheet:
@use "jk-sass-lib";
.button {
background: jk-sass-lib.$color-primary;
border-radius: jk-sass-lib.$radius-md;
@include jk-sass-lib.transition(background, transform);
}Or import only what you need:
@use "jk-sass-lib/sass/abstracts" as lib;
.card {
padding: lib.$space-6;
@include lib.card;
}Configuration
Every token is defined with !default, so you can override the entire system before your first @use:
@use "jk-sass-lib" with (
$color-primary: #e63946,
$font-sans: "Söhne",
system-ui,
sans-serif,
$radius-md: 4px,
$bp-lg: 1100px
);Overrides must be passed at @use time — you cannot change tokens after the module is loaded.
Token reference
Color
| Token | Default | Description |
| --------------------- | --------- | ---------------------------- |
| $color-primary | #5b4fcf | Brand / interactive color |
| $color-primary-dark | #3d33b0 | Hover / pressed state |
| $color-surface | #ffffff | Card and modal backgrounds |
| $color-surface-alt | #f5f5f5 | Subtle surface variant |
| $color-text | #1a1a1a | Body text |
| $color-text-muted | #6b6b6b | Secondary / placeholder text |
| $color-border | #e0e0e0 | Default border |
| $color-error | #d93025 | Error states |
| $color-success | #1e8c45 | Success states |
Spacing
Base-4 scale in rem. Numeric suffix = multiple of 4px.
| Token | Value |
| ----------- | ---------------- |
| $space-1 | 0.25rem (4px) |
| $space-2 | 0.5rem (8px) |
| $space-3 | 0.75rem (12px) |
| $space-4 | 1rem (16px) |
| $space-6 | 1.5rem (24px) |
| $space-8 | 2rem (32px) |
| $space-12 | 3rem (48px) |
| $space-16 | 4rem (64px) |
Typography
| Token | Default |
| --------------------------------------- | -------------------------------- |
| $font-sans | "Inter", system-ui, sans-serif |
| $font-serif | "Georgia", serif |
| $font-mono | "JetBrains Mono", monospace |
| $text-xs … $text-4xl | 0.75rem … 2.25rem |
| $leading-tight / -normal / -loose | 1.25 / 1.5 / 1.75 |
| $weight-normal / -medium / -bold | 400 / 500 / 700 |
Border
| Token | Default |
| --------------- | -------- |
| $radius-sm | 4px |
| $radius-md | 6px |
| $radius-lg | 12px |
| $radius-full | 9999px |
| $border-width | 1px |
Breakpoints
| Token | Default |
| -------- | -------- |
| $bp-sm | 640px |
| $bp-md | 768px |
| $bp-lg | 1024px |
| $bp-xl | 1280px |
Motion
| Token | Default |
| ---------------- | -------------------------------- |
| $duration-fast | 150ms |
| $duration-base | 250ms |
| $duration-slow | 400ms |
| $ease-out | cubic-bezier(0.16, 1, 0.3, 1) |
| $ease-in-out | cubic-bezier(0.65, 0, 0.35, 1) |
Z-index
| Token | Value |
| ------------ | ----- |
| $z-base | 0 |
| $z-raised | 10 |
| $z-overlay | 100 |
| $z-modal | 200 |
| $z-toast | 300 |
Mixin reference
respond-to($bp)
Mobile-first media query using named breakpoints (sm, md, lg, xl).
.sidebar {
display: none;
@include lib.respond-to(md) {
display: block;
}
}visually-hidden
Hides an element visually while keeping it accessible to screen readers.
.sr-only {
@include lib.visually-hidden;
}focus-ring($color, $offset)
Accessible focus indicator. Defaults to $color-primary with a 2px offset.
.input:focus-visible {
@include lib.focus-ring;
}
.input:focus-visible {
@include lib.focus-ring($color: red, $offset: 4px);
}truncate
Single-line text truncation with an ellipsis.
.label {
@include lib.truncate;
}line-clamp($lines)
Multi-line text truncation.
.excerpt {
@include lib.line-clamp(3);
}flex-center($direction)
Centers children with flexbox. Direction defaults to row.
.icon-button {
@include lib.flex-center;
}
.stack {
@include lib.flex-center(column);
}absolute-fill
Stretches an element to fill its nearest positioned ancestor using inset: 0.
.overlay {
position: absolute;
@include lib.absolute-fill;
}transition($props...)
Applies transitions using $duration-base and $ease-out tokens. Accepts one or more CSS properties.
.chip {
@include lib.transition(background, transform, opacity);
}card($padding, $radius)
Applies surface card styling — background, border, border-radius, and padding.
.widget {
@include lib.card;
}
.widget--compact {
@include lib.card($padding: lib.$space-4, $radius: lib.$radius-md);
}button-reset
Strips all browser button styles — useful as a base for custom button components.
.icon-button {
@include lib.button-reset;
}Function reference
rem($px)
Converts a unitless pixel value to rem (assumes 16px root).
font-size: lib.rem(14); // → 0.875remshade($color, $amount)
Mixes a color with black. Replaces the deprecated darken().
background: lib.shade(lib.$color-primary, 20%);tint($color, $amount)
Mixes a color with white. Replaces the deprecated lighten().
background: lib.tint(lib.$color-primary, 80%);z($key)
Looks up a z-index value by name (base, raised, overlay, modal, toast).
z-index: lib.z(modal); // → 200
z-index: lib.z(overlay); // → 100fluid($min-size, $max-size, $min-width, $max-width)
Generates a clamp() expression for fluid type or spacing between two viewport widths. $min-width and $max-width default to 320px and 1280px.
font-size: lib.fluid(14px, 18px);
font-size: lib.fluid(14px, 18px, 480px, 1440px);Contributing
This is a personal library, but if you're forking or adapting it:
- Keep
!defaulton every token — it's what makes overrides work. - Nothing in
abstracts/should emit CSS. Tokens, functions, and mixins only. - Use
@useand@forwardthroughout.@importis deprecated. - Run
npm run checkto confirm the library itself compiles without errors or unwanted output.
