# ProGradient recipes

Make a gradient from one color with a preset like .tonal or .fade, or write your own in a line.

Get a finished gradient from a single color: pass a recipe, such as `.tonal` for depth or `.fade` for a glow, to [`proGradient(_:)`](https://colortokenskit.com/api/pro-gradient/index.md). A recipe turns one color into the gradient's colors, and with no recipe you get `.subtle`, which runs from one stop lighter at the top to the color itself:

```swift
Text("Book now")
    .padding()
    .foregroundStyle(.black)
    .background(brand._400.proGradient())   // .subtle: _350 at the top to _400
```

What this draws, with `#00B386`:

| Color   | light mode                             | dark mode                              |
| ------- | -------------------------------------- | -------------------------------------- |
| `_400`  | color(display-p3 0.2666 0.7286 0.5502) | color(display-p3 0.2666 0.7286 0.5502) |
| `black` | #000000                                | #000000                                |

It draws a linear gradient from the `.subtle` recipe from `_400`, with `.vivid` and `.smooth`.

Pick a color or a token below to draw every recipe from it, in both modes. The checkerboard shows where a recipe turns transparent:

The live page shows all seven recipes made from one color. For `Color.proBlue._400`, `.subtle` runs from #7ab4fd to #63a7fd, and `.tonal` runs from #8fc0fe through #63a7fd to #508edc. [Try it on the live page](https://colortokenskit.com/api/gradient-recipes/).

## The seven presets

| Recipe              | Colors it makes from `color`                                 | Good for                 |
| ------------------- | ------------------------------------------------------------ | ------------------------ |
| `.subtle` (default) | `color.lighten()`, `color`                                   | Buttons and icons        |
| `.fade`             | `color`, `color.opacity(0)`                                  | Glows and scrims         |
| `.tonal`            | `color.lighten(by: 2)`, `color`, `color.darken(by: 2)`       | Cards and headers        |
| `.analogous`        | `color.analogous()`, the hues 30° either side                | Banners                  |
| `.wash`             | `color.opacity(0.1)`, `color.opacity(0.3)`                   | Card backdrops           |
| `.sheen`            | `color.opacity(0)`, `color.opacity(0.5)`, `color.opacity(0)` | A shine, made from white |
| `.edgeHighlight`    | `color.opacity(0.15)`, `color`, `color.opacity(0.15)`        | Borders and rims         |

Every recipe works with all three shapes: `proGradient`, [`proRadialGradient`](https://colortokenskit.com/api/pro-radial-gradient/index.md) and [`proAngularGradient`](https://colortokenskit.com/api/pro-angular-gradient/index.md).

## Adding a sheen to a button

`.sheen` puts a band of color across the middle, clear at both ends. Made from white and laid over a `.tonal` fill, it reads as a shine:

```swift
Button("Book now") {}
    .buttonStyle(.plain)
    .padding()
    .foregroundStyle(.black)
    .background(Color.white.proGradient(.sheen, from: .leading, to: .trailing))
    .background(brand._400.proGradient(.tonal))   // _300 through _400 to _500
```

What this draws, with `#00B386`:

| Color   | light mode                             | dark mode                              |
| ------- | -------------------------------------- | -------------------------------------- |
| `_400`  | color(display-p3 0.2666 0.7286 0.5502) | color(display-p3 0.2666 0.7286 0.5502) |
| `white` | #ffffff                                | #ffffff                                |
| `black` | #000000                                | #000000                                |

It draws a linear gradient from the `.tonal` recipe from `_400`, with `.vivid` and `.smooth`; a linear gradient from the `.sheen` recipe from `white`, with `.vivid` and `.smooth`.

## Writing your own recipe

A recipe is a function from one `Color` to the gradient's colors, in order. Add it as a static property, and it reads like the presets:

```swift
extension ProGradient.Recipe {
    static var deepen: Self { Self { [$0, $0.darken(by: 4)] } }
}

Rectangle()
    .fill(brand._400.proGradient(.deepen))   // _400 to _600
    .frame(height: 64)
```

What this draws, with `#00B386`:

| Color  | light mode                             | dark mode                              |
| ------ | -------------------------------------- | -------------------------------------- |
| `_400` | color(display-p3 0.2666 0.7286 0.5502) | color(display-p3 0.2666 0.7286 0.5502) |
| `_600` | color(display-p3 0.1547 0.5182 0.3824) | color(display-p3 0.1547 0.5182 0.3824) |

It draws a linear gradient from `_400` to `_600`, with `.vivid` and `.smooth`.

## Reading a recipe's colors

`colors(from:)` gives a recipe's colors without drawing a gradient, for a chart series, a row of badges or your own gradient type:

```swift
let steps = ProGradient.Recipe.tonal.colors(from: accent)   // [accent.lighten(by: 2), accent, accent.darken(by: 2)]
```

## How it behaves

Recipes built on [`lighten()`](https://colortokenskit.com/api/lighten/index.md) and [`darken()`](https://colortokenskit.com/api/darken/index.md) land palette colors on exact stops, so `.tonal` on `_400` gives `_300`, `_400` and `_500`. A color off the palette moves the same number of steps along the lightness ladder, keeping its hue and chroma.

On a family, a recipe starts from the family's own color: `_450` for a built-in family, and your hex for a family made with [`ProTheme(hex:)`](https://colortokenskit.com/api/protheme/index.md#from-a-hex-color). To start from a stop, call it on the stop, as in `brand._400.proGradient(.tonal)`.

The recipes that fade, `.fade`, `.wash`, `.sheen` and `.edgeHighlight`, change only opacity, so the color keeps its hue all the way to transparent. On a token they fade the token's color in each mode.

## API

```swift
public enum ProGradient {
    public struct Recipe {
        public init(_ makeColors: @escaping (Color) -> [Color])
        public func colors(from color: Color) -> [Color]
    }
}

public extension ProGradient.Recipe {
    static var subtle: Self { get }
    static var fade: Self { get }
    static var tonal: Self { get }
    static var analogous: Self { get }
    static var wash: Self { get }
    static var sheen: Self { get }
    static var edgeHighlight: Self { get }
}
```

| Parameter                 | Type                 | Default | What other values do                                 |
| ------------------------- | -------------------- | ------- | ---------------------------------------------------- |
| `makeColors` (`init`)     | `(Color) -> [Color]` | none    | Returns the gradient's colors for a color, in order. |
| `color` (`colors(from:)`) | `Color`              | none    | Any color, including tokens and system colors.       |

`colors(from:)` returns the recipe's colors in gradient order. Pass a recipe as the first argument of `proGradient`, `proRadialGradient` or `proAngularGradient` on a `Color` or `ProTheme`.

## Sources

- ColorTokensKit source: [ProGradient.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Sources/ColorTokensKit/Gradients/ProGradient.swift) and [Color+ProGradient.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Sources/ColorTokensKit/Gradients/Color+ProGradient.swift).

## See also

- [Gradient theory](https://colortokenskit.com/advanced/gradient-theory/index.md): Add depth with gradients that stay vivid, from a single color or a recipe, in both modes.
- [Building for interaction states](https://colortokenskit.com/getting-started/interaction-states/index.md): Give buttons and rows hover, pressed, selected and disabled colors that stay readable in both modes.
- [.analogous(count:spread:)](https://colortokenskit.com/api/analogous/index.md): Close neighbors of your color for banners, illustrations and gradients, at matching contrast.
- [How colors land on exact stops](https://colortokenskit.com/under-the-hood/palette-snapping/index.md): Derived colors land on exact stops, so you know their contrast before you run the app.

---

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