npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unwreck/core

v1.0.1

Published

Design tokens, themes, fonts, and CSS reset for unwreck

Readme

@unwreck/core

@unwreck/core is the design system foundation for everything under the unwreck brand. It's the source of truth for colors, type, spacing and motion across all my projects, so I stop rebuilding the same buttons and color logic every time I start something new.

It takes a small set of design primitives (colors, typography, spacing, shadows, motion) and compiles them into whatever format a given repo needs: CSS custom properties, a Tailwind v4 theme, W3C DTCG tokens, or typed TypeScript constants.


What is this?

The goal was to make the architecture the actual product, not just a pile of hex codes. Every output format (CSS, Tailwind, JSON, TS) is generated from one source instead of hand maintained separately.

  • Perceptual OKLCH color scales. Colors are generated in OKLCH using Culori, 12 steps per scale with contrast that progresses uniformly instead of me eyeballing it.
  • Automated WCAG contrast solver. Solid steps (buttons, badges) get run through the solver at build time to enforce a 4.5:1 minimum on text fills, in both light and dark mode. If an accent doesn't clear it, the emitter adjusts the foreground token instead of me catching it later.
  • Multi target emitters. One source of truth outputs CSS variables (--uw-*), a Tailwind v4 @theme inline config, DTCG JSON, and typed TS constants.
  • Zero FOUC theme manager. Handles light / dark / system preferences synced across tabs via localStorage. There's also a Vite plugin that kills the flash of unstyled content on first paint.

Why was this made?

I kept rebuilding the same buttons, cards and color logic for every project on the unwreck roadmap, and it was never consistent. Slightly different grays each time, no shared source of truth, contrast I never actually verified.

My internship's internal vue-core package is where the idea came from, but I wanted something framework agnostic from the start since not everything I build is Vue.

The real reason though was accessibility. I got tired of manually checking contrast ratios every time I picked a new accent color. Baking the contrast solver into the generator means I pick an anchor color once and the system guarantees the rest is readable.


Distribution Targets

All distribution artifacts are exported under subpaths:

| Target | Import Path | Output File | Description | | :---------------- | :-------------------------- | :------------------- | :--------------------------------------------------------------------- | | CSS Variables | @unwreck/core/css | dist/tokens.css | :root, [data-theme="light"], and [data-theme="dark"] tokens. | | Tailwind v4 | @unwreck/core/tailwind | dist/tailwind.css | @theme inline mappings and dark mode variant. | | CSS Reset | @unwreck/core/reset | dist/reset.css | Modern CSS reset with reduced motion defaults. | | Fonts | @unwreck/core/fonts.css | dist/fonts/all.css | Self hosted variable fonts with zero layout shift fallbacks. | | TypeScript | @unwreck/core | dist/index.js | Strongly typed token values, cssVar() helper, and TokenName union. | | Theme Runtime | @unwreck/core/theme | dist/theme.js | Theme preference getter/setter, listeners, and DOM reader. | | Vite Plugin | @unwreck/core/vite | dist/vite.js | Injects blocking theme initialization script into <head>. | | DTCG JSON | @unwreck/core/tokens.json | dist/tokens.json | Standard W3C Design Tokens Community Group JSON format. |


Getting Started

1. Installation

pnpm add @unwreck/core
# or
npm install @unwreck/core

2. CSS Setup

Import the reset, fonts and token variables into your application entrypoint:

import "@unwreck/core/reset";
import "@unwreck/core/fonts.css";
import "@unwreck/core/css";

Or via plain CSS:

@import "@unwreck/core/reset";
@import "@unwreck/core/fonts.css";
@import "@unwreck/core/css";

3. Tailwind CSS v4 Setup

If you're using Tailwind v4, import the theme definition in your main stylesheet:

@import "tailwindcss";
@import "@unwreck/core/css";
@import "@unwreck/core/tailwind";

This registers all token aliases under --color-*, --radius-*, --font-*, and gives you the @custom-variant dark matching [data-theme="dark"].

4. Vite Plugin (Prevent Flash of Unstyled Theme)

In vite.config.ts, add the unwreck plugin to inject a synchronous theme resolver into the HTML <head> before render:

import { defineConfig } from "vite";
import { unwreck } from "@unwreck/core/vite";

export default defineConfig({
  plugins: [unwreck()],
});

Token Subsystems

1. Color Engine

The color system is built from 6 primary scales. Each scale defines light and dark modes across 12 perceptual steps:

  • brand (Anchor: #439124): Primary brand accents.
  • neutral (Derived from brand with low chroma): Warm, brand tinted structural grays.
  • success (Anchor: #12A150): Positive states and confirmations (guaranteed dark text on solid).
  • warning (Anchor: #D9A000): Cautions and alerts (guaranteed dark text on solid).
  • danger (Anchor: #D62C2C): Errors and destructive actions (guaranteed light text on solid).
  • info (Anchor: #2E7FD4): Informational highlights and guidance.

The 12-Step Scale Roles

| Step | Role | Intended Usage | | :----: | :----------------------- | :--------------------------------------------------------------------------------------------- | | 1 | App Canvas Background | Base page background (--uw-bg-canvas) | | 2 | Subtle Background | Code wells, hovered canvas (--uw-bg-subtle) | | 3 | Component Surface | Cards, panels, input backgrounds (--uw-bg-surface, *-bg) | | 4 | Component Surface Hover | Hover state for cards and subtle buttons (*-bg-hover) | | 5 | Component Surface Active | Active/pressed state for subtle elements (--uw-bg-surface-active) | | 6 | Subtle Border | Low contrast dividers and separators (--uw-border-subtle) | | 7 | Component Border | Standard inputs, card outlines, checkboxes (--uw-border-default, *-border) | | 8 | Strong Border | Hovered borders, active input outlines (--uw-border-strong) | | 9 | Solid Accent | Primary buttons, filled badges (*-solid), guaranteed 4.5:1 minimum against *-on-solid | | 10 | Solid Accent Hover | Hovered state for primary buttons (*-solid-hover) | | 11 | High-Contrast Text | Colored badges, link text, labels (*-fg), guaranteed 4.5:1 minimum against steps 1 to 3 | | 12 | Maximum-Contrast Text | Primary body text, headings (--uw-fg-default), guaranteed 7.0:1 minimum against steps 1 to 2 |

Universal Accent Pattern (7 Tokens per Scale)

Every color scale exposes the same 7 token component API:

var(--uw-{scale}-bg)          /* Step 3: subtle component background */
var(--uw-{scale}-bg-hover)    /* Step 4: subtle background hover */
var(--uw-{scale}-border)      /* Step 7: interactive border */
var(--uw-{scale}-solid)       /* Step 9: solid fill */
var(--uw-{scale}-solid-hover) /* Step 10: solid fill hover */
var(--uw-{scale}-fg)          /* Step 11: readable text on subtle surfaces */
var(--uw-{scale}-on-solid)    /* Solved accessible text on solid fill */

2. Typography & Fonts

Three self hosted variable font families, with fallback metric overrides (ascent-override, descent-override, size-adjust) pre calculated so there's no layout shift:

  • Sans: Inter (--uw-font-sans)
  • Display: Bricolage Grotesque (--uw-font-display)
  • Mono: JetBrains Mono (--uw-font-mono)

Font sizes from 2xl through 6xl use fluid viewport clamping (clamp(...)) so they scale smoothly between mobile and desktop.

3. Spacing & Radius

  • Space: 4px grid (1 = 0.25rem, 2 = 0.5rem, up to 48 = 12rem, plus px and 0-5).
  • Radius: none, xs, sm, md, lg, xl, 2xl, full.

4. Elevation & Shadows

Shadows (sm, md, lg) are dynamically tinted in OKLCH using the neutral scale's hue. Light mode gets soft multi layer shadows, dark mode gets deeper black based ones with higher opacity.

5. Motion

  • Durations: instant (0ms), fast (100ms), normal (200ms), slow (300ms), slower (400ms).
  • Easings: standard, emphasized, decelerate, accelerate.

Runtime Theme API

The theme runtime manages theme preferences and syncs changes across browser tabs:

import {
  getPreference,
  setTheme,
  resolve,
  subscribe,
  readToken,
} from "@unwreck/core/theme";

// Get user preference: 'light' | 'dark' | 'system'
const pref = getPreference();

// Set preference (stored in localStorage under 'uw-theme')
setTheme("dark");

// Resolve current theme against system preference: 'light' | 'dark'
const activeTheme = resolve();

// Subscribe to changes (syncs across tabs and system OS switches)
const unsubscribe = subscribe((newTheme) => {
  console.log("Active theme changed to:", newTheme);
});

// Read computed CSS variable from the DOM
const primaryColor = readToken("brand-solid");

Verification

All contrast invariants, perceptual bounds, and entrypoint types are verified automatically before every build and publish via Vitest and publint.