# Design System Colors, typography, spacing, and visual patterns for professional macOS apps. ```swift import SwiftUI extension Color { // Use semantic colors that adapt to light/dark mode static let background = Color(NSColor.windowBackgroundColor) static let secondaryBackground = Color(NSColor.controlBackgroundColor) static let tertiaryBackground = Color(NSColor.underPageBackgroundColor) // Text static let primaryText = Color(NSColor.labelColor) static let secondaryText = Color(NSColor.secondaryLabelColor) static let tertiaryText = Color(NSColor.tertiaryLabelColor) static let quaternaryText = Color(NSColor.quaternaryLabelColor) // Controls static let controlAccent = Color.accentColor static let controlBackground = Color(NSColor.controlColor) static let selectedContent = Color(NSColor.selectedContentBackgroundColor) // Separators static let separator = Color(NSColor.separatorColor) static let gridLine = Color(NSColor.gridColor) } // Usage Text("Hello") .foregroundStyle(.primaryText) .background(.background) ``` ```swift extension Color { // Define once, use everywhere static let appPrimary = Color("AppPrimary") // From asset catalog static let appSecondary = Color("AppSecondary") // Or programmatic static let success = Color(red: 0.2, green: 0.8, blue: 0.4) static let warning = Color(red: 1.0, green: 0.8, blue: 0.0) static let error = Color(red: 0.9, green: 0.3, blue: 0.3) } // Asset catalog with light/dark variants // Assets.xcassets/AppPrimary.colorset/Contents.json: /* { "colors" : [ { "color" : { "color-space" : "srgb", "components" : { "red" : "0.2", "green" : "0.5", "blue" : "1.0" } }, "idiom" : "universal" }, { "appearances" : [ { "appearance" : "luminosity", "value" : "dark" } ], "color" : { "color-space" : "srgb", "components" : { "red" : "0.4", "green" : "0.7", "blue" : "1.0" } }, "idiom" : "universal" } ] } */ ``` ```swift extension Font { // System fonts static let displayLarge = Font.system(size: 34, weight: .bold, design: .default) static let displayMedium = Font.system(size: 28, weight: .semibold) static let displaySmall = Font.system(size: 22, weight: .semibold) static let headlineLarge = Font.system(size: 17, weight: .semibold) static let headlineMedium = Font.system(size: 15, weight: .semibold) static let headlineSmall = Font.system(size: 13, weight: .semibold) static let bodyLarge = Font.system(size: 15, weight: .regular) static let bodyMedium = Font.system(size: 13, weight: .regular) static let bodySmall = Font.system(size: 11, weight: .regular) // Monospace for code static let codeLarge = Font.system(size: 14, weight: .regular, design: .monospaced) static let codeMedium = Font.system(size: 12, weight: .regular, design: .monospaced) static let codeSmall = Font.system(size: 10, weight: .regular, design: .monospaced) } // Usage Text("Title") .font(.displayMedium) Text("Body text") .font(.bodyMedium) Text("let x = 42") .font(.codeMedium) ``` ```swift enum Spacing { static let xxxs: CGFloat = 2 static let xxs: CGFloat = 4 static let xs: CGFloat = 8 static let sm: CGFloat = 12 static let md: CGFloat = 16 static let lg: CGFloat = 24 static let xl: CGFloat = 32 static let xxl: CGFloat = 48 static let xxxl: CGFloat = 64 } // Usage VStack(spacing: Spacing.md) { Text("Title") Text("Subtitle") } .padding(Spacing.lg) HStack(spacing: Spacing.sm) { Image(systemName: "star") Text("Favorite") } ``` ```swift enum CornerRadius { static let small: CGFloat = 4 static let medium: CGFloat = 8 static let large: CGFloat = 12 static let xlarge: CGFloat = 16 } // Usage RoundedRectangle(cornerRadius: CornerRadius.medium) .fill(.secondaryBackground) Text("Tag") .padding(.horizontal, Spacing.sm) .padding(.vertical, Spacing.xxs) .background(.controlBackground, in: RoundedRectangle(cornerRadius: CornerRadius.small)) ``` ```swift extension View { func cardShadow() -> some View { shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2) } func elevatedShadow() -> some View { shadow(color: .black.opacity(0.15), radius: 8, x: 0, y: 4) } func subtleShadow() -> some View { shadow(color: .black.opacity(0.05), radius: 2, x: 0, y: 1) } } // Usage CardView() .cardShadow() ``` ```swift struct PrimaryButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .font(.headlineMedium) .foregroundStyle(.white) .padding(.horizontal, Spacing.md) .padding(.vertical, Spacing.sm) .background( RoundedRectangle(cornerRadius: CornerRadius.medium) .fill(Color.accentColor) ) .opacity(configuration.isPressed ? 0.8 : 1.0) } } struct SecondaryButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .font(.headlineMedium) .foregroundStyle(.accentColor) .padding(.horizontal, Spacing.md) .padding(.vertical, Spacing.sm) .background( RoundedRectangle(cornerRadius: CornerRadius.medium) .stroke(Color.accentColor, lineWidth: 1) ) .opacity(configuration.isPressed ? 0.8 : 1.0) } } // Usage Button("Save") { save() } .buttonStyle(PrimaryButtonStyle()) Button("Cancel") { cancel() } .buttonStyle(SecondaryButtonStyle()) ``` ```swift struct CardStyle: ViewModifier { func body(content: Content) -> some View { content .padding(Spacing.md) .background( RoundedRectangle(cornerRadius: CornerRadius.large) .fill(.secondaryBackground) ) .cardShadow() } } extension View { func cardStyle() -> some View { modifier(CardStyle()) } } // Usage VStack { Text("Card Title") Text("Card content") } .cardStyle() ``` ```swift struct ItemRow: View { let item: Item let isSelected: Bool var body: some View { HStack(spacing: Spacing.sm) { Image(systemName: item.icon) .foregroundStyle(isSelected ? .white : .secondaryText) VStack(alignment: .leading, spacing: Spacing.xxs) { Text(item.name) .font(.headlineSmall) .foregroundStyle(isSelected ? .white : .primaryText) Text(item.subtitle) .font(.bodySmall) .foregroundStyle(isSelected ? .white.opacity(0.8) : .secondaryText) } Spacer() Text(item.date.formatted(date: .abbreviated, time: .omitted)) .font(.bodySmall) .foregroundStyle(isSelected ? .white.opacity(0.8) : .tertiaryText) } .padding(.horizontal, Spacing.sm) .padding(.vertical, Spacing.xs) .background( RoundedRectangle(cornerRadius: CornerRadius.small) .fill(isSelected ? Color.accentColor : .clear) ) } } ``` ```swift struct StyledTextField: View { let placeholder: String @Binding var text: String var body: some View { TextField(placeholder, text: $text) .textFieldStyle(.plain) .font(.bodyMedium) .padding(Spacing.sm) .background( RoundedRectangle(cornerRadius: CornerRadius.medium) .fill(.controlBackground) ) .overlay( RoundedRectangle(cornerRadius: CornerRadius.medium) .stroke(.separator, lineWidth: 1) ) } } ``` ```swift // Use SF Symbols Image(systemName: "doc.text") Image(systemName: "folder.fill") Image(systemName: "gear") // Consistent sizing Image(systemName: "star") .font(.system(size: 16, weight: .medium)) // With colors Image(systemName: "checkmark.circle.fill") .symbolRenderingMode(.hierarchical) .foregroundStyle(.green) // Multicolor Image(systemName: "externaldrive.badge.checkmark") .symbolRenderingMode(.multicolor) ``` ```swift // Standard durations enum AnimationDuration { static let fast: Double = 0.15 static let normal: Double = 0.25 static let slow: Double = 0.4 } // Common animations extension Animation { static let defaultSpring = Animation.spring(response: 0.3, dampingFraction: 0.7) static let quickSpring = Animation.spring(response: 0.2, dampingFraction: 0.8) static let gentleSpring = Animation.spring(response: 0.5, dampingFraction: 0.7) static let easeOut = Animation.easeOut(duration: AnimationDuration.normal) static let easeIn = Animation.easeIn(duration: AnimationDuration.normal) } // Usage withAnimation(.defaultSpring) { isExpanded.toggle() } // Respect reduce motion struct AnimationSettings { static var prefersReducedMotion: Bool { NSWorkspace.shared.accessibilityDisplayShouldReduceMotion } static func animation(_ animation: Animation) -> Animation? { prefersReducedMotion ? nil : animation } } ``` ```swift // Automatic adaptation struct ContentView: View { @Environment(\.colorScheme) var colorScheme var body: some View { VStack { // Semantic colors adapt automatically Text("Title") .foregroundStyle(.primaryText) .background(.background) // Manual override when needed Image("logo") .colorInvert() // Only if needed } } } // Force scheme for preview #Preview("Dark Mode") { ContentView() .preferredColorScheme(.dark) } ``` ```swift // Dynamic type support Text("Title") .font(.headline) // Scales with user settings // Custom fonts with scaling @ScaledMetric(relativeTo: .body) var customSize: CGFloat = 14 Text("Custom") .font(.system(size: customSize)) // Contrast Button("Action") { } .foregroundStyle(.white) .background(.accentColor) // Ensure contrast ratio >= 4.5:1 // Reduce transparency @Environment(\.accessibilityReduceTransparency) var reduceTransparency VStack { // content } .background(reduceTransparency ? .background : .background.opacity(0.8)) ```