The Fiori color system is built on a versioned, dynamic palette. Every color style resolves to a different hex value depending on the current light/dark color scheme, the interface elevation level (base vs. elevated), and the accessibility contrast setting. You never hard-code hex values; instead, you request a semantic or decorative color by name and the system picks the right variant at render time.
Color.preferredColor
The primary API for consuming palette colors is the Color.preferredColor static method, defined in Color+Extension.swift.
static func preferredColor(
_ style: ColorStyle,
background scheme: BackgroundColorScheme? = .device,
interface level: InterfaceLevel? = .device,
display mode: ColorDisplayMode? = .device
) -> Color
The semantic or decorative color style to resolve. See Color styles below.
scheme
BackgroundColorScheme
default:".device"
Describes the background behind the content. Controls whether light or dark color variants are used. Defaults to .device, which follows the system setting automatically.
level
InterfaceLevel
default:".device"
Describes the elevation level of the surface (base window vs. alerts, popovers, sheets). Defaults to .device.
mode
ColorDisplayMode
default:".device"
Controls accessibility contrast behavior. Defaults to .device, which respects the system accessibility contrast setting.
Basic usage
import FioriThemeManager
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
// Follows the device light/dark mode automatically
Text("Primary label")
.foregroundStyle(Color.preferredColor(.primaryLabel))
// Tint color for interactive elements
Button("Tap me") {}
.tint(Color.preferredColor(.tintColor))
// Semantic status colors
Label("Success", systemImage: "checkmark.circle")
.foregroundStyle(Color.preferredColor(.positiveLabel))
Label("Warning", systemImage: "exclamationmark.triangle")
.foregroundStyle(Color.preferredColor(.criticalLabel))
Label("Error", systemImage: "xmark.circle")
.foregroundStyle(Color.preferredColor(.negativeLabel))
}
}
}
Force a constant color scheme
// Always use light-background foreground colors, regardless of system setting
let alwaysDark = Color.preferredColor(.primaryLabel, background: .lightConstant)
// Always use dark-background foreground colors
let alwaysLight = Color.preferredColor(.primaryLabel, background: .darkConstant)
// Invert — useful inside inverted-theme headers
let inverted = Color.preferredColor(.primaryLabel, background: .deviceInverse)
Force an interface level
// Elevated surface — e.g. inside a sheet or popover
let elevatedBackground = Color.preferredColor(
.secondaryBackground,
interface: .elevatedConstant
)
Resolve to a static color (iOS / visionOS only)
When you need a concrete Color value — for example, to pass into a non-SwiftUI API — call resolvedColor:
let staticColor = Color.preferredColor(.tintColor)
.resolvedColor(with: .light, in: .base)
Color styles
ColorStyle is a Swift enum whose raw value is the string key used in .nss stylesheets. The current palette (v8) defines over 200 styles. The categories below cover the most commonly used ones.
Grey scale (grey1–grey11)
The grey scale runs from grey1 (lightest) to grey11 (darkest) in light mode, inverting automatically in dark mode.
Color.preferredColor(.grey1) // near-white in light, near-black in dark
Color.preferredColor(.grey6) // neutral mid-tone in both schemes
Color.preferredColor(.grey11) // near-black in light, near-white in dark
Label colors
| Style | Usage |
|---|
.primaryLabel | Primary body text |
.secondaryLabel | Supporting text, captions |
.tertiaryLabel | Placeholder, hint text |
.quaternaryLabel | Disabled text |
.quinaryLabel | Pure white/black contrast |
.neutralLabel | De-emphasized, neutral content |
.navBarTitleLabel | Navigation bar title |
Tint colors
| Style | Usage |
|---|
.tintColor | Primary interactive color (links, buttons) |
.tintColor2 | Interactive color on lower-contrast surfaces |
.tintColor3 | Transparent tint overlay |
.tintColorTapState | Highlighted/pressed state for tinted controls |
Semantic status colors
| Style | Usage |
|---|
.positiveLabel | Positive / success foreground |
.negativeLabel | Negative / error foreground |
.criticalLabel | Critical / warning foreground |
.informativeLabel | Informational foreground |
.neutralLabel | Neutral status foreground |
.positiveBackground | Positive status background tint |
.negativeBackground | Negative status background tint |
.criticalBackground | Critical status background tint |
.informationBackground | Informational status background tint |
Background colors
Color.preferredColor(.primaryBackground) // main window background
Color.preferredColor(.secondaryBackground) // secondary surface
Color.preferredColor(.primaryGroupedBackground) // grouped list background
Color.preferredColor(.secondaryGroupedBackground) // grouped cell background
Color.preferredColor(.tertiaryGroupedBackground) // nested grouped content
Fill colors
Translucent overlay colors for button backgrounds, form fields, and selection states.
Color.preferredColor(.primaryFill)
Color.preferredColor(.secondaryFill)
Color.preferredColor(.tertiaryFill)
Color.preferredColor(.quaternaryFill)
Structural colors
Color.preferredColor(.separator) // hairline dividers
Color.preferredColor(.separatorOpaque) // opaque dividers
Color.preferredColor(.header) // navigation bar / header background
Color.preferredColor(.footer) // footer bar background
Color.preferredColor(.tintColor) // primary brand accent
Extended palette (color families)
The palette also exposes named color families with 11 steps each. These are useful for data visualization and accent decoration:
- Blues:
.blue1 – .blue11
- Teals:
.teal1 – .teal11
- Greens:
.green1 – .green11
- Mangos:
.mango1 – .mango11
- Reds:
.red1 – .red11
- Pinks:
.pink1 – .pink11
- Raspberries:
.raspberry1 – .raspberry11
- Indigos:
.indigo1 – .indigo11
- Chart colors:
.chart1 – .chart12
BackgroundColorScheme
BackgroundColorScheme tells the color resolver what kind of background the content sits on. This is about the background behind the content, not the system color scheme.
| Case | Behavior |
|---|
.device | Follows the system light/dark setting (default) |
.deviceInverse | Inverts the system setting |
.lightConstant | Always uses dark color variants (content on a light background) |
.darkConstant | Always uses light color variants (content on a dark background) |
.lightConstant and .darkConstant replace the deprecated .light and .dark aliases from earlier SDK versions.
InterfaceLevel
InterfaceLevel mirrors UIUserInterfaceLevel and selects between base and elevated color variants, which can differ in some palette styles.
| Case | Behavior |
|---|
.device | Follows the system interface level (default) |
.deviceInverse | Inverts the system interface level |
.baseConstant | Forces base-level color variants |
.elevatedConstant | Forces elevated-level color variants (alerts, popovers) |
ColorDisplayMode
ColorDisplayMode controls how accessibility contrast settings affect color resolution.
| Case | Behavior |
|---|
.device | Follows the system contrast setting (default) |
.deviceInverse | Inverts the system contrast setting |
.normalConstant | Always uses normal-contrast variants |
.highConstant | Always uses high-contrast variants |
ColorVariant
ColorVariant is the internal type that represents the fully-resolved combination of scheme + level + contrast. You use it when calling ThemeManager.shared.setColor(_:for:variant:) to target a specific rendering context:
| Variant | Context |
|---|
.light | Dark color scheme, base level |
.dark | Light color scheme, base level |
.elevatedLight | Dark color scheme, elevated level |
.elevatedDark | Light color scheme, elevated level |
.contrastLight | Dark color scheme, high contrast |
.contrastDark | Light color scheme, high contrast |
To invert any variant, call .inverse() on it. The same helper is available on BackgroundColorScheme, InterfaceLevel, and ColorDisplayMode.