Get the FREE Ultimate OpenClaw Setup Guide →

ax-design-ref

npx machina-cli add skill Kasempiternal/axiom-v2/ax-design-ref --openclaw
Files (1)
SKILL.md
17.0 KB

Design 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 .secondary for 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 = true in 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 #available check -- 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)

LevelUngroupedGrouped
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

  1. Assets.xcassets > Add Color Set
  2. Configure: Light, Dark, High Contrast Light, High Contrast Dark
  3. Use: Color("BrandAccent")

Typography

San Francisco Font System

FamilyUse
SF ProGeneral UI (iOS, iPadOS, macOS, tvOS)
SF CompactwatchOS, narrow columns
SF MonoCode, monospaced text
SF Pro RoundedFriendly/approachable interfaces
New YorkSerif, editorial content

Variable font axes: Weight (9 weights), Width (Condensed to Expanded), Optical Size (auto text/display switch at ~20pt).

Text Styles with Sizes

StyleiOS DefaultUse
.largeTitle34ptPrimary page headings
.title28ptSecondary headings
.title222ptTertiary headings
.title320ptQuaternary headings
.headline17pt SemiboldEmphasized body
.body17ptPrimary body
.callout16ptSecondary body
.subheadline15ptTertiary body
.footnote13ptFootnotes
.caption12ptSmall annotations
.caption211ptSmallest 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

EffectCategoryiOSTrigger
BounceDiscrete17+.symbolEffect(.bounce, value:)
PulseDiscrete/Indefinite17+value: or isActive:
Variable ColorDiscrete/Indefinite17+.iterative, .cumulative, .reversing
ScaleIndefinite17+.scale.up/.down
Appear/DisappearTransition17+.transition(.symbolEffect(.appear))
ReplaceContent Trans17+.contentTransition(.symbolEffect(.replace))
WiggleDiscrete/Indefinite18+.wiggle.forward/.backward (RTL-aware)
RotateDiscrete/Indefinite18+.rotate.clockwise/.byLayer
BreatheDiscrete/Indefinite18+.breathe.plain/.pulse
Draw On/OffIndefinite26+.drawOn.byLayer/.wholeSymbol/.individually
Variable DrawValue-based26+.symbolVariableValueMode(.draw)
GradientRendering26+.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

  1. Export SVG from design tool
  2. Import into SF Symbols app (File > Import)
  3. Annotate layers (Primary/Secondary/Tertiary) for rendering modes
  4. For Draw: add guide points (start, end, corner) per path
  5. Export as .svg template 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/UIBlurEffect backgrounds

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

LegacyLiquid Glass
UIBlurEffect(style: .systemMaterial).glassEffect()
UIBlurEffect(style: .systemUltraThinMaterial).glassEffect(.clear)
UIVisualEffectView with blurRemove, 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

PlatformMinimum
iOS/iPadOS44x44 points
macOS20x20 points
tvOS60pt+ 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:

  1. Fixed -- RoundedRectangle(cornerRadius: 12) constant radius
  2. Capsule -- radius = half height, buttons/pills/controls
  3. 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

  1. Check iOS version requirement
  2. Check Reduce Motion setting
  3. Discrete: value: must change. Indefinite: isActive: must be true
  4. Check symbol compatibility in SF Symbols app
  5. 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 defense
  • ax-swiftui-ref -- SwiftUI animation system, layout APIs, navigation
  • ax-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

  1. 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.
  2. Step 2: Implement patterns in a sample SwiftUI view by applying semantic colors, system typography, SF Symbols effects, and glass features.
  3. 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

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers