# Stops: ._50 to ._1000

Twenty fixed colors per theme, lightest to darkest, with the same contrast in every hue.

Every theme has 20 stops, from `_50`, nearly white, to `_1000`, nearly black. A stop is one fixed color, and it has the same lightness in every hue, so it has the same contrast too. `allStops` gives you all 20, lightest first.

```swift
let theme = Color.proBlue

theme._50        // the lightest stop
theme._600       // as light as every other hue's _600
theme._1000      // the darkest
theme.allStops   // all 20, _50 first
```

Here are `proBlue`'s 20:

`proBlue`, lightest to darkest: #eff6ff, #ddecff, #cbe1fe, #b8d7fe, #a4cbfe, #8fc0fe, #7ab4fd, #63a7fd, #579aef, #508edc, #4882ca, #4176b8, #3a69a5, #335e94, #2c5282, #254771, #1e3b60, #183150, #122640, #0b1c32.

## Making a token from two stops

A stop stays the same in dark mode, so views draw with tokens, and each token picks one stop for light mode and one for dark. When you need a color the 20 tokens don't cover, name its two stops:

```swift
extension ProTheme {
    var badgeBackground: Color {
        Color(light: _200.toColor(), dark: _800.toColor())
    }
}

Text("New")
    .padding(8)
    .foregroundStyle(Color.proGreen.foregroundPrimary)
    .background(Color.proGreen.badgeBackground)
```

What this draws, with `Color.proGreen`:

| Color               | light mode | dark mode |
| ------------------- | ---------- | --------- |
| `foregroundPrimary` | #04210c    | #edf8ee   |
| `_200/_800`         | #abe0b5    | #135027   |

[`Color(light:dark:)`](https://colortokenskit.com/api/light-dark/index.md) explains the switch, and [understanding semantic tokens](https://colortokenskit.com/getting-started/semantic-tokens/index.md) lists the stops behind the 20 built-in tokens.

## The same contrast in every hue

Two stops have the same contrast in every hue, so a pair you check once works in every theme:

```swift
Color.proRed._800.contrastRatio(to: Color.proRed._100)     // 7.91
Color.proTeal._800.contrastRatio(to: Color.proTeal._100)   // 7.91, the same
```

`proGray` is the exception. Its stops sit on a lightness ladder of their own, so check gray pairs on their own.

## Stepping through the ladder

`allStops` is in order, so a stop's index is its number divided by 50, minus 1: `allStops[11]` is `_600`. That makes a light-to-dark scale for a heat map or a chart easy to slice:

```swift
let levels = Array(Color.proBlue.allStops[3...15])   // _200 to _800, light to dark
```

## How it behaves

Every hue shares one lightness per stop, from `_50` to `_1000` in steps of about 4 to 5 L\*, and one chroma per stop, most vivid around `_350`. [How the ramps are built](https://colortokenskit.com/under-the-hood/how-ramps-are-built/index.md) has the numbers.

Each stop is itself a `ProTheme`, whose own color is that stop. Its stops and tokens read the same ramp, so `Color.proBlue._600._200` is `Color.proBlue._200`, and `Color.proBlue._600.foregroundPrimary` is `Color.proBlue.foregroundPrimary`. A theme from [`ProTheme(hex:)`](https://colortokenskit.com/api/protheme/index.md#from-a-hex-color) works the same way: its stops come from its hue's ramp, not from your hex.

Many stops are beyond sRGB, in [Display P3](https://colortokenskit.com/reference/glossary/index.md#display-p3). `getHexString()` clamps those into sRGB, so name a stop in code instead of copying its hex.

## API

```swift
public extension ProTheme {
    var _50: ProTheme { get }
    var _100: ProTheme { get }
    // _150 to _950, every 50
    var _1000: ProTheme { get }
    var allStops: [ProTheme] { get }
}
```

Each stop returns a `ProTheme` that holds that stop's fixed color and reads the same ramp. `allStops` returns all 20, from `_50` to `_1000`.

## Sources

- The library's [ProTheme.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Sources/ColorTokensKit/ProTheme/ProTheme.swift), which defines the stops, and [UniformRamp.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Sources/ColorTokensKit/Services/Ramps/UniformRamp.swift), which sets each stop's lightness and chroma.

## See also

- [Understanding semantic tokens](https://colortokenskit.com/getting-started/semantic-tokens/index.md): Learn the 20 tokens by the job each one does, and get dark mode and passing contrast with them.
- [Color(light:dark:)](https://colortokenskit.com/api/light-dark/index.md): Make any color switch between light and dark mode, the way every token does.
- [Ready-made themes](https://colortokenskit.com/api/named-themes/index.md): 37 themes to use as they are, from proPink to proRose, each with 20 stops and every token.
- [How the ramps are built](https://colortokenskit.com/under-the-hood/how-ramps-are-built/index.md): The lightness and chroma behind every stop, so any hue you pick gives the same contrast.
- [.lighten(by:)](https://colortokenskit.com/api/lighten/index.md): Add highlights and lighter steps to any color, landing on an exact palette stop.

---

From ColorTokensKit, by Penguin Design Ventures: https://colortokenskit.com/api/stops/ (updated September 26, 2026).
