Color Management and Theme Systems

1. Color Palette Maps and Theme Variables

Pattern Syntax Description Use Case
Color Maps $colors: (key: value) Organize colors in map structure Brand color systems
Nested Palettes $theme: (primary: (light: ..., dark: ...)) Multi-level color organization Color variants
Semantic Naming $color-primary, $color-success Purpose-based naming Maintainable themes
Shade Generation @function shade($color, $level) Auto-generate color variants Consistent palettes
Color Tokens $token-color-primary-500 Design token convention Design system integration

Example: Comprehensive color palette system

// Base color palette
$colors: (
  primary: #1976d2,
  secondary: #dc004e,
  success: #4caf50,
  warning: #ff9800,
  error: #f44336,
  info: #2196f3,
  neutral: #9e9e9e
);

// Generate shade levels (50-900)
@function generate-shades($base-color) {
  @return (
    50: mix(white, $base-color, 90%),
    100: mix(white, $base-color, 80%),
    200: mix(white, $base-color, 60%),
    300: mix(white, $base-color, 40%),
    400: mix(white, $base-color, 20%),
    500: $base-color,
    600: mix(black, $base-color, 20%),
    700: mix(black, $base-color, 40%),
    800: mix(black, $base-color, 60%),
    900: mix(black, $base-color, 80%)
  );
}

// Complete theme with all shades
$theme-colors: ();
@each $name, $color in $colors {
  $theme-colors: map-merge($theme-colors, (
    $name: generate-shades($color)
  ));
}

// Access function
@function theme-color($color, $shade: 500) {
  @return map-get(map-get($theme-colors, $color), $shade);
}

// Usage
.button-primary {
  background: theme-color(primary);
  &:hover { background: theme-color(primary, 600); }
  &:active { background: theme-color(primary, 700); }
}

// Semantic color variables
$color-background: theme-color(neutral, 50);
$color-surface: white;
$color-text-primary: rgba(0, 0, 0, 0.87);
$color-text-secondary: rgba(0, 0, 0, 0.60);
$color-divider: rgba(0, 0, 0, 0.12);

Example: Advanced nested theme structure

// Multi-theme system
$themes: (
  light: (
    background: (
      primary: #ffffff,
      secondary: #f5f5f5,
      elevated: #fafafa
    ),
    text: (
      primary: rgba(0, 0, 0, 0.87),
      secondary: rgba(0, 0, 0, 0.60),
      disabled: rgba(0, 0, 0, 0.38)
    ),
    brand: (
      primary: #1976d2,
      secondary: #dc004e,
      accent: #ff9800
    )
  ),
  dark: (
    background: (
      primary: #121212,
      secondary: #1e1e1e,
      elevated: #2c2c2c
    ),
    text: (
      primary: rgba(255, 255, 255, 0.87),
      secondary: rgba(255, 255, 255, 0.60),
      disabled: rgba(255, 255, 255, 0.38)
    ),
    brand: (
      primary: #90caf9,
      secondary: #f48fb1,
      accent: #ffb74d
    )
  )
);

// Deep map getter
@function theme-get($theme, $category, $variant) {
  $theme-map: map-get($themes, $theme);
  $category-map: map-get($theme-map, $category);
  @return map-get($category-map, $variant);
}

2. Color Scheme Generation and Automation

Technique Implementation Description Output
Complementary adjust-hue($color, 180deg) Opposite on color wheel High contrast pairs
Analogous adjust-hue($color, ±30deg) Adjacent colors Harmonious schemes
Triadic adjust-hue($color, 120deg) Evenly spaced colors Vibrant palettes
Monochromatic lighten/darken($color, %) Single hue variations Cohesive design
Tint/Shade mix(white/black, $color, %) Add white/black Subtle variations
Tone mix(gray, $color, %) Add gray Muted colors

Example: Automatic color scheme generators

// Complementary scheme
@function complementary-scheme($base) {
  @return (
    base: $base,
    complement: adjust-hue($base, 180deg)
  );
}

// Analogous scheme
@function analogous-scheme($base, $angle: 30deg) {
  @return (
    base: $base,
    left: adjust-hue($base, -$angle),
    right: adjust-hue($base, $angle)
  );
}

// Triadic scheme
@function triadic-scheme($base) {
  @return (
    primary: $base,
    secondary: adjust-hue($base, 120deg),
    tertiary: adjust-hue($base, 240deg)
  );
}

// Split complementary
@function split-complementary($base, $angle: 150deg) {
  @return (
    base: $base,
    left: adjust-hue($base, $angle),
    right: adjust-hue($base, -$angle)
  );
}

// Monochromatic with tints and shades
@function monochromatic-scheme($base, $steps: 5) {
  $scheme: ();
  @for $i from 1 through $steps {
    $lighter: lighten($base, $i * 10%);
    $darker: darken($base, $i * 10%);
    $scheme: map-merge($scheme, (
      'light-#{$i}': $lighter,
      'dark-#{$i}': $darker
    ));
  }
  @return map-merge($scheme, (base: $base));
}

// Usage
$brand: #1976d2;
$palette: triadic-scheme($brand);

.primary { color: map-get($palette, primary); }
.secondary { color: map-get($palette, secondary); }
.tertiary { color: map-get($palette, tertiary); }

Example: Material Design-style palette generator

@use 'sass:color';
@use 'sass:map';

@function material-palette($base-color) {
  $palette: ();
  
  // Define lightness levels
  $levels: (
    50: 95%,
    100: 90%,
    200: 80%,
    300: 70%,
    400: 60%,
    500: 50%,  // base
    600: 40%,
    700: 30%,
    800: 20%,
    900: 10%
  );
  
  @each $level, $lightness in $levels {
    $adjusted: change-color($base-color, $lightness: $lightness);
    $palette: map.merge($palette, ($level: $adjusted));
  }
  
  // Add accent colors (A100-A700)
  $palette: map.merge($palette, (
    'A100': lighten(saturate($base-color, 20%), 20%),
    'A200': lighten(saturate($base-color, 20%), 10%),
    'A400': saturate($base-color, 20%),
    'A700': darken(saturate($base-color, 20%), 10%)
  ));
  
  @return $palette;
}

// Generate complete color system
$primary: material-palette(#1976d2);
$accent: material-palette(#ff4081);

.button {
  background: map.get($primary, 500);
  &:hover { background: map.get($primary, 600); }
  &.accent { background: map.get($accent, 'A200'); }
}

3. Dark Mode and Light Mode Implementation

Approach Method Pros Cons
CSS Variables Change custom properties Runtime switching, scoped Browser support
Separate Files Load different CSS Simple, cacheable Flash of wrong theme
Class Toggle .dark-mode class Full control CSS duplication
Media Query prefers-color-scheme Respects OS setting No manual override
Hybrid Media query + class Best of both More complex
// Define theme maps
$light-theme: (
  bg-primary: #ffffff,
  bg-secondary: #f5f5f5,
  text-primary: #212121,
  text-secondary: #757575,
  border: #e0e0e0,
  shadow: rgba(0, 0, 0, 0.1)
);

$dark-theme: (
  bg-primary: #121212,
  bg-secondary: #1e1e1e,
  text-primary: #ffffff,
  text-secondary: #b0b0b0,
  border: #333333,
  shadow: rgba(0, 0, 0, 0.5)
);

// Generate CSS variables mixin
@mixin theme-variables($theme) {
  @each $name, $value in $theme {
    --color-#{$name}: #{$value};
  }
}

// Apply themes
:root {
  @include theme-variables($light-theme);
  color-scheme: light;
}

[data-theme="dark"] {
  @include theme-variables($dark-theme);
  color-scheme: dark;
}

// Respect system preference
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    @include theme-variables($dark-theme);
    color-scheme: dark;
  }
}

// Usage in components
.card {
  background: var(--color-bg-primary);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border);
  box-shadow: 0 2px 4px var(--color-shadow);
}

Example: SCSS mixin-based theme system

// Theme configuration
$themes: (
  light: (
    background: #ffffff,
    surface: #f5f5f5,
    primary: #1976d2,
    on-background: #000000,
    on-surface: #212121,
    on-primary: #ffffff
  ),
  dark: (
    background: #121212,
    surface: #1e1e1e,
    primary: #90caf9,
    on-background: #ffffff,
    on-surface: #e0e0e0,
    on-primary: #000000
  )
);

// Theme mixin
@mixin themed($property, $color-key) {
  @each $theme-name, $theme-colors in $themes {
    [data-theme="#{$theme-name}"] & {
      #{$property}: map-get($theme-colors, $color-key);
    }
  }
}

// Multi-property theme mixin
@mixin theme-colors($map) {
  @each $theme-name, $theme-colors in $themes {
    [data-theme="#{$theme-name}"] & {
      @each $property, $color-key in $map {
        #{$property}: map-get($theme-colors, $color-key);
      }
    }
  }
}

// Usage
.button {
  @include themed(background-color, primary);
  @include themed(color, on-primary);
  
  &:hover {
    @include themed(background-color, surface);
  }
}

.card {
  @include theme-colors((
    background-color: surface,
    color: on-surface,
    border-color: primary
  ));
}

Example: Advanced dark mode with elevation

// Dark mode elevation system
@function dark-elevation($level) {
  $opacity: 0.05 * $level;
  @return rgba(255, 255, 255, $opacity);
}

// Elevation mixin for dark mode
@mixin elevation($level: 1) {
  [data-theme="light"] & {
    box-shadow: 0 #{$level * 2}px #{$level * 4}px rgba(0, 0, 0, 0.1);
  }
  
  [data-theme="dark"] & {
    background: mix(white, #121212, $level * 5%);
    box-shadow: 0 #{$level * 2}px #{$level * 4}px rgba(0, 0, 0, 0.5);
  }
}

// Surface tint for Material Design 3
@mixin surface-tint($level: 1) {
  [data-theme="light"] & {
    background: white;
  }
  
  [data-theme="dark"] & {
    $tint: mix(#90caf9, #121212, $level * 5%);
    background: $tint;
  }
}

.card {
  @include elevation(2);
  
  &.elevated {
    @include elevation(8);
  }
  
  &.surface {
    @include surface-tint(3);
  }
}

4. Accessibility Color Contrast Functions

Function Purpose WCAG Level Ratio Required
contrast-ratio() Calculate contrast ratio - Returns number
is-accessible() Check WCAG compliance AA/AAA 4.5:1 / 7:1
accessible-color() Auto-adjust for contrast AA 4.5:1
text-color() Choose black/white text AA Based on background
Large Text 18pt+ or 14pt+ bold AA 3:1
UI Components Interactive elements AA 3:1

Example: Contrast ratio calculation and validation

@use 'sass:math';
@use 'sass:color';

// Calculate relative luminance
@function luminance($color) {
  $r: color.red($color) / 255;
  $g: color.green($color) / 255;
  $b: color.blue($color) / 255;
  
  $r: if($r <= 0.03928, $r / 12.92, math.pow(($r + 0.055) / 1.055, 2.4));
  $g: if($g <= 0.03928, $g / 12.92, math.pow(($g + 0.055) / 1.055, 2.4));
  $b: if($b <= 0.03928, $b / 12.92, math.pow(($b + 0.055) / 1.055, 2.4));
  
  @return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
}

// Calculate contrast ratio
@function contrast-ratio($fg, $bg) {
  $l1: luminance($fg);
  $l2: luminance($bg);
  
  $lighter: math.max($l1, $l2);
  $darker: math.min($l1, $l2);
  
  @return math.div($lighter + 0.05, $darker + 0.05);
}

// Check WCAG compliance
@function is-accessible($fg, $bg, $level: 'AA', $size: 'normal') {
  $ratio: contrast-ratio($fg, $bg);
  
  @if $level == 'AAA' {
    @return if($size == 'large', $ratio >= 4.5, $ratio >= 7);
  } @else {
    @return if($size == 'large', $ratio >= 3, $ratio >= 4.5);
  }
}

// Usage
$bg: #1976d2;
$text: #ffffff;

@debug contrast-ratio($text, $bg); // 4.53
@debug is-accessible($text, $bg); // true
@debug is-accessible($text, $bg, 'AAA'); // false

Example: Auto-adjust colors for accessibility

// Choose best text color (black or white)
@function text-color($bg, $light: #ffffff, $dark: #000000) {
  $light-ratio: contrast-ratio($light, $bg);
  $dark-ratio: contrast-ratio($dark, $bg);
  
  @return if($light-ratio > $dark-ratio, $light, $dark);
}

// Ensure accessible color
@function accessible-color($fg, $bg, $target-ratio: 4.5) {
  $ratio: contrast-ratio($fg, $bg);
  
  @if $ratio >= $target-ratio {
    @return $fg;
  }
  
  // Try darkening
  $darkened: $fg;
  @for $i from 1 through 20 {
    $darkened: darken($darkened, 5%);
    @if contrast-ratio($darkened, $bg) >= $target-ratio {
      @return $darkened;
    }
  }
  
  // Try lightening
  $lightened: $fg;
  @for $i from 1 through 20 {
    $lightened: lighten($lightened, 5%);
    @if contrast-ratio($lightened, $bg) >= $target-ratio {
      @return $lightened;
    }
  }
  
  // Fallback to black or white
  @return text-color($bg);
}

// Mixin for accessible text
@mixin accessible-text($bg, $level: 'AA') {
  $target: if($level == 'AAA', 7, 4.5);
  color: accessible-color(inherit, $bg, $target);
}

// Usage
.button {
  background: #ff9800;
  @include accessible-text(#ff9800);
}

.badge {
  $bg: #e3f2fd;
  background: $bg;
  color: text-color($bg);
}

Example: Accessibility validation mixin

// Validate and warn about contrast issues
@mixin validate-contrast($fg, $bg, $context: '') {
  $ratio: contrast-ratio($fg, $bg);
  
  @if $ratio < 3 {
    @error '#{$context} Contrast ratio #{$ratio} fails WCAG (minimum 3:1)';
  } @else if $ratio < 4.5 {
    @warn '#{$context} Contrast ratio #{$ratio} passes for large text only';
  } @else if $ratio < 7 {
    @warn '#{$context} Contrast ratio #{$ratio} passes AA but not AAA';
  }
}

// Auto-validate color usage
@mixin color-with-validation($property, $color, $bg, $context: '') {
  @include validate-contrast($color, $bg, $context);
  #{$property}: $color;
}

// Usage
.button-primary {
  $bg: #1976d2;
  background: $bg;
  @include color-with-validation(color, #ffffff, $bg, 'Button primary');
}

// Generate accessible palette
@function accessible-palette($base, $bg: #ffffff) {
  $palette: ();
  
  @for $i from 1 through 9 {
    $shade: darken($base, $i * 10%);
    @if is-accessible($shade, $bg) {
      $palette: append($palette, $shade);
    }
  }
  
  @return $palette;
}

5. Dynamic Color Manipulation Functions

Function Syntax Description Use Case
adjust-hue() adjust-hue($color, $degrees) Rotate hue on color wheel Color variations
saturate() saturate($color, $amount) Increase saturation Make colors vibrant
desaturate() desaturate($color, $amount) Decrease saturation Muted colors
mix() mix($color1, $color2, $weight) Blend two colors Color transitions
scale-color() scale-color($color, $red: 0%) Scale RGB/HSL values Precise adjustments
change-color() change-color($color, $hue: 0) Set specific channel Direct manipulation
complement() complement($color) Opposite hue (180°) Complementary colors
invert() invert($color, $weight) Invert RGB values Negative colors
grayscale() grayscale($color) Remove saturation Monochrome

Example: Advanced color manipulation utilities

@use 'sass:color';

// Smart color adjustment based on lightness
@function smart-scale($color, $amount) {
  $lightness: color.lightness($color);
  
  @if $lightness > 70% {
    @return darken($color, $amount);
  } @else if $lightness < 30% {
    @return lighten($color, $amount);
  } @else {
    @return saturate($color, $amount);
  }
}

// Create tint (mix with white)
@function tint($color, $percentage) {
  @return mix(white, $color, $percentage);
}

// Create shade (mix with black)
@function shade($color, $percentage) {
  @return mix(black, $color, $percentage);
}

// Create tone (mix with gray)
@function tone($color, $percentage) {
  @return mix(gray, $color, $percentage);
}

// Alpha transparency
@function alpha($color, $opacity) {
  @return rgba($color, $opacity);
}

// Multi-step color transformation
@function transform-color($color, $transforms...) {
  $result: $color;
  
  @each $transform in $transforms {
    $fn: nth($transform, 1);
    $args: if(length($transform) > 1, nth($transform, 2), null);
    
    @if $fn == 'lighten' {
      $result: lighten($result, $args);
    } @else if $fn == 'darken' {
      $result: darken($result, $args);
    } @else if $fn == 'saturate' {
      $result: saturate($result, $args);
    } @else if $fn == 'adjust-hue' {
      $result: adjust-hue($result, $args);
    }
  }
  
  @return $result;
}

// Usage
$base: #1976d2;
$tinted: tint($base, 20%);
$shaded: shade($base, 20%);
$toned: tone($base, 30%);

.button {
  background: transform-color($base, 
    (darken, 10%), 
    (saturate, 20%)
  );
}

Example: Color harmony and relationship functions

// Get complementary color
@function complementary($color) {
  @return adjust-hue($color, 180deg);
}

// Get analogous colors
@function analogous($color, $angle: 30deg) {
  @return (
    adjust-hue($color, -$angle),
    $color,
    adjust-hue($color, $angle)
  );
}

// Get triadic colors
@function triadic($color) {
  @return (
    $color,
    adjust-hue($color, 120deg),
    adjust-hue($color, 240deg)
  );
}

// Get split-complementary
@function split-complementary($color, $angle: 150deg) {
  @return (
    $color,
    adjust-hue($color, $angle),
    adjust-hue($color, -$angle)
  );
}

// Get tetradic (rectangle)
@function tetradic($color, $offset: 60deg) {
  @return (
    $color,
    adjust-hue($color, $offset),
    adjust-hue($color, 180deg),
    adjust-hue($color, 180deg + $offset)
  );
}

// Color temperature shift
@function warm($color, $amount: 10%) {
  @return adjust-hue($color, -$amount * 3.6deg);
}

@function cool($color, $amount: 10%) {
  @return adjust-hue($color, $amount * 3.6deg);
}

// Perceptual lightness adjustment
@function perceptual-lighten($color, $amount) {
  @return scale-color($color, $lightness: $amount);
}

@function perceptual-darken($color, $amount) {
  @return scale-color($color, $lightness: -$amount);
}

Example: State color generation

// Generate all button states from base color
@function button-states($base) {
  @return (
    default: $base,
    hover: darken($base, 8%),
    active: darken($base, 12%),
    focus: $base,
    disabled: desaturate(lighten($base, 20%), 40%),
    loading: desaturate($base, 20%)
  );
}

// Generate input states
@function input-states($base-border: #ccc) {
  @return (
    default: $base-border,
    hover: darken($base-border, 10%),
    focus: adjust-hue($base-border, 200deg),
    error: #f44336,
    success: #4caf50,
    disabled: lighten($base-border, 10%)
  );
}

// Mixin to apply all states
@mixin button-colors($base) {
  $states: button-states($base);
  
  background: map-get($states, default);
  
  &:hover:not(:disabled) {
    background: map-get($states, hover);
  }
  
  &:active:not(:disabled) {
    background: map-get($states, active);
  }
  
  &:focus-visible {
    outline: 2px solid map-get($states, focus);
    outline-offset: 2px;
  }
  
  &:disabled {
    background: map-get($states, disabled);
    cursor: not-allowed;
    opacity: 0.6;
  }
}

// Usage
.btn-primary {
  @include button-colors(#1976d2);
}

.btn-success {
  @include button-colors(#4caf50);
}

6. Color Token Systems and Design System Integration

Pattern Structure Description Example
Core Tokens Base color values Primitive colors $blue-500: #1976d2
Semantic Tokens Purpose-based names Functional colors $color-primary: $blue-500
Component Tokens Component-specific Scoped colors $button-bg: $color-primary
Token Aliasing Reference other tokens Single source of truth $link: $color-primary
Token Scale Numbered variations Consistent gradations 50, 100, 200...900
Theme Tokens Mode-specific values Light/dark variants $bg-light, $bg-dark

Example: Three-tier token system

// ===== TIER 1: Core/Primitive Tokens =====
// These are the base color values
$blue-50: #e3f2fd;
$blue-100: #bbdefb;
$blue-200: #90caf9;
$blue-300: #64b5f6;
$blue-400: #42a5f5;
$blue-500: #2196f3;
$blue-600: #1e88e5;
$blue-700: #1976d2;
$blue-800: #1565c0;
$blue-900: #0d47a1;

$gray-50: #fafafa;
$gray-100: #f5f5f5;
$gray-200: #eeeeee;
$gray-300: #e0e0e0;
// ... more grays

$red-500: #f44336;
$green-500: #4caf50;
$orange-500: #ff9800;

// ===== TIER 2: Semantic Tokens =====
// Purpose-based tokens
$color-primary: $blue-700;
$color-primary-light: $blue-500;
$color-primary-dark: $blue-900;

$color-secondary: $red-500;
$color-success: $green-500;
$color-warning: $orange-500;
$color-error: $red-500;
$color-info: $blue-500;

// Background tokens
$color-background: $gray-50;
$color-surface: #ffffff;
$color-overlay: rgba(0, 0, 0, 0.5);

// Text tokens
$color-text-primary: rgba(0, 0, 0, 0.87);
$color-text-secondary: rgba(0, 0, 0, 0.60);
$color-text-disabled: rgba(0, 0, 0, 0.38);
$color-text-hint: rgba(0, 0, 0, 0.38);

// Border tokens
$color-border: $gray-300;
$color-divider: rgba(0, 0, 0, 0.12);

// ===== TIER 3: Component Tokens =====
// Component-specific tokens
$button-bg-primary: $color-primary;
$button-text-primary: #ffffff;
$button-bg-secondary: $color-secondary;
$button-border-radius: 4px;

$input-bg: $color-surface;
$input-border: $color-border;
$input-text: $color-text-primary;
$input-placeholder: $color-text-secondary;

$card-bg: $color-surface;
$card-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

$link-color: $color-primary;
$link-hover: $color-primary-dark;

Example: Design system integration with Style Dictionary

// tokens.scss - Source tokens in SCSS format
$tokens: (
  color: (
    core: (
      blue: (
        50: #e3f2fd,
        100: #bbdefb,
        500: #2196f3,
        900: #0d47a1
      ),
      gray: (
        50: #fafafa,
        500: #9e9e9e,
        900: #212121
      )
    ),
    semantic: (
      primary: (
        default: '{color.core.blue.500}',
        light: '{color.core.blue.50}',
        dark: '{color.core.blue.900}'
      ),
      text: (
        primary: '{color.core.gray.900}',
        secondary: '{color.core.gray.500}'
      )
    ),
    component: (
      button: (
        background: '{color.semantic.primary.default}',
        text: '#ffffff',
        hover: '{color.semantic.primary.dark}'
      ),
      input: (
        background: '#ffffff',
        border: '{color.core.gray.500}',
        text: '{color.semantic.text.primary}'
      )
    )
  ),
  spacing: (
    xs: 4px,
    sm: 8px,
    md: 16px,
    lg: 24px,
    xl: 32px
  )
);

// Token resolver function
@function resolve-token($path) {
  // Parse token reference like '{color.core.blue.500}'
  @if str-index($path, '{') {
    $clean: str-slice($path, 2, -2); // Remove { }
    $keys: split-string($clean, '.');
    
    $value: $tokens;
    @each $key in $keys {
      $value: map-get($value, $key);
    }
    
    @return $value;
  }
  @return $path;
}

// Generate CSS custom properties
@mixin generate-css-vars($map, $prefix: '') {
  @each $key, $value in $map {
    @if type-of($value) == 'map' {
      @include generate-css-vars($value, '#{$prefix}#{$key}-');
    } @else {
      --#{$prefix}#{$key}: #{resolve-token($value)};
    }
  }
}

:root {
  @include generate-css-vars(map-get($tokens, color), 'color-');
  @include generate-css-vars(map-get($tokens, spacing), 'spacing-');
}

Example: Multi-brand token system

// Brand token configuration
$brands: (
  acme: (
    primary: #1976d2,
    secondary: #dc004e,
    logo: url('/brands/acme-logo.svg')
  ),
  globex: (
    primary: #4caf50,
    secondary: #ff9800,
    logo: url('/brands/globex-logo.svg')
  ),
  initech: (
    primary: #9c27b0,
    secondary: #00bcd4,
    logo: url('/brands/initech-logo.svg')
  )
);

// Generate brand-specific tokens
@each $brand-name, $brand-config in $brands {
  [data-brand="#{$brand-name}"] {
    --brand-primary: #{map-get($brand-config, primary)};
    --brand-secondary: #{map-get($brand-config, secondary)};
    --brand-logo: #{map-get($brand-config, logo)};
    
    // Generate palette from primary
    --brand-primary-light: #{lighten(map-get($brand-config, primary), 20%)};
    --brand-primary-dark: #{darken(map-get($brand-config, primary), 20%)};
    
    // Generate contrast colors
    --brand-on-primary: #{text-color(map-get($brand-config, primary))};
    --brand-on-secondary: #{text-color(map-get($brand-config, secondary))};
  }
}

// Component usage
.header {
  background: var(--brand-primary);
  color: var(--brand-on-primary);
  
  &__logo {
    background-image: var(--brand-logo);
  }
}

.button-primary {
  background: var(--brand-primary);
  color: var(--brand-on-primary);
  
  &:hover {
    background: var(--brand-primary-dark);
  }
}

Example: Token documentation generator

// Generate color documentation
@mixin document-colors($color-map, $name: '') {
  @if type-of($color-map) == 'color' {
    // Generate a swatch
    .color-swatch-#{$name} {
      &::before {
        content: '#{$name}: #{$color-map}';
        display: inline-block;
        width: 100px;
        height: 40px;
        background: $color-map;
        margin-right: 10px;
        border: 1px solid #ccc;
      }
    }
  } @else if type-of($color-map) == 'map' {
    @each $key, $value in $color-map {
      $full-name: if($name == '', $key, '#{$name}-#{$key}');
      @include document-colors($value, $full-name);
    }
  }
}

// Generate documentation
@include document-colors($tokens);

// Export as JSON for documentation tools
@function tokens-to-json($map, $indent: 0) {
  $json: '{\n';
  $i: 0;
  
  @each $key, $value in $map {
    $i: $i + 1;
    $spacing: '';
    @for $s from 1 through ($indent + 1) {
      $spacing: $spacing + '  ';
    }
    
    $json: $json + $spacing + '"#{$key}": ';
    
    @if type-of($value) == 'map' {
      $json: $json + tokens-to-json($value, $indent + 1);
    } @else {
      $json: $json + '"#{$value}"';
    }
    
    @if $i < length($map) {
      $json: $json + ',';
    }
    $json: $json + '\n';
  }
  
  $spacing: '';
  @for $s from 1 through $indent {
    $spacing: $spacing + '  ';
  }
  $json: $json + $spacing + '}';
  
  @return $json;
}

Color Management Best Practices

  • Three-tier tokens: Core → Semantic → Component for scalability
  • CSS variables: Enable runtime theme switching and scoping
  • Accessibility first: Always validate contrast ratios (4.5:1 minimum)
  • Dark mode: Use hybrid approach (media query + manual toggle)
  • Semantic naming: Use purpose-based names, not color names
  • Automated generation: Generate palettes and states programmatically
  • Design tokens: Single source of truth for multi-platform consistency
  • Contrast functions: Validate and auto-adjust colors for WCAG compliance
Note: Modern Sass modules (sass:color) provide more precise color manipulation with better support for different color spaces. Use @use 'sass:color' for future-proof implementations.