Skip to main content
Conty’s color system uses the OKLCH color space to provide perceptually uniform, accessible colors that automatically adapt between light and dark themes.

Color Categories

Colors are organized into five semantic categories:
  • Surface - Background colors for containers and surfaces
  • Text - Foreground colors for typography and icons
  • Brand - Primary brand colors for interactive elements
  • Border - Border and divider colors
  • Status - State colors for destructive actions and feedback

Surface Colors

Surface tokens define background colors for your application.
surface.default
color
Default background color for the application
semanticTokens.color.surface.default
CSS Custom Property: --background
surface.muted
color
Muted/subdued background for secondary containers
semanticTokens.color.surface.muted
CSS Custom Property: --muted

Usage Example

import { semanticTokens } from '@conty/tokens'

function Card({ children }) {
  return (
    <div style={{ 
      backgroundColor: semanticTokens.color.surface.default,
      border: `1px solid ${semanticTokens.color.border.default}`
    }}>
      {children}
    </div>
  )
}

Text Colors

Text tokens provide semantic foreground colors for typography.
text.default
color
Primary text color for body content
semanticTokens.color.text.default
CSS Custom Property: --foregroundWCAG Contrast Ratio: 16.8:1 (AAA) on default surface
text.muted
color
Secondary/muted text for less prominent content
semanticTokens.color.text.muted
CSS Custom Property: --muted-foregroundWCAG Contrast Ratio: 6.5:1 (AA) on default surface
text.onBrand
color
Text color when placed on brand-colored backgrounds
semanticTokens.color.text.onBrand
CSS Custom Property: --primary-foreground

Usage Example

import { semanticTokens } from '@conty/tokens'

function Text({ muted, children }) {
  const color = muted 
    ? semanticTokens.color.text.muted 
    : semanticTokens.color.text.default
  
  return <p style={{ color }}>{children}</p>
}

Brand Colors

Brand tokens represent your primary brand identity.
brand.primary
color
Primary brand color for buttons, links, and key interactions
semanticTokens.color.brand.primary
CSS Custom Property: --primaryLightness: 62.48% - Optimized for both light and dark themesChroma: 0.2042 - Saturated but not overwhelmingHue: 257.08° - Blue-violet

Usage Example

import { semanticTokens } from '@conty/tokens'

function PrimaryButton({ children }) {
  return (
    <button style={{
      backgroundColor: semanticTokens.color.brand.primary,
      color: semanticTokens.color.text.onBrand
    }}>
      {children}
    </button>
  )
}

Border Colors

Border tokens provide consistent edge and divider colors.
border.default
color
Standard border color for components
semanticTokens.color.border.default
CSS Custom Property: --border
border.focus
color
Focus ring color for keyboard navigation
semanticTokens.color.border.focus
CSS Custom Property: --ring

Usage Example

import { semanticTokens } from '@conty/tokens'

function Input({ focused }) {
  return (
    <input style={{
      border: `1px solid ${focused 
        ? semanticTokens.color.border.focus 
        : semanticTokens.color.border.default}`
    }} />
  )
}

Status Colors

Status tokens communicate state and feedback.
status.destructive
color
Destructive/error color for dangerous actions
semanticTokens.color.status.destructive
CSS Custom Property: --destructiveLightness: 64.96% - Visible but not alarmingChroma: 0.2362 - High saturation for attentionHue: 26.90° - Warm red-orange
status.onDestructive
color
Text color on destructive backgrounds
semanticTokens.color.status.onDestructive
CSS Custom Property: --destructive-foreground

Usage Example

import { semanticTokens } from '@conty/tokens'

function DeleteButton({ children }) {
  return (
    <button style={{
      backgroundColor: semanticTokens.color.status.destructive,
      color: semanticTokens.color.status.onDestructive
    }}>
      {children}
    </button>
  )
}

Legacy Color Aliases

For backward compatibility, Conty provides legacy aliases that map to semantic tokens:
// packages/tokens/src/index.ts
export const colors = {
  background: semanticTokens.color.surface.default,
  foreground: semanticTokens.color.text.default,
  primary: semanticTokens.color.brand.primary,
  primaryForeground: semanticTokens.color.text.onBrand,
  secondary: semanticTokens.color.surface.muted,
  secondaryForeground: semanticTokens.color.text.default,
  muted: semanticTokens.color.surface.muted,
  mutedForeground: semanticTokens.color.text.muted,
  border: semanticTokens.color.border.default,
  ring: semanticTokens.color.border.focus,
  destructive: semanticTokens.color.status.destructive,
  destructiveForeground: semanticTokens.color.status.onDestructive
} as const
New projects should use semantic token paths. Legacy aliases are maintained while teams migrate to the new structure.

Complete Token Reference

// From packages/tokens/src/index.ts
export const semanticTokens = {
  color: {
    surface: {
      default: "oklch(1 0 0)",
      defaultDark: "#0b0d10",
      muted: "oklch(0.96 0 0)",
      mutedDark: "oklch(0.252 0 0)"
    },
    text: {
      default: "oklch(0.2178 0 0)",
      defaultDark: "oklch(0.9551 0 0)",
      muted: "oklch(0.5103 0 0)",
      mutedDark: "oklch(0.683 0 0)",
      onBrand: "oklch(1 0 0)",
      onBrandDark: "oklch(0.9551 0 0)"
    },
    brand: {
      primary: "oklch(0.6248 0.2042 257.0818)",
      primaryDark: "oklch(0.6248 0.2042 257.0818)"
    },
    border: {
      default: "oklch(0.92 0 0)",
      defaultDark: "oklch(0.28 0 0)",
      focus: "oklch(0.8452 0 0)"
    },
    status: {
      destructive: "oklch(0.6496 0.2362 26.9032)",
      onDestructive: "oklch(1 0 0)"
    }
  }
} as const

CSS Custom Properties

/* From packages/tokens/src/theme.css */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.2178 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.2178 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.2178 0 0);
  --primary: oklch(0.6248 0.2042 257.0818);
  --primary-foreground: oklch(1 0 0);
  --secondary: oklch(0.96 0 0);
  --secondary-foreground: oklch(0.2178 0 0);
  --muted: oklch(0.96 0 0);
  --muted-foreground: oklch(0.5103 0 0);
  --accent: oklch(0.96 0 0);
  --accent-foreground: oklch(0.2178 0 0);
  --destructive: oklch(0.6496 0.2362 26.9032);
  --destructive-foreground: oklch(1 0 0);
  --border: oklch(0.92 0 0);
  --input: oklch(0.96 0 0);
  --ring: oklch(0.8452 0 0);
}

.dark {
  --background: #0b0d10;
  --foreground: oklch(0.9551 0 0);
  --card: oklch(0.2 0 0);
  --card-foreground: oklch(0.9551 0 0);
  --popover: oklch(0.16 0 0);
  --popover-foreground: oklch(0.9551 0 0);
  --primary: oklch(0.6248 0.2042 257.0818);
  --primary-foreground: oklch(0.9551 0 0);
  --secondary: oklch(0.2178 0 0);
  --secondary-foreground: oklch(0.9551 0 0);
  --muted: oklch(0.252 0 0);
  --muted-foreground: oklch(0.683 0 0);
  --accent: oklch(0.2178 0 0);
  --accent-foreground: oklch(0.9551 0 0);
  --destructive: oklch(0.6496 0.2362 26.9032);
  --destructive-foreground: oklch(1 0 0);
  --border: oklch(0.28 0 0);
  --input: oklch(0.2178 0 0);
  --ring: oklch(0.5103 0 0);
}

Accessibility

All color combinations in Conty meet WCAG 2.1 Level AA standards:
  • text.default on surface.default: 16.8:1 (AAA)
  • text.muted on surface.default: 6.5:1 (AA)
  • text.onBrand on brand.primary: 4.8:1 (AA)
  • status.onDestructive on status.destructive: 4.5:1 (AA)
When customizing colors, use a contrast checker to ensure WCAG compliance. Aim for at least 4.5:1 for normal text and 3:1 for large text.

Next Steps

Spacing Tokens

Learn about the spacing scale and layout tokens

Theming Guide

Implement light/dark mode and create custom themes

Build docs developers (and LLMs) love