@fresh-ds/tokens
v0.1.4
Published
Authority for all reusable visual values in Fresh. Used by components, recipes, and product code across all platforms.
Readme
@fresh-ds/tokens
Authority for all reusable visual values in Fresh. Used by components, recipes, and product code across all platforms.
Token Layers
Two distinct layers that should never be mixed casually:
1. Raw Tokens
Use only when defining semantic roles. Neutral building blocks:
| Category | Examples |
| -------------- | ------------------------------------------ |
| Color families | neutral.900, accent.600, success.500 |
| Spacing scale | 4, 8, 12, 16 (pixels) |
| Radius scale | sm, md, lg, full |
| Typography | text.sm, font.semibold |
2. Semantic Tokens
Use everywhere else. Intent-based names that survive brand changes:
| Role | Purpose | Examples |
| ---------- | ---------------------------------------- | -------------------------------------- |
| canvas | App and page backgrounds | canvas.default, canvas.overlay |
| surface | Contained UI (cards, sections, disabled) | surface.default, surface.brand |
| border | Separators, outlines, focus | border.default, border.brand |
| content | Text and icon foregrounds | content.primary, content.brand |
| action | Interactive surfaces | action.brand, action.danger |
| feedback | Status communication | feedback.success, feedback.warning |
| input | Field-specific roles | input.placeholder, input.border |
Usage by Platform
React Native / Expo
import { useFreshTheme } from '@fresh-ds/ui';
function MyComponent() {
const theme = useFreshTheme();
// theme.color.surface.default
// theme.spacing['4'] // 16px
}Or with NativeWind:
<Box className="bg-surface-default p-4 rounded-lg" />Next.js
Import CSS variables:
@import '@fresh-ds/tokens/tokens.css';
.card {
background: var(--surface-default);
border: var(--border-width-default) solid var(--border-default);
border-radius: var(--radius-lg);
padding: var(--spacing-4);
color: var(--content-primary);
box-shadow: var(--shadow-1);
}Phoenix / LiveView
CSS variables are available when tokens are loaded:
@import '../vendor/tokens/tokens.css'; /* Vendored from contract/tokens/ */Or use the classes from platforms/phoenix/assets/css/fresh.css which reference these variables.
Exports
| File | Format | Use Case |
| ------------------- | --------------------- | --------------------------- |
| tokens.css | CSS custom properties | Web projects, Phoenix |
| tokens.json | W3C Design Tokens | Design tools, Figma plugins |
| reset.css | CSS reset | Keyboard-only focus rings |
| src/index.ts | TypeScript objects | Component implementations |
| src/nativewind.ts | Tailwind preset | RN with NativeWind |
Generation
Tokens are generated from source. Don't edit tokens.css or tokens.json directly:
npm run generate:tokens # Regenerates tokens.css and tokens.jsonSource files in src/:
colors.ts— Raw color palettesspacing.ts— Spacing scaleradius.ts— Border radius scaletypography.ts— Font stacks, sizes, weightselevation.ts— Shadowssemantic.ts— Semantic token mappings
Dark Mode
Automatic via prefers-color-scheme:
/* In tokens.css */
@media (prefers-color-scheme: dark) {
:root {
--canvas-default: var(--color-neutral-900);
--surface-default: var(--color-neutral-800);
/* ... */
}
}Or manual with .dark class on container.
Rules
- Product code: Never import raw palettes. Use semantic tokens.
- Component code: Choose semantic intent first, map variants to that intent.
- New brands: Raw values change without renaming semantic callers.
- New patterns: Add semantic roles instead of bypassing with inline values.
Verification
# Regenerate exports
npm run generate:tokens
# Check token output
cat tokens.css | grep --color "surface-default"
# Typecheck token TypeScript
npm run typecheck --workspace @fresh-ds/tokens
# Test token usage
npm run test --workspace @fresh-ds/tokensVisual verification:
- Open showcase app
- Inspect a card surface
- Confirm
background: var(--surface-default)in devtools - Verify color matches between light/dark modes
What Belongs Here
- Token source definitions (colors, spacing, radius, typography, elevation, semantic)
- Generated exports (CSS, JSON, TypeScript)
- Generation scripts
What Does NOT Belong Here
- Component implementations — lives in
platforms/ - Visual design rules — lives in
docs/visual-recipe.md - Brand guidelines — lives in
docs/brand.md
Related
| Doc | Purpose |
| -------------------------- | --------------------------------- |
| ../docs/visual-recipe.md | Visual design rules and rationale |
| ../docs/brand.md | Brand guidelines and character |
| ../contract/README.md | Contract layer overview |
