Design Tokens
The foundational token system that powers all visual consistency across Byteion components.
Overview
Design tokens are the atomic values that power every visual aspect of Byteion. They are the single source of truth for colors, spacing, typography, shadows, borders, and motion. Instead of hardcoding values like #3b82f6 or 0.5rem, components reference semantic tokens like bg-primary and spacing values like p-md. This ensures visual consistency across every screen and enables systematic re-theming without touching component markup.
Why this exists
Without tokens, changing a brand color requires searching for every occurrence of bg-blue-500 and text-blue-600 across 50+ components. With tokens, you change one CSS variable (--primary) and every component that references it updates simultaneously. This is not just about efficiency — it ensures that the entire system responds to a change in a predictable, consistent way. Tokens also create a shared vocabulary between designers and developers: when a designer says "use the primary color", the developer reaches for bg-primary, not bg-blue-500.
System philosophy
Consistency rules
- Prefer semantic tokens in components. Shared component styling should use Byteion tokens for visual decisions such as color, spacing, radius, shadow, typography, and motion. Structural Tailwind utilities are allowed when they describe layout behavior rather than brand or design values.
- Semantic naming. Tokens describe purpose, not appearance. Use
bg-backgroundnotbg-white,text-foregroundnottext-gray-900. - Scale-based values. When a token is not available, add it to the scale before using arbitrary values in shared components.
Scaling logic
Tokens are organized in scales that grow predictably. The spacing scale follows 0.25rem increments. Color scales (50-950) are designed to support accessible foreground/background combinations. Semantic foreground/background pairs should be tested for sufficient contrast, especially after custom theme overrides.
Shared vocabulary
Tokens create a vocabulary that designers and developers share. When a designer says "use the primary color", the developer knows exactly which token to use (bg-primary). When a developer needs a subtle border, they reach for border-border. This shared language eliminates interpretation errors and ensures consistent implementation.
Token layers
Tokens exist in three layers, each serving a distinct role:
| Layer | File | Purpose |
|---|---|---|
| JS tokens | packages/tokens/*.js | Build-time source of truth — defines scales, defaults, and the shape of the design system |
| CSS variables | packages/core/theme/variables.css | Runtime theming layer — override at the CSS level for white-label or multi-brand themes |
| Tailwind preset | packages/core/tailwind.preset.cjs | Maps tokens into utility classes (bg-background, shadow-card, rounded-button) |
Token types
Byteion defines three categories of tokens, each with a different purpose and audience:
Primitive / scale tokens
Raw values organized in steps. Used to build the system and define new semantic aliases.
primary-50throughprimary-950spacing-sm,spacing-md,spacing-lgshadow-sm,shadow-xs- Utility:
bg-primary-500,p-4
Semantic tokens
Named by purpose, not value. Used in components and application UI for consistent theming.
bg-primary,text-primary-foregroundbg-background,bg-cardborder-border,ring-ringtext-muted-foreground
Component tokens
Target specific component families. Keeps radii, shadows, and spacing consistent per component type.
rounded-button,rounded-cardshadow-card,shadow-dropdownshadow-button,shadow-button-hoverp-inset-sm,gap-stack-md
Naming system
Tokens follow a consistent naming pattern:
- bg-primary — Semantic background (brand color)
- text-muted-foreground — Muted text color (semantic)
- border-border — Border color (semantic)
- rounded-card — Card border radius (component token)
- bg-primary-500 — Primary at scale step 500 (primitive)
- p-md — Medium padding from spacing scale
Categories
Colors
Controls surface backgrounds, text, borders, focus rings, and brand accents. Every component uses color tokens for its visual state.
bg-background,text-foreground— Page surfacebg-card,text-card-foreground— Card surfacesbg-primary,text-primary-foreground— Brand actionsborder-border,ring-ring— Chrome
Spacing
Controls padding, margin, gap, and layout density. Used by every component's internal and external spacing.
p-inset-sm— Button / input paddinggap-stack-md— Vertical spacing between itemsp-surface-card— Card inner padding
Radius
Controls corner rounding per component family. Each component has a dedicated token.
rounded-button(0.5rem) — Buttonsrounded-card(0.75rem) — Cards, panelsrounded-input(0.5rem) — Inputs, selectsrounded-badge(9999px) — Badges, pills, tags
Shadows
Controls elevation and interactive state feedback. Component-specific tokens target the right context.
shadow-card— Default card elevationshadow-button— Button default / hovershadow-dropdown— Menu / popover surfacesshadow-modal— Modal / dialog elevation
Typography
Controls font family, size, weight, line height, and letter spacing across headings, body text, and code.
font-sans(Inter) — Product UIfont-mono(JetBrains Mono) — Codetext-sm,text-base,text-lg— Size scalefont-medium,font-semibold,font-bold— Weights
Motion
Controls transition durations and easing curves for interactions, animations, and micro-interactions.
duration-fast(120ms) — Hover statesduration-normal(200ms) — Default transitionsease-out-soft— Entry animationsease-spring— Scale / pop effects
Practical usage
Developers use tokens through Tailwind utility classes. Always prefer semantic and component tokens over raw scale steps in shared components:
<!-- Button using semantic tokens -->
<button class="inline-flex items-center gap-2 rounded-button bg-primary px-md py-sm text-primary-foreground shadow-button hover:bg-primary/90">
Save changes
</button>
<!-- Card using surface and component tokens -->
<div class="rounded-card border border-border bg-card shadow-card">
<div class="p-surface-card">
<h3 class="font-semibold text-foreground">Card title</h3>
<p class="text-muted-foreground mt-2">Card body content goes here.</p>
</div>
</div>
<!-- Badge using component tokens -->
<span class="inline-flex items-center rounded-badge bg-primary/10 px-inset-xs py-0.5 text-xs font-medium text-primary">
Active
</span>
Behind the scenes
Each utility class is backed by a CSS variable. The / <alpha-value> syntax enables Tailwind's opacity modifier (bg-primary/50):
/* Semantic color mapping */
.bg-primary {
background-color: hsl(var(--primary) / <alpha-value>);
}
.text-primary-foreground {
color: hsl(var(--primary-foreground) / <alpha-value>);
}
.bg-card {
background-color: hsl(var(--card) / <alpha-value>);
}
/* Component token mapping */
.rounded-card {
border-radius: var(--radius-card);
}
.shadow-card {
box-shadow: var(--shadow-card);
}
.rounded-button {
border-radius: var(--radius-button);
}
/* Spacing mapping */
.px-md {
padding-left: var(--spacing-md, 1rem);
padding-right: var(--spacing-md, 1rem);
}
Color CSS variables store raw HSL channel values (hue saturation% lightness%) without the hsl() wrapper. This is required for Tailwind's alpha-value syntax:
:root {
/* Correct — raw HSL channels enable bg-primary/50 */
--primary: 217 91% 60%;
--primary-foreground: 0 0% 100%;
/* Component tokens store full values */
--radius-card: 0.75rem;
--shadow-card: 0 1px 3px 0 rgb(0 0 0 / 0.04), 0 1px 2px -1px rgb(0 0 0 / 0.04);
}
Semantic vs scale tokens
Choosing the right token type depends on context:
Use semantic tokens when
- Building shared components (
bg-primary,text-foreground) - Writing application UI that should theme automatically
- Referencing component-specific values (
rounded-card,shadow-button) - Setting surface, text, border, and ring colors in layouts
Use scale tokens when
- Defining the design language or creating new semantic aliases
- Building charts, data visualizations, or custom graphics
- Extending the system with new component tokens
- Applying a specific scale step with a clear rationale
Avoid using raw scale steps (e.g. bg-primary-500) everywhere in application UI unless the purpose is clear. Prefer bg-primary so that a brand theme override of --primary flows through automatically.
Do and Don't
Do
- Use semantic tokens in shared components (
bg-background,text-foreground) - Use component-specific radii and shadows (
rounded-button,shadow-card) - Use spacing tokens from the scale (
p-inset-sm,gap-stack-md) - Use
bg-primaryinstead ofbg-primary-500in UI components - Refer to the token reference when uncertain about a value
Don't
- Use arbitrary values (
bg-[#3b82f6],p-[13px]) in shared components - Use raw Tailwind color steps (
bg-blue-500) — use semantic tokens instead - Create new spacing values without first checking the token scale
- Use
text-whitewhentext-primary-foregroundis the correct semantic token - Mix primitive and semantic tokens in the same component without purpose
Customization
Override tokens by redefining CSS variables in your project. This is the recommended approach for white-label theming because it requires no component markup changes:
/* Override semantic tokens for a white-label theme */
:root {
--primary: 270 100% 50%;
--primary-foreground: 0 0% 100%;
--radius-card: 0.75rem;
--shadow-card: 0 4px 12px rgb(0 0 0 / 0.08);
}
Each layer serves a different customization scenario:
- CSS variables — Runtime customization. Change at the
:rootlevel for immediate visual updates. Best for multi-brand or white-label themes. - JS tokens — Build-time source. Edit the token files in
packages/tokens/when you need to change the foundation of the system. - Tailwind preset — Maps both into utility classes. Extend the preset to add new tokens or override existing mappings.
To add entirely new tokens, extend the Tailwind preset:
const byteionPreset = require('@byteion/core/preset');
module.exports = {
presets: [byteionPreset],
theme: {
extend: {
colors: {
brand: {
50: '#eff6ff',
500: '#3b82f6',
900: '#1e3a8a',
},
},
},
},
};
For advanced multi-brand theme setup, see the Theming Guide.
Relationship to components
Every Byteion component uses tokens internally. Components never hardcode values — they reference semantic and component tokens throughout:
Button
bg-primary— Primary variant backgroundtext-primary-foreground— Text on primaryrounded-button— Border radiuspx-md py-sm— Paddingshadow-button— Default shadowhover:shadow-button-hover— Hover shadow
Card
bg-card— Card surfacetext-card-foreground— Card textborder-border— Card borderrounded-card— Border radiusshadow-card— Elevation
When you change a token, every component that uses it updates. Change --primary and all primary buttons, links, focus rings, and active indicators update simultaneously. Change --radius-card and every card across the application adopts the new rounding — no markup changes needed.
Token dependency tree
Developer tips
bg-primary/50). Never store hex values in CSS variables.
• Use semantic names. When you see bg-white, replace it with bg-background — it adapts to dark mode automatically.
• Semantic tokens survive rebranding. A component using bg-primary responds to a --primary variable change. A component using bg-primary-500 requires a preset rebuild.
• Check the reference. Before creating a new color or spacing value, verify it does not already exist in the token system.
• Use bg-primary over bg-primary-500. The semantic alias follows brand theme overrides; the scale step does not.Common mistakes
- Using
bg-blue-500in shared components. This hardcodes a Tailwind color that ignores your brand overrides. Usebg-primaryinstead. - Using
text-whiteon primary buttons. In dark mode or with a custom brand,text-whitemay lack contrast. Usetext-primary-foreground. - Editing component markup instead of tokens. If you need rounded cards, change
--radius-cardin CSS, not therounded-*class on every card instance. - Creating one-off spacing values. Adding
p-[13px]breaks the spacing rhythm. Use the existing scale or propose a new token. - Mixing primitive and semantic tokens without purpose. A component that uses both
bg-backgroundandbg-primary-500may behave inconsistently when themes change. - Forgetting dark mode variables. Custom CSS variable overrides should be mirrored in a
.darkor[data-theme="dark"]block unless the value is mode-agnostic.
Production usage tips
- Test dark mode after token changes. Every
--backgroundand--foregroundoverride needs a corresponding dark-mode value to maintain readability. - Test brand themes after overriding CSS variables. Verify that all components that use
bg-primary,text-primary-foreground, andborder-primaryreflect the new values. - Run contrast checks. After changing foreground/background pairs, test WCAG contrast ratios. Tools like the WebAIM contrast checker can validate your combinations.
- Keep framework examples aligned. React and Vue components use the same token classes as HTML. The utility classes are framework-agnostic.
- Avoid primitive color utilities in shared source. Importing
bg-primary-500in a component library may bypass theme overrides. Stick to semantic aliases in shared code.
Related
- CSS Variables — Complete reference of all CSS custom properties
- Theming Guide — Multi-brand and advanced theme setup
- Colors — Color token system and palette
- Spacing — Spacing scale reference
- Shadows — Shadow token reference
- Tailwind Preset — Preset configuration details
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.
Explore Pro Components