Design SystemUpdated April 27, 2026

Colors

Semantic color roles, theming architecture, and usage guidelines used across PyColors UI.

OverviewLink to section

Colors in PyColors UI are designed as semantic product roles, not decorative values.

The system gives every interface layer a stable meaning: page surfaces, cards, text, actions, states, borders, form controls, sidebars, and charts. Components consume those roles through utilities like bg-card, text-foreground, text-muted-foreground, bg-primary, and border-border instead of hardcoding visual values locally.

At the end of this page, you will understand how PyColors structures color roles, how light and dark mode remain predictable, and how to apply color decisions without creating theme drift.

Why this matters

Color consistency is one of the fastest signals of product quality. A semantic color system keeps dashboards, marketing pages, documentation, forms, and reusable components visually aligned without forcing every component to reinvent its own palette.

Role first
Describe intent

Use tokens that explain product meaning: surface, text, action, state, input, and data.

Theme safe
Change centrally

Map CSS variables into Tailwind utilities so components stay stable when themes evolve.

Production ready
Scale consistently

Keep reusable components, dashboards, docs, and commercial pages visually coherent.

What you’ll doLink to section

Understand the semantic role model behind PyColors colors.

Map CSS variables to Tailwind utilities through the token layer.

Apply colors in components without raw values or one-off overrides.

Use decision rules to keep UI colors, state colors, and chart colors separate.

ArchitectureLink to section

PyColors uses an OKLCH-based color system exposed through CSS variables and mapped into Tailwind semantic utilities.

OKLCH gives the token layer more predictable control over perceived lightness, contrast, and theme balance than raw RGB or one-off HSL values. That matters when a product must support light mode, dark mode, reusable UI components, long documentation pages, dashboards, settings screens, and commercial surfaces.

Core principle

Components should consume color roles. The token layer should decide how those roles look.

tokens.css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-border: var(--border);
  --color-ring: var(--ring);
}
example-card.tsx
export function ExampleCard() {
  return (
    <div className="rounded-2xl border border-border bg-card p-5 text-card-foreground">
      <p className="text-sm font-medium text-foreground">Semantic surface</p>
      <p className="mt-1 text-sm text-muted-foreground">
        This component uses product roles instead of raw color values.
      </p>
    </div>
  );
}
themes.css
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.141 0.005 285.823);
  --primary: oklch(0.21 0.006 285.885);
  --primary-foreground: oklch(0.985 0 0);
}

.dark {
  --background: oklch(0.141 0.005 285.823);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.92 0.004 286.32);
  --primary-foreground: oklch(0.21 0.006 285.885);
}

This keeps the component API stable while allowing the underlying theme to evolve centrally. Components keep the same classes, token meaning stays stable, and the theme layer handles contrast and visual balance.

Role modelLink to section

PyColors groups colors by product responsibility. This keeps the system easier to reason about and prevents the table of contents from becoming noisy.

CategoryTokensUsed for
Surfacesbackground, card, popover, sidebarPage layers, cards, overlays, navigation
Textforeground, muted-foreground, card-foregroundPrimary copy, secondary copy, surface-specific text
Actionsprimary, secondary, accent, mutedButtons, emphasis, subtle interaction areas
Statesdestructive, success, warningProduct feedback, validation, risk, confirmation
Inputsborder, input, ringForms, focus states, separators, control outlines
Chartschart-1 to chart-5Data visualization only

Why this matters

Separating UI roles from chart roles prevents data visualization colors from leaking into product states. A chart palette should not become the source of truth for buttons, alerts, or destructive actions.

background
card
primary
secondary
accent
muted
destructive
success
warning
border

ImplementationLink to section

Use semantic utilities in every reusable component.

recommended.tsx
export function ProductNotice() {
  return (
    <div className="rounded-2xl border border-border bg-card p-5 text-card-foreground">
      <p className="text-sm font-medium text-foreground">Production-ready surface</p>
      <p className="mt-1 text-sm text-muted-foreground">
        The visual intent comes from the design system, not from local overrides.
      </p>
    </div>
  );
}

Avoid raw values inside reusable UI.

avoid.tsx
export function ProductNotice() {
  return (
    <div className="rounded-2xl border border-[#e5e7eb] bg-[#ffffff] p-5 text-[#111827]">
      <p className="text-sm text-[#6b7280]">This creates theme drift.</p>
    </div>
  );
}

Common pitfall

Do not solve repeated color needs with local overrides. If the same visual intent appears in multiple places, define or adjust the semantic role instead.

Decision guideLink to section

Use PyColors semantic color roles when:

  • the component is reusable
  • the UI must support light and dark mode
  • the surface appears in dashboards, docs, marketing, or settings
  • the same visual meaning should remain stable across the product
  • theme updates should happen centrally

Avoid local raw values when:

  • the component belongs to the design system
  • the value represents a product state
  • the color affects text contrast or focus visibility
  • the color will likely be reused elsewhere
  • the value needs to survive future theme changes

Inline CTA

Ready to move from visual consistency to a production-shaped SaaS foundation? Explore Starter Pro for auth, billing, backend, and delivery patterns built on top of PyColors UI.

Common mistakesLink to section

Next stepsLink to section