Skip to content

Color System

Vetra UI's color system uses intuitive, semantic naming that makes it easy to understand and use. Unlike Material Design's technical color roles, Vetra colors are named for their purpose, not their position in a hierarchy.

Philosophy

  • Semantic Over Technical: Colors are named for what they do, not abstract roles
  • Accessibility First: All color combinations meet WCAG 2.1 AA standards
  • Mode-Aware: Automatic adjustment between light and dark modes
  • Beautiful by Default: Carefully chosen colors that work well together

Color Roles

The color system is organized into semantic roles that describe how colors are used in real-world scenarios. Each color has a specific purpose and appears in predictable contexts throughout your application.

Name Preview Use Case
Brand Colors
brand Login page primary button, active navigation tab, "Save" action in forms
onBrand White text on primary buttons, icons on brand-colored backgrounds
brandSubtle Notification badge background, selected item highlight, info banner
onBrandSubtle Text and icons on subtle brand backgrounds, badge labels
Accent Colors
accent Secondary action buttons, "Learn More" links, special feature highlights
onAccent White text on secondary buttons, icons on accent-colored surfaces
accentSubtle Chip backgrounds, tag highlights, subtle feature indicators
onAccentSubtle Text on chips and tags, labels on accent backgrounds
Canvas Colors
canvas Main app background, screen root container, list view background
onCanvas Primary headings on main background, main body text
canvasElevated Card backgrounds, dialog surfaces, bottom sheets, floating panels
onCanvasElevated Text content on cards, dialog titles and body text
canvasSubtle List item backgrounds, grouped content areas, input field backgrounds
onCanvasSubtle Text on list items, content in grouped sections
Text Colors
textPrimary Page titles, article headings, important labels, primary content
textSecondary Subtitles, descriptions, metadata, supporting information
textTertiary Placeholder text, hints, captions, less important labels
textDisabled Disabled button labels, inactive menu items, unavailable content
Border Colors
border Input field borders, card outlines, divider lines, section separators
borderSubtle Subtle dividers between list items, soft section boundaries
borderFocus Focus rings on inputs, keyboard navigation indicators, active field outline
Semantic Colors
success Success notification backgrounds, checkmark icons, completion indicators
onSuccess Text on success messages, icons on green backgrounds
warning Warning alert backgrounds, caution badges, attention indicators
onWarning Text on warning messages, icons on orange backgrounds
danger Delete button backgrounds, error alert boxes, critical action indicators
onDanger "Delete" button text, error message text, icons on red backgrounds
info Information banners, help tooltips, informational badges
onInfo Text on info messages, icons on cyan backgrounds

Usage Examples

Basic Usage

@Composable
fun MyComponent() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(VetraTheme.colors.canvas)
            .padding(16.dp)
    ) {
        Text(
            text = "Welcome",
            style = VetraTheme.typography.displayMd,
            color = VetraTheme.colors.textPrimary
        )

        Text(
            text = "Get started with Vetra UI",
            style = VetraTheme.typography.bodyLg,
            color = VetraTheme.colors.textSecondary
        )
    }
}

Custom Colors

Override default colors when creating your theme:

val CustomLightColors = VetraLightColorScheme.copy(
    brand = Color(0xFF1E40AF),      // Custom blue
    accent = Color(0xFF9333EA),      // Custom purple
    success = Color(0xFF059669),     // Custom green
)

@Composable
fun App() {
    VetraTheme(colors = CustomLightColors) {
        // Your app content
    }
}

Dynamic Theme Colors

@Composable
fun DynamicThemedApp() {
    val brandColor = remember { mutableStateOf(Color(0xFF2563EB)) }

    VetraTheme(
        colors = VetraLightColorScheme.copy(
            brand = brandColor.value
        )
    ) {
        // Color picker
        ColorPicker(
            color = brandColor.value,
            onColorChange = { brandColor.value = it }
        )

        // Your app adapts automatically
        VetraButton(onClick = { }) {
            Text("Dynamic Color")
        }
    }
}

Color Naming Comparison

Vetra vs Material

Vetra Material Design
brand primary
onBrand onPrimary
brandSubtle primaryContainer
accent secondary
canvas background
canvasElevated surface
textPrimary onSurface
textSecondary onSurfaceVariant
border outline
danger error

Accessibility

All color combinations in Vetra UI meet WCAG 2.1 AA standards:

  • Normal text: Minimum 4.5:1 contrast ratio
  • Large text (18sp+ or 14sp+ bold): Minimum 3:1 contrast ratio
  • UI components: Minimum 3:1 contrast ratio

Testing Contrast

// Built-in colors are already accessible
Text(
    text = "This text is accessible",
    color = VetraTheme.colors.textPrimary, // ✓ 4.5:1+ contrast
    modifier = Modifier.background(VetraTheme.colors.canvas)
)

// When using custom colors, verify contrast
Text(
    text = "Check contrast for custom colors",
    color = customColor, // ⚠️ Test this
    modifier = Modifier.background(customBackground)
)

Best Practices

✅ Do

  • Use semantic color names consistently
  • Test your UI in both light and dark modes
  • Maintain color hierarchies (primary → secondary → tertiary)
  • Use brandSubtle and accentSubtle for backgrounds
  • Leverage semantic colors for states

❌ Don't

  • Use hardcoded hex colors
  • Mix Vetra and Material color APIs
  • Ignore disabled states
  • Use brand for large background areas
  • Skip contrast testing for custom colors

Migration from Material

// Before (Material)
MaterialTheme.colorScheme.primary
MaterialTheme.colorScheme.onSecondaryContainer
MaterialTheme.colorScheme.surfaceVariant

// After (Vetra)
VetraTheme.colors.brand
VetraTheme.colors.onAccentSubtle
VetraTheme.colors.canvasSubtle

Next: Learn about Typography →