ax-design-ref
npx machina-cli add skill Kasempiternal/axiom-v2/ax-design-ref --openclawDesign API Reference
Quick Patterns
Semantic Color Hierarchy
// Labels (foreground)
Text("Title").foregroundStyle(.primary) // label
Text("Subtitle").foregroundStyle(.secondary) // secondaryLabel
Text("Detail").foregroundStyle(.tertiary) // tertiaryLabel
// Backgrounds
Color(.systemBackground) // Main
Color(.secondarySystemBackground) // Grouped element
Color(.systemGroupedBackground) // Settings-style list
// Fills (semi-transparent, for controls)
Color(.systemFill)
Color(.secondarySystemFill)
Dynamic Type with System Styles
.font(.largeTitle) // 34pt -- page headings
.font(.title) // 28pt -- secondary headings
.font(.headline) // 17pt semibold -- emphasized body
.font(.body) // 17pt -- primary body
.font(.callout) // 16pt -- secondary body
.font(.footnote) // 13pt -- footnotes
.font(.caption) // 12pt -- small annotations
SF Symbols Effect API (SwiftUI)
// Discrete (value change trigger)
.symbolEffect(.bounce, value: count)
.symbolEffect(.wiggle, value: count) // iOS 18+
// Indefinite (continuous while active)
.symbolEffect(.pulse, isActive: isLoading)
.symbolEffect(.breathe, isActive: true) // iOS 18+
.symbolEffect(.rotate, isActive: true) // iOS 18+
// Content transition (symbol swap)
.contentTransition(.symbolEffect(.replace))
// Transition (view enter/leave)
.transition(.symbolEffect(.appear))
// Draw (iOS 26+)
.symbolEffect(.drawOn, isActive: isComplete)
Liquid Glass (iOS 26+)
// Standard components adopt automatically with Xcode 26
// For custom views:
Button("Action") { }.glassEffect() // Controls
VStack { content }.glassBackgroundEffect() // Content containers
GlassEffectContainer { /* multiple glass views */ } // Optimization
Decision Tree
What design reference do you need?
|
+-- Colors?
| +-- Text/icons --> semantic label colors (.primary, .secondary, .tertiary)
| +-- Backgrounds --> systemBackground / systemGroupedBackground
| +-- Controls --> systemFill colors (semi-transparent)
| +-- Custom brand --> Color Set in asset catalog (light + dark + high contrast)
| +-- Separators --> Color(.separator) or Color(.opaqueSeparator)
|
+-- Typography?
| +-- System text style --> .font(.body), .font(.title), etc.
| +-- Rounded design --> .fontDesign(.rounded)
| +-- Custom font + scaling --> .font(.custom(name, size:, relativeTo: .body))
| +-- ScaledMetric --> @ScaledMetric var padding: CGFloat = 20
| +-- Tight/loose leading --> .font(.body.leading(.tight))
| +-- Monospaced --> SF Mono or .fontDesign(.monospaced)
|
+-- SF Symbols API?
| +-- Rendering mode --> .symbolRenderingMode(.hierarchical/.palette/.multicolor)
| +-- Tap feedback effect --> .symbolEffect(.bounce, value:)
| +-- Loading indicator --> .symbolEffect(.pulse, isActive:)
| +-- Symbol swap --> .contentTransition(.symbolEffect(.replace))
| +-- Draw animation --> .symbolEffect(.drawOn, isActive:) (iOS 26+)
| +-- UIKit effect --> imageView.addSymbolEffect(.bounce)
| +-- Variable value --> Image(systemName:, variableValue: 0.5)
|
+-- Liquid Glass?
| +-- What adopts automatically --> nav bars, tab bars, toolbars, sheets, controls
| +-- Custom glass control --> .glassEffect()
| +-- Custom glass container --> .glassBackgroundEffect()
| +-- Multiple glass views --> GlassEffectContainer { }
| +-- Backward compat --> UIDesignRequiresCompatibility = true in Info.plist
| +-- Clear glass variant --> .glassEffect(.clear) (only over rich backgrounds)
|
+-- Accessibility?
+-- Contrast ratio --> 4.5:1 min (7:1 for small text)
+-- Touch targets --> 44x44 points min (iOS)
+-- Reduce Motion --> @Environment(\.accessibilityReduceMotion)
+-- VoiceOver --> .accessibilityLabel("description")
+-- Color alone --> convey info with shape + text + color
Anti-Patterns
Colors
- Hardcoded
Color.black/.white-- use semantic colors that adapt to light/dark - Custom gray for text without contrast verification -- use
.secondaryfor automatic compliance - Hardcoded RGB in controls -- use
.tint(.blue)for automatic adaptation - Missing High Contrast color variants in asset catalog
Typography
.font(.system(size: 17))fixed size -- doesn't scale with Dynamic Type; use.font(.body)- Ultralight/Thin/Light font weights -- legibility issues at small sizes
.font()modifier with AttributedString paragraph styles -- environment override drops lineHeightMultiple; set font inside AttributedString instead- Missing
adjustsFontForContentSizeCategory = truein UIKit
SF Symbols
- Missing
.searchCompletion()on suggestions -- unrelated but common co-occurring issue .foregroundColor()with Multicolor mode -- overrides Apple's curated colors- Palette with fewer colors than layers -- extra layers reuse last color silently
- Missing
.accessibilityLabel-- VoiceOver reads raw symbol name - iOS 18+ effects without
#availablecheck -- crashes on iOS 17
Liquid Glass
- Custom backgrounds on navigation/toolbar --
.background(Color.blue)breaks glass effects .presentationBackground()on sheets -- remove it, system applies glass automatically- Hard-coded
.frame(height:)on controls/rows -- system determines height in iOS 26 .glassEffect()on content items (list rows, cards) -- glass is for navigation layer only- Glass-on-glass crowding without
GlassEffectContainer - Missing
.safeAreaPadding()with edge-to-edge glass -- content hits notch/home indicator
Deep Patterns
Color System
Background Hierarchy (Ungrouped vs Grouped)
| Level | Ungrouped | Grouped |
|---|---|---|
| Primary | .systemBackground | .systemGroupedBackground |
| Secondary | .secondarySystemBackground | .secondarySystemGroupedBackground |
| Tertiary | .tertiarySystemBackground | .tertiarySystemGroupedBackground |
Base vs Elevated Backgrounds
Base set for background apps; elevated set for foreground (lighter in Dark Mode for visual separation). iPad multitasking: slide-over uses elevated. Semi-opaque fill and separator colors adapt gracefully.
Materials (Background Blur)
.background(.ultraThinMaterial) // Minimal separation
.background(.thinMaterial) // Lighter weight
.background(.regularMaterial) // Default
.background(.thickMaterial) // Most separation
Use vibrant foreground colors (.primary, .secondary) on materials for legibility.
Custom Color Creation
- Assets.xcassets > Add Color Set
- Configure: Light, Dark, High Contrast Light, High Contrast Dark
- Use:
Color("BrandAccent")
Typography
San Francisco Font System
| Family | Use |
|---|---|
| SF Pro | General UI (iOS, iPadOS, macOS, tvOS) |
| SF Compact | watchOS, narrow columns |
| SF Mono | Code, monospaced text |
| SF Pro Rounded | Friendly/approachable interfaces |
| New York | Serif, editorial content |
Variable font axes: Weight (9 weights), Width (Condensed to Expanded), Optical Size (auto text/display switch at ~20pt).
Text Styles with Sizes
| Style | iOS Default | Use |
|---|---|---|
.largeTitle | 34pt | Primary page headings |
.title | 28pt | Secondary headings |
.title2 | 22pt | Tertiary headings |
.title3 | 20pt | Quaternary headings |
.headline | 17pt Semibold | Emphasized body |
.body | 17pt | Primary body |
.callout | 16pt | Secondary body |
.subheadline | 15pt | Tertiary body |
.footnote | 13pt | Footnotes |
.caption | 12pt | Small annotations |
.caption2 | 11pt | Smallest annotations |
Custom Font + Dynamic Type
// SwiftUI
Text("Custom").font(.custom("Avenir-Medium", size: 17, relativeTo: .body))
@ScaledMetric(relativeTo: .body) var padding: CGFloat = 20
// UIKit
let metrics = UIFontMetrics(forTextStyle: .body)
label.font = metrics.scaledFont(for: UIFont(name: "Avenir-Medium", size: 17)!)
label.adjustsFontForContentSizeCategory = true
Rounded Design
// SwiftUI
Text("Today").font(.largeTitle.bold()).fontDesign(.rounded)
// UIKit
let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .largeTitle).withDesign(.rounded)!
let font = UIFont(descriptor: desc, size: 0)
Leading Variants
Text("Tight").font(.body.leading(.tight)) // -2pt line height
Text("Loose").font(.body.leading(.loose)) // +2pt line height
AttributedString Typography Gotcha
// Font INSIDE AttributedString when using paragraph styles:
var s = AttributedString("Content")
s.font = .system(.body) // Set font in attributed content
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
Text(s) // No .font() modifier -- preserves paragraph styles
Tracking
Text("Tracked").tracking(2.0) // Use .tracking(), not .kerning()
// .tracking() disables ligatures when needed; .kerning() does not
SF Symbols Complete API
Display (SwiftUI)
Image(systemName: "star.fill")
.font(.title) // Scale with text style
.fontWeight(.bold) // Weight matching
.imageScale(.large) // Relative sizing
.symbolVariant(.circle.fill) // Programmatic variant
Display (UIKit)
let config = UIImage.SymbolConfiguration(pointSize: 24, weight: .bold, scale: .large)
let image = UIImage(systemName: "star.fill", withConfiguration: config)
Rendering Modes (SwiftUI)
.symbolRenderingMode(.monochrome) // Single color (default)
.symbolRenderingMode(.hierarchical) // Single color, auto opacity per layer
.symbolRenderingMode(.palette) // Explicit per-layer: .foregroundStyle(.red, .white, .blue)
.symbolRenderingMode(.multicolor) // Apple's fixed curated colors
Rendering Modes (UIKit)
UIImage.SymbolConfiguration(hierarchicalColor: .systemBlue)
UIImage.SymbolConfiguration(paletteColors: [.white, .systemBlue])
UIImage.SymbolConfiguration.preferringMulticolor()
// Combine: sizeConfig.applying(colorConfig)
All Effects Reference
| Effect | Category | iOS | Trigger |
|---|---|---|---|
| Bounce | Discrete | 17+ | .symbolEffect(.bounce, value:) |
| Pulse | Discrete/Indefinite | 17+ | value: or isActive: |
| Variable Color | Discrete/Indefinite | 17+ | .iterative, .cumulative, .reversing |
| Scale | Indefinite | 17+ | .scale.up/.down |
| Appear/Disappear | Transition | 17+ | .transition(.symbolEffect(.appear)) |
| Replace | Content Trans | 17+ | .contentTransition(.symbolEffect(.replace)) |
| Wiggle | Discrete/Indefinite | 18+ | .wiggle.forward/.backward (RTL-aware) |
| Rotate | Discrete/Indefinite | 18+ | .rotate.clockwise/.byLayer |
| Breathe | Discrete/Indefinite | 18+ | .breathe.plain/.pulse |
| Draw On/Off | Indefinite | 26+ | .drawOn.byLayer/.wholeSymbol/.individually |
| Variable Draw | Value-based | 26+ | .symbolVariableValueMode(.draw) |
| Gradient | Rendering | 26+ | .symbolColorRenderingMode(.gradient) |
Effect Options
.symbolEffect(.bounce, options: .repeat(3), value: count)
.symbolEffect(.pulse, options: .speed(2.0), isActive: true)
.symbolEffect(.breathe, options: .nonRepeating, isActive: true)
UIKit Effects
imageView.addSymbolEffect(.bounce)
imageView.addSymbolEffect(.pulse, options: .speed(2.0))
imageView.removeSymbolEffect(ofType: PulseSymbolEffect.self)
imageView.removeAllSymbolEffects()
// Content transition
imageView.setSymbolImage(newImage, contentTransition: .replace.downUp)
Custom Symbols
- Export SVG from design tool
- Import into SF Symbols app (File > Import)
- Annotate layers (Primary/Secondary/Tertiary) for rendering modes
- For Draw: add guide points (start, end, corner) per path
- Export as
.svgtemplate for Xcode asset catalog
Liquid Glass Adoption
What Adopts Automatically (Xcode 26)
Navigation bars, tab bars, toolbars, sheets, popovers, buttons, sliders, toggles, sidebars, split views, menus, action sheets.
Navigation Layer vs Content Layer
Navigation (Liquid Glass): tab bar, sidebar, toolbar
Content (no glass): articles, photos, data, list rows
Never apply .glassEffect() to content items.
Tab Bar to Sidebar Adaptation
TabView { ... }.tabViewStyle(.sidebarAdaptable)
// Tab bar on iPhone, sidebar on iPad/macOS
Tab Bar Minimize
TabView { ... }.tabBarMinimizeBehavior(.onScrollDown)
Background Extension Effect
NavigationSplitView {
Sidebar()
} detail: {
DetailView().backgroundExtensionEffect()
}
Scroll Edge Effects
.scrollEdgeEffectStyle(.hard, for: .top) // Obscure content under glass
.scrollEdgeEffectStyle(.soft) // Gradual fade
Controls
- Bordered buttons default to capsule shape
- New
controlSize(.extraLarge) - Remove hard-coded
.frame()dimensions - Use
containerRelativeShape()for concentric alignment
Sheets
- Increased corner radius, half sheets inset
- Remove
.presentationBackground()-- system handles glass material - Remove custom
UIVisualEffectView/UIBlurEffectbackgrounds
App Icons (iOS 26+)
Three layers: foreground, middle, background. Use Icon Composer (Xcode 26+). Appearance variants: light, dark, clear, tinted. Export layers as PNG/SVG with transparency.
UIBlurEffect Migration
| Legacy | Liquid Glass |
|---|---|
UIBlurEffect(style: .systemMaterial) | .glassEffect() |
UIBlurEffect(style: .systemUltraThinMaterial) | .glassEffect(.clear) |
UIVisualEffectView with blur | Remove, use .glassEffect() |
.background(.thinMaterial) | Adapts automatically or .glassEffect() |
Backward Compatibility
UIDesignRequiresCompatibility = true in Info.plist to maintain iOS 18 appearance while shipping with iOS 26 SDK.
Accessibility
Contrast Requirements
- Normal text (14pt+): 4.5:1 minimum
- Small text (<14pt): 7:1 recommended
- Large text (18pt+): 3:1 acceptable
- Semantic colors automatically meet AA
Touch Targets
| Platform | Minimum |
|---|---|
| iOS/iPadOS | 44x44 points |
| macOS | 20x20 points |
| tvOS | 60pt+ spacing |
Reduce Motion
@Environment(\.accessibilityReduceMotion) var reduceMotion
.animation(reduceMotion ? nil : .spring(), value: isExpanded)
Symbol effects auto-respect Reduce Motion. Only intervene if effects carry semantic meaning.
VoiceOver
Image(systemName: "square.and.arrow.up").accessibilityLabel("Share")
// Label provides automatic accessibility:
Label("Settings", systemImage: "gear")
Convey Info Beyond Color
HStack {
Image(systemName: isComplete ? "checkmark.circle.fill" : "xmark.circle.fill")
Text(isComplete ? "Complete" : "Incomplete")
}
.foregroundStyle(isComplete ? .green : .red)
Shapes & Geometry (iOS 26)
Three shape types:
- Fixed --
RoundedRectangle(cornerRadius: 12)constant radius - Capsule -- radius = half height, buttons/pills/controls
- Concentric --
containerRelativeShape(), nested elements maintain visual harmony
Concentricity principle: hardware curvature guides UI, shapes nest from window to sheet to card to button.
Inclusive Design
- Use plain, direct, respectful tone
- Address users as "you/your" not "the user"
- Feature diverse representation
- Provide inclusive gender options
- Avoid culture-specific expressions
- Colors carry different cultural meanings
Diagnostics
Color Contrast Failures
Use Accessibility Inspector or contrast calculators. Test Light + Dark + Increase Contrast. Solution: replace custom colors with semantic colors or verify 4.5:1 ratio.
Dynamic Type Not Scaling
Fixed font sizes (.system(size: 17)) don't scale. Use text styles (.body) or .custom(name, size:, relativeTo:). UIKit: use UIFontMetrics.scaledFont(for:) + adjustsFontForContentSizeCategory = true.
Liquid Glass Broken on Custom Components
Remove: custom .background(), .presentationBackground(), UIBlurEffect, hard-coded heights. Let system determine appearance. Test with Reduce Transparency, Increase Contrast, Reduce Motion.
Symbol Effect Not Playing
- Check iOS version requirement
- Check Reduce Motion setting
- Discrete:
value:must change. Indefinite:isActive:must be true - Check symbol compatibility in SF Symbols app
- Remove conflicting
.symbolEffect()modifiers
AttributedString Losing Paragraph Styles
Font set in .font() modifier overrides AttributedString. Set font inside the AttributedString directly and remove .font() from the Text view.
Related
ax-design-- quick HIG decisions, SF Symbols effects overview, design review defenseax-swiftui-ref-- SwiftUI animation system, layout APIs, navigationax-swiftui-- SwiftUI patterns and decision guidance
Source
git clone https://github.com/Kasempiternal/axiom-v2/blob/main/axiom-plugin/skills/ax-design-ref/SKILL.mdView on GitHub Overview
This skill consolidates a Design API Reference for the Axiom design system, covering semantic color hierarchy (labels, backgrounds, fills), typography with SF San Francisco styles and Dynamic Type, the full SF Symbols API (rendering modes, effects, transitions), the Liquid Glass adoption guide (controls, navigation, windows, icons, migration), and accessibility compliance. It translates these references into concrete SwiftUI patterns for real apps.
How This Skill Works
It documents code patterns and decision guidance that map the reference sections to SwiftUI implementations. It shows how to apply foregroundStyle colors, Color system backgrounds, dynamic typography with .font styles, SF Symbols effects and transitions, and Glass features like .glassEffect and GlassEffectContainer, including platform and version considerations.
When to Use It
- Architect a semantic color palette and mapping for labels and backgrounds using the Semantic Color Hierarchy.
- Define typography using system styles and Dynamic Type for headings, body, and accessibility, including tracking and leading choices.
- Implement SF Symbols with rendering modes, symbol effects, and content transitions across UI elements.
- Adopt Liquid Glass patterns for controls, containers, and navigation surfaces to achieve a cohesive glass look.
- Ensure accessibility compliance across color, typography, and symbol usage, and handle backward compatibility
Quick Start
- Step 1: Review the Design API Reference sections in the SKILL.md (Quick Patterns and Decision Tree) to identify required patterns for colors, typography, SF Symbols, and Liquid Glass.
- Step 2: Implement patterns in a sample SwiftUI view by applying semantic colors, system typography, SF Symbols effects, and glass features.
- Step 3: Validate accessibility and platform requirements; apply Info.plist settings for backward compatibility if needed (UIDesignRequiresCompatibility) and test on iOS versions that support the features
Best Practices
- Map text and icons to semantic colors using foregroundStyle(.primary/.secondary/.tertiary) for consistency.
- Use system color surfaces like Color(.systemBackground) and Color(.systemGroupedBackground) for main UI and lists.
- Prefer translucent fills with Color(.systemFill) and related variants for controls.
- Leverage SF Symbols API with rendering modes and symbolEffect, plus contentTransition for smooth icon changes.
- Apply Liquid Glass patterns with standard components and containers, and declare backward compatibility in Info.plist when needed
Example Use Cases
- Semantic color hierarchy in SwiftUI: mapping labels to foregroundStyle(.primary/.secondary/.tertiary) and backgrounds to systemBackground variants.
- Typography usage: applying system text styles like .largeTitle, .title, .body and enabling Dynamic Type for accessibility.
- SF Symbols usage: using symbolEffect for bounce or pulse, contentTransition for symbol swaps, and drawOn for draw animations (iOS 26+).
- Liquid Glass adoption: glassEffect on a Button, glassBackgroundEffect on a content container, and using GlassEffectContainer for multiple glass views.
- Migration guidance: follow the Decision Tree to migrate colors, typography, SF Symbols usage, and Glass patterns with backward compatibility notes