DESIGN SYSTEM

Token-driven, theme-aware design system. 18 themes, runtime switching via CSS variables, and a terminal-inspired aesthetic. Never hardcode colors.

[COLOR TOKENS]

All colors come from semantic CSS variables. Never use Tailwind color utilities like bg-blue-500 — always use tokens so components adapt to theme switching.

BACKGROUND
background
FOREGROUND
foreground
CARD
card
CARD FG
card-foreground
PRIMARY
primary
PRIMARY FG
primary-foreground
SECONDARY
secondary
SECONDARY FG
secondary-foreground
MUTED
muted
MUTED FG
muted-foreground
ACCENT
accent
ACCENT FG
accent-foreground
DESTRUCTIVE
destructive
BORDER
border
INPUT
input
RING
ring
TEXT COLORS
Primary texttext-foreground
Secondary / helper texttext-muted-foreground
Accent / highlight texttext-primary
Error / danger texttext-destructive
Inside card surfacestext-card-foreground
CORRECT — always use semantic tokens
// ✅ Adapts to all 18 themes
className="bg-primary text-primary-foreground"
className="bg-card border-border"
className="text-muted-foreground"

// ❌ Hardcoded — breaks theme switching
className="bg-blue-500 text-white"
className="bg-gray-100 text-gray-900"

[TYPOGRAPHY SCALE]

Terminal aesthetic uses monospace font via mode.font. Apply it to headings, labels, buttons, and badge text. Body text uses the default sans-serif.

THE FIRST UI FRAMEWORKH1 PAGE TITLE
[GETTING STARTED]H2 SECTION
[INSTALL]H3 SUBSECTION
Stop generating 500 lines of custom components.BODY
Optional helper text shown below inputsSMALL / HELPER
import { Button } from "@fabrk/components"CODE
[ACTIVE] [STATUS] [v0.2.0]LABEL / BADGE
> SUBMIT > GET STARTED > SAVE CHANGESBUTTON
FONT USAGE
import { mode } from '@fabrk/design-system'
import { cn } from '@fabrk/core'

// Headlines + labels → mode.font (monospace)
<h1 className={cn("text-2xl font-bold uppercase", mode.font)}>
  PAGE TITLE
</h1>

// Badges + status labels
<span className={cn("text-xs uppercase", mode.font)}>[ACTIVE]</span>

// Body text → no mode.font needed (default sans)
<p className="text-sm text-muted-foreground">
  Description text here.
</p>

[THE MODE OBJECT]

mode from @fabrk/design-system is the primary interface for theme-aware styling. It exposes Tailwind class strings that update with the active theme.

mode.radiusrounded-dynamicBorder radius — apply to every full-border element
mode.fontfont-bodyFont family — apply to headings, labels, buttons
mode.textTransformuppercaseText transform — uppercase for terminal aesthetic
IMPORT
import { mode } from '@fabrk/design-system'
import { cn } from '@fabrk/core'

// Full border card — needs mode.radius
<div className={cn("border border-border bg-card p-4", mode.radius)}>

// Heading — needs mode.font
<h2 className={cn("text-lg font-bold uppercase", mode.font)}>
  [SECTION TITLE]
</h2>

// Button — needs both
<button className={cn(
  "border border-primary bg-primary text-primary-foreground px-4 py-2 text-xs font-bold uppercase",
  mode.font, mode.radius
)}>
  {'>'} SUBMIT
</button>

[BORDER & RADIUS RULES]

The most common source of visual bugs. Follow these rules exactly.

Full border → always add mode.radius
✅ CORRECT
<Card className={cn("border border-border", mode.radius)}>
❌ WRONG
<Card className="border border-border rounded-lg">
Partial border → NEVER add mode.radius
✅ CORRECT
<div className="border-t border-border">
❌ WRONG
<div className={cn("border-t border-border", mode.radius)}>
Table cells → NEVER add mode.radius
✅ CORRECT
<td className="px-3 py-2 border-b border-border">
❌ WRONG
<td className={cn("px-3 py-2", mode.radius)}>
Switch/toggle → always rounded-full
✅ CORRECT
<span className="rounded-full">
❌ WRONG
<span className={cn(mode.radius)}>

[TERMINAL CONVENTIONS]

FABRK uses a consistent terminal-inspired text style. Apply these conventions to all UI text, labels, and interactive elements.

ELEMENTRULEEXAMPLE
UI Labels / BadgesUPPERCASE in brackets[ACTIVE] [STATUS] [v0.2.0] [ON THIS PAGE]
ButtonsUPPERCASE with > prefix> SUBMIT > GET STARTED > SAVE CHANGES
H1 / H2 HeadlinesUPPERCASETHE FIRST UI FRAMEWORK
Body textNormal sentence caseGet started by installing the package.
Error messagesNormal sentence caseSomething went wrong. Please try again.
NEVER USE UNDERSCORES IN UI TEXT
✅ CORRECT
[API KEY]
[LAST SEEN]
[CREATED AT]
❌ WRONG
[api_key]
[last_seen]
[created_at]

[18 THEMES]

All themes use the same semantic CSS variables. Switch themes at runtime with setColorTheme() from useThemeContext(). Use the theme switcher in the sidebar to preview any theme on this page right now.

[CRT]
GREEN
AMBER
BLUE
RED
PURPLE
[RETRO]
GAMEBOY
C64
GBPOCKET
VIC20
ATARI
SPECTRUM
[FUTURE]
CYBERPUNK
PHOSPHOR
HOLOGRAPHIC
NAVIGATOR
BLUEPRINT
INFRARED
[LIGHT]
BW
THEME USAGE
import { useThemeContext } from '@fabrk/design-system'

function MyComponent() {
  const { colorTheme, setColorTheme } = useThemeContext()

  return (
    <button onClick={() => setColorTheme('cyberpunk')}>
      Switch to CYBERPUNK
    </button>
  )
}

// Wrap your app in ThemeWrapper (already done in layout.tsx)
// Theme persists to localStorage via storageKey

[QUICK REFERENCE]

✅ ALWAYS
  • Use semantic tokens: bg-primary, text-foreground
  • Add mode.radius to full-border elements
  • Add mode.font to headings, labels, buttons
  • UPPERCASE button text with > prefix
  • UPPERCASE labels in [BRACKETS]
  • Use spaces in labels: [API KEY]
❌ NEVER
  • Hardcode colors: bg-blue-500, text-white
  • Add mode.radius to partial borders or table cells
  • Use rounded-lg directly (bypass mode.radius)
  • Use underscores in UI text: [api_key]
  • Mix theme tokens: bg-green-900 with semantic tokens