Skip to content
ColorTokensKitby Penguin Design Ventures
Contents
Function

.tetrad(offset:)

Four colors in two opposite pairs for tags and categories, all at your color's contrast.

Updated View as Markdown

Color four categories with .tetrad(): your color, the hue offset around the wheel, and the opposite of each. The four form two opposite pairs, and all keep your color's lightness, so every tag has the same contrast.

swift
let tags = ["Beach", "City", "Food", "Nature"]
let families = brand.tetrad()   // your family, then 227°, 347° and 47°

HStack {
    ForEach(tags.indices, id: \.self) { index in
        Text(tags[index])
            .padding(8)
            .foregroundStyle(families[index].foregroundPrimary)   // _1000 in light mode, _50 in dark
            .background(families[index].backgroundTertiary)       // _200 in light mode, _700 in dark
    }
}
light mode
BeachCityFoodNature

Pick your color below and change the offset to move the second pair around the wheel.

Try it / Harmonies
Color

Every OKLCH hue at this color's lightness

0°90°180°270°360°
light mode
#63a7fdproBlue._400
#c08defproPurple._400
#da9630proAmber._400
#8ab24dproLime._400
dark mode
#63a7fdproBlue._400
#c08defproPurple._400
#da9630proAmber._400
#8ab24dproLime._400
swift
let color = Color.proBlue._400.toColor()
color.tetrad()

Choosing the offset#

offset sets where the second pair starts. A small offset gives two close pairs, each opposite the other:

swift
let families = brand._400.tetrad(offset: .degrees(30))   // 167°, 197°, 347° and 17°
#44ba8c
167°
#13b8be
197°
#e383bc
347°
#ef8388
17°

An offset of 90° spaces all four evenly, the same hues as square.

How it behaves#

The colors come back as yours, the hue offset away, your complement, then the complement of the second: for Color.proBlue, that's blue, purple, amber and lime.

Each color is turned with rotateHue(by:), so a palette color lands on the same stop at its new hue. On a ProTheme, you get whole families at the stop you started from. Gray has no hue, so its tetrad is all gray. Only hue tells the four apart, so when color carries meaning, add a label, as using tokens in charts shows.

API#

swift
public extension Color {
    func tetrad(offset: Angle = .degrees(60)) -> [Color]
}

public extension ProTheme {
    func tetrad(offset: Angle = .degrees(60)) -> [ProTheme]
}
ParameterTypeDefaultWhat other values do
offsetAngle60°Where the second hue sits; the other two are the complements. 90° gives square.

It returns four colors or families, in the order above. It's the same as harmony(.tetrad(offset:)).

Sources#

See also

  • .square Four hues spaced evenly around the wheel for chart series and categories, at one contrast.
  • .complement Give a price or badge an accent that stands apart from your brand, at the same contrast.
  • Color theory Pair stops that always read, and pick secondary hues that match your brand, in both modes.
  • .harmony(_:) Build the harmony someone picks at runtime, from a picker or a setting, in one call.