Token Usage

How to use design tokens correctly across components and custom styles.

Overview

Byteion design tokens are CSS variables and Tailwind utility classes that power every component. They keep SaaS dashboards, admin panels, ERP/POS tools, ecommerce back offices, internal tools, templates, starter kits, and plugins visually consistent and themeable.

Every hardcoded value bypasses the token system. If you use bg-blue-500 instead of bg-primary, that element will not respond when the brand colour changes. If you use text-white instead of text-primary-foreground, your button text breaks in a dark primary theme.

Tokens are the contract between design and implementation. This guide explains the token types, the correct class to use for every situation, and how to stay theme-compatible across all Byteion contexts.

Token types

Byteion defines five categories of tokens. Understanding the difference is critical for writing correct, themeable code.

Primitive tokens

Raw colour scales such as primary-500, success-100, danger-700. These map to HSL variables and are used by semantic tokens internally. In public components and docs examples, prefer semantic tokens over primitives.

Semantic tokens

Purpose-based classes such as bg-background, text-foreground, bg-card, text-muted-foreground, border-border, bg-primary, text-primary-foreground, bg-danger, text-danger. These are the primary classes for all surfaces, text, borders, and actions. They survive theme changes automatically.

Component tokens

Component-specific classes for radius, shadow, spacing, and padding: rounded-button, rounded-card, rounded-input, rounded-badge, shadow-card, shadow-modal, shadow-dropdown, shadow-button, p-card. These ensure consistent sizing across all instances of a component.

Runtime tokens

CSS variables defined in packages/core/theme/variables.css. These are the single source of truth for all theme values. Changing --primary updates every component using bg-primary, text-primary-foreground, border-primary, and all related semantic classes.

Build-time tokens

JavaScript token modules in packages/tokens/. Used for programmatic access to token values in React, Vue, and Node.js contexts. Useful for generating charts, CSS-in-JS, or runtime theme switching.

Token categories

Colour and surface tokens

TokenPurpose
bg-backgroundPage-level background
bg-cardCard, surface, container background
bg-mutedSubtle background for disabled, secondary, or de-emphasised areas
bg-primaryPrimary action background
bg-dangerDestructive action background
bg-successSuccess / positive indicator background
bg-warningWarning / caution indicator background

Text tokens

TokenPurpose
text-foregroundPrimary text colour
text-muted-foregroundSecondary / helper / placeholder text
text-primary-foregroundText on primary backgrounds (buttons, badges)
text-dangerError / destructive text
text-successSuccess / positive text
text-warningWarning / caution text

Border and ring tokens

TokenPurpose
border-borderDefault border colour for all surfaces
border-dangerError state border
border-primaryPrimary accent border
ring-primaryFocus ring colour for primary elements
ring-dangerFocus ring colour for error state inputs

Spacing tokens

TokenPurpose
p-cardDefault Card padding
space-y-lg / space-y-smVertical Stack spacing
gap-md / gap-lgGrid gap spacing
px-md / py-smNamed padding sizes

Radius tokens

TokenPurpose
rounded-buttonButton border-radius
rounded-cardCard / surface border-radius
rounded-inputInput / select border-radius
rounded-badgeBadge / label border-radius

Shadow tokens

TokenPurpose
shadow-cardStandard card shadow
shadow-dropdownDropdown / popover shadow
shadow-modalModal / dialog shadow
shadow-buttonButton default shadow

Examples

Good: Token-driven card with button

Every class is a semantic or component token. Spacing is controlled by the parent space-y-* — no margin classes on children. The button uses text-primary-foreground, not text-white.

<div class="space-y-lg rounded-card border border-border bg-card p-card shadow-card">
  <div class="space-y-sm">
    <h3 class="font-semibold text-foreground">Card title</h3>
    <p class="text-muted-foreground">Description text for this card surface.</p>
  </div>
  <button class="rounded-button bg-primary px-md py-sm text-primary-foreground shadow-button hover:bg-primary/90">
    Action
  </button>
</div>

Bad: Hardcoded values that break theming

Every class here is a hardcoded primitive or raw Tailwind utility. This card will not respond to theme changes and breaks in dark mode. Do not copy this pattern.

<!-- BAD: Do not copy -->
<div class="rounded-lg border border-gray-200 bg-white p-6 shadow-md">
  <h3 class="font-semibold text-gray-900">Card title</h3>
  <p class="text-gray-500 mt-2">Description text</p>
  <button class="rounded-lg bg-blue-500 px-4 py-2 text-white mt-4">Action</button>
</div>

Why this fails theming:

  • bg-white — stays white in dark mode instead of switching to bg-card
  • border-gray-200 — hardcoded grey; does not use border-border
  • text-gray-900 / text-gray-500 — hardcoded; does not use text-foreground / text-muted-foreground
  • bg-blue-500 text-white — does not respond to a custom primary colour; ignores text-primary-foreground
  • rounded-lg shadow-md — generic Tailwind utilities; does not use rounded-card / shadow-card
  • mt-2 / mt-4 — individual margins; should be controlled by parent space-y-*
  • p-6 — hardcoded padding; should use p-card

Allowed vs not allowed

Allowed

  • Semantic token classes in shared components (bg-card, text-foreground, border-border)
  • Component tokens for reusable UI (rounded-button, shadow-card, p-card)
  • App-level one-off layout utilities only when they are not part of reusable package code (max-w-4xl, w-72, h-9)
  • Primitive scale tokens in internal palette definitions or when making fine-grained colour adjustments that do not affect theme compatibility

Not allowed

  • Raw colour scales in package components (bg-blue-500, text-gray-700)
  • Hex colours in shared components (bg-[#123456], text-[#abc])
  • Arbitrary values in reusable components (p-[13px], m-[4px], shadow-[0_0_0_1px_#eee])
  • Mixing token and hardcoded values in the same component (e.g., bg-card border-gray-200)
  • Using text-white on primary buttons instead of text-primary-foreground

Theming and white-labeling

Byteion's token architecture makes white-labeling and theming a configuration change, not a code rewrite.

  • Changing --primary in variables.css updates every component using bg-primary, text-primary-foreground, border-primary, ring-primary, and all related semantic classes — zero HTML changes needed.
  • Client-specific branding should happen through variables.css or theme overrides, not by editing component HTML. Override --primary, --background, --card, and other surface tokens per client.
  • HSL values are required for all colour CSS variables. Without HSL, alpha utilities like bg-primary/10, ring-primary/20, and border-primary/30 will not work. The format is hsl(var(--primary) / <alpha-value>).

Practical scenarios

White-labeling a client dashboard

Create a client-variables.css file that overrides --primary, --primary-foreground, --background, and --card. Load it after the base theme. Every bg-primary, text-foreground, and bg-card class in every component updates automatically. No component HTML changes. No search-and-replace.

Creating a new dashboard card

Start from the token-driven card pattern: rounded-card border border-border bg-card p-card shadow-card. Add a space-y-* stack inside for the title, metric value, and trend indicator. If you need a coloured accent use bg-primary/10 text-primary or bg-success/10 text-success — never bg-blue-100 text-blue-700.

Building an ecommerce admin form

Use rounded-card border border-border bg-card p-card shadow-card as the form container. Inside, use space-y-4 for field groups. Each input uses rounded-input border border-border bg-background px-3 py-2 text-sm text-foreground with focus:border-primary focus:ring-2 focus:ring-primary/20. Buttons use rounded-button bg-primary px-4 py-2 text-primary-foreground. No border-gray-300, no bg-white, no text-white.

Adding a new status badge

Use inline-flex rounded-badge px-2 py-0.5 text-xs font-medium plus a semantic background: bg-success/10 text-success for active, bg-warning/10 text-warning for pending, bg-danger/10 text-danger for blocked, bg-muted text-muted-foreground for inactive. Never bg-green-100 text-green-700 — those break in dark mode and custom themes.

Creating a custom plugin while staying theme-compatible

Use only Byteion semantic tokens in your plugin markup. Reference bg-card, text-foreground, border-border, and rounded-card for surfaces. Let the host application's theme control colours. Do not hardcode any colour, radius, shadow, or spacing value. Test your plugin with the default theme, a dark theme, and a custom-branded theme.

Token audit checklist

Search your codebase for these patterns to find token violations. Replace each with the recommended semantic alternative.

Search forReplace with
bg-gray-*bg-background, bg-card, bg-muted
text-gray-*text-foreground, text-muted-foreground
border-gray-*border-border
bg-blue-* / bg-red-*bg-primary, bg-danger, bg-success, bg-warning
text-blue-* / text-red-*text-primary, text-danger, text-success, text-warning
border-blue-*border-primary, border-danger
text-whitetext-primary-foreground
bg-whitebg-background, bg-card
#[0-9a-fA-F]Semantic token class
p-[*] / m-[*]Spacing scale or p-card
rounded-lgrounded-card, rounded-button, rounded-input
shadow-md / shadow-lgshadow-card, shadow-modal, shadow-dropdown

Do and Don't

Do

  • Use semantic tokens for surfaces, text, borders, rings, and actions
  • Use component-specific radius, spacing, and shadow tokens
  • Add missing reusable values to the token system before using them
  • Test token changes in light and dark mode
  • Keep shared package components free from hardcoded visual values
  • Use text-primary-foreground on primary backgrounds

Don't

  • Use raw Tailwind colour scales in shared components
  • Use text-white for primary actions — text-primary-foreground exists
  • Use arbitrary values (p-[*], bg-[*]) in reusable package code
  • Mix hardcoded values and tokens in the same component
  • Rebrand by editing every component manually — override theme variables instead
  • Use rounded-lg when rounded-card or rounded-button are available

Developer tips

Start from variables.css for runtime theme changes. The complete runtime token reference is in packages/core/theme/variables.css. Change a CSS variable, update every component.

Start from packages/tokens for build-time token changes. The JavaScript token modules let you reference token values programmatically for charts, CSS-in-JS, or server-side rendering.

Use semantic names based on purpose, not colour appearance. Name tokens for what they do (bg-danger, text-success), not what they look like (bg-red, text-green). This makes theme swaps meaningful.

Prefer "danger" over "red" and "primary" over "blue". A danger action may not be red in your brand. Semantic naming keeps the system flexible.

Test token changes against contrast and dark mode. A token that works in light mode may lose contrast in dark mode. Verify WCAG AA ratios for all foreground-background token combinations.

Use docs examples as token-compliant copy-paste patterns. Every component page in these docs uses only Byteion semantic and component tokens. Paste any example directly into your project.

Audit your codebase regularly. Search for bg-gray-, text-gray-, border-gray-, text-white, bg-white, rounded-lg, shadow-md, and #[0-9a-fA-F] — these are token violations that accumulate over time.

HSL format is mandatory. All colour CSS variables must use HSL format. Without it, alpha utilities (bg-primary/10, ring-primary/20) will not work. Check that your custom variables follow the pattern hsl(var(--name) / <alpha-value>).

Unlock Premium Patterns

Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.

Explore Pro Components