Skip to main content

Color Pipeline

Each preset color (primary, accent, neutral) is a single hex value that passes through a generation pipeline to produce an 11-level shade scale.

Summary

The pipeline converts a hex color to HSL, then interpolates lightness and adjusts saturation to produce 11 shades (50 through 950). Each shade is converted back to hex and written as a CSS custom property.

The base color sits at the 600 level.

How It Works

Step 1: Hex to HSL

The input hex color (e.g., #ea580c) is parsed into RGB channels, then converted to HSL (hue, saturation, lightness) using standard color math.

#ea580c → RGB(234, 88, 12) → HSL(20.5°, 90.2%, 48.2%)

Step 2: Generate Shade Scale

Each shade level has a predefined lightness position and saturation factor:

LevelPositionSaturation FactorPurpose
50+0.930.40Near white
100+0.860.55Very light
200+0.730.70Light
300+0.580.82Light-medium
400+0.390.92Medium-light
500+0.200.98Medium
60001.00Base color
700−0.280.95Medium-dark
800−0.500.90Dark
900−0.660.85Very dark
950−0.800.80Near black

Lightness calculation:

  • Positive position: targetLightness = baseLightness + (position × (100 − baseLightness))
  • Negative position: targetLightness = baseLightness × (1 + position)

Saturation calculation:

  • adjustedSaturation = baseSaturation × saturationFactor

Step 3: HSL to Hex

Each computed HSL value is converted back to RGB, then to a hex string. The result is a set of 11 hex colors that form a perceptually smooth gradient from near-white to near-black.

Output

For the Foundry primary color #ea580c:

PropertyValue
--nova-color-primary-50Lightest
--nova-color-primary-100
--nova-color-primary-200
--nova-color-primary-300
--nova-color-primary-400
--nova-color-primary-500
--nova-color-primary-600#ea580c
--nova-color-primary-700
--nova-color-primary-800
--nova-color-primary-900
--nova-color-primary-950Darkest

The same pipeline runs for accent and neutral, producing 33 CSS custom properties total (11 per color channel).

Using Color Tokens

Reference the generated tokens in your CSS:

.my-element {
  color: var(--nova-color-primary-600);
  background-color: var(--nova-color-neutral-50);
  border-color: var(--nova-color-accent-200);
}

Lighter shades (50–400) work well for backgrounds and borders. The base shade (600) is the brand color.

Darker shades (700–950) work well for text and emphasis.