Four opinionated visual identities — Slate, Aurora, Copper, Sage. Each ships with a light and dark theme. One modifier, automatic switching.
The four presets
Each preset varies colors, corner radius, and shadow weight. Typography, spacing, and animation stay consistent across all presets — only the identity changes.
Live previews
Every preset ships both a light and a dark theme. The dfThemePreset() modifier selects the correct variant automatically based on the system color scheme.
API
The common case is one modifier at the app root. Power users can go deeper.
import DesignFoundation @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() .dfThemePreset(.aurora) // reads \.colorScheme, switches automatically } } }
// Force dark in Xcode Previews ContentView() .dfTheme(.auroraDark) .environment(\.colorScheme, .dark) // Force light for a sub-tree HeroView() .dfTheme(.slateLight)
// Mix preset themes — light from one, dark from another let myPreset = DFThemePreset(light: .slateLight, dark: .auroraDark) ContentView().dfThemePreset(myPreset) // Extend a preset with one token override var custom = DFTheme.sageLight custom.colors.primary = .purple MyView().dfTheme(custom)
dfThemePreset reads @Environment(\.colorScheme) from above the modifier.
A .preferredColorScheme on a descendant does not retroactively flip the preset for ancestors —
this is standard SwiftUI environment behavior.
Under the hood
The implementation is a thin wrapper over the existing dfTheme() environment system.
DFTheme values — one for light, one for dark. Four named statics ship in the box.dfThemePreset() modifier reads @Environment(\.colorScheme) and calls dfTheme() with the correct variant. SwiftUI re-evaluates on scheme changes.DFThemePreset is a value type with only Sendable stored properties. Compiles clean under StrictConcurrency.Color reference
Every color token for each preset. respectsColorScheme is false on all preset tokens — switching is handled by the modifier.
| Token | Light | Dark |
|---|---|---|
| .primary | #1C3D5A deep navy-slate | #64B5F6 sky blue |
| .secondary | #546E7A blue-gray | #78909C muted blue-gray |
| .accent | #386DC3 steel blue | #82C4FF light blue |
| .background | #E4E7EB cool grey | #0F1923 |
| .surface | #ECEEF1 | #1C2B3A |
| .surfaceElevated | #F5F6F8 | #243447 |
| .textPrimary | #0D1B2A | #E8F0F8 |
| .interactiveFill | #1E3D7D deep navy | #64B5F6 |
| .destructive | #E53935 | #EF5350 |
| Token | Light | Dark |
|---|---|---|
| .primary | #6C47FF electric violet | #A78BFA soft violet |
| .secondary | #9B72CF medium purple | #7C6BAD muted purple |
| .accent | #A78BFA soft violet | #C4B5FD light lavender |
| .background | #FAFAFA | #0D0A1E |
| .surface | #F3F0FF lavender tint | #1A1535 |
| .surfaceElevated | #FFFFFF | #241D47 |
| .textPrimary | #1A0A4F deep purple | #EDE9FF |
| .interactiveFill | #6C47FF | #A78BFA |
| .destructive | #E53935 | #EF5350 |
| Token | Light | Dark |
|---|---|---|
| .primary | #C4622D copper | #F4A261 warm amber |
| .secondary | #8D6E63 warm brown-gray | #A1887F light brown |
| .accent | #E8894B amber | #FFB74D golden amber |
| .background | #FBF8F5 warm white | #1A1008 espresso |
| .surface | #F5EDE3 warm cream | #2C1F12 |
| .surfaceElevated | #FFFAF6 | #3D2C1C |
| .textPrimary | #2C1810 dark espresso | #FFF3E8 |
| .interactiveFill | #C4622D | #F4A261 |
| .destructive | #C62828 deep red | #EF5350 |
| Token | Light | Dark |
|---|---|---|
| .primary | #2D6A4F deep sage | #74C69D mint green |
| .secondary | #52796F teal-gray | #6B9E8F muted teal |
| .accent | #52B788 mint | #95D5B2 light mint |
| .background | #F7FAF7 green-white tint | #0A1A0F deep forest |
| .surface | #EDF4EE soft green | #162B1C |
| .surfaceElevated | #FFFFFF | #1F3D27 |
| .textPrimary | #0A2318 deep forest | #E8F5EC |
| .interactiveFill | #2D6A4F | #74C69D |
| .destructive | #C62828 | #EF5350 |
Get started
Preset themes are included in DesignFoundation at no cost. MIT licensed.