@mmerterden/multi-agent-pipeline 20.17.0 → 20.17.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/docs/facts.json +6 -6
  3. package/docs/features.md +1 -1
  4. package/install/catalog-history.json +1 -1
  5. package/manifest.json +85 -47
  6. package/package.json +1 -1
  7. package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
  8. package/pipeline/commands/multi-agent/update/SKILL.md +2 -2
  9. package/pipeline/multi-agent-refs/features/usage-reporting.md +106 -67
  10. package/pipeline/schemas/prefs.schema.json +23 -2
  11. package/pipeline/scripts/usage-identity.mjs +312 -53
  12. package/pipeline/scripts/usage-register.mjs +204 -85
  13. package/pipeline/scripts/usage-report.mjs +7 -5
  14. package/pipeline/skills/.skill-manifest.json +35 -15
  15. package/pipeline/skills/.skills-index.json +66 -11
  16. package/pipeline/skills/shared/README.md +18 -13
  17. package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +2 -2
  18. package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +2 -2
  19. package/pipeline/skills/shared/external/NOTICE-avdlee-swiftui-agent-skill.md +3 -1
  20. package/pipeline/skills/shared/external/NOTICE-dimillian-skills.md +2 -1
  21. package/pipeline/skills/shared/external/hig-app-icons/SKILL.md +159 -0
  22. package/pipeline/skills/shared/external/hig-app-icons/evals/evals.json +48 -0
  23. package/pipeline/skills/shared/external/hig-app-icons/evals/trigger-eval.json +22 -0
  24. package/pipeline/skills/shared/external/hig-app-icons/references/icon-workflow.md +115 -0
  25. package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +32 -4
  26. package/pipeline/skills/shared/external/hig-components-layout/evals/evals.json +47 -0
  27. package/pipeline/skills/shared/external/hig-components-layout/evals/trigger-eval.json +22 -0
  28. package/pipeline/skills/shared/external/hig-components-layout/references/bars-and-tabs.md +231 -0
  29. package/pipeline/skills/shared/external/hig-components-layout/references/containers.md +5 -30
  30. package/pipeline/skills/shared/external/hig-components-status/SKILL.md +1 -1
  31. package/pipeline/skills/shared/external/hig-foundations/SKILL.md +23 -4
  32. package/pipeline/skills/shared/external/hig-foundations/evals/evals.json +47 -0
  33. package/pipeline/skills/shared/external/hig-foundations/evals/trigger-eval.json +21 -0
  34. package/pipeline/skills/shared/external/hig-foundations/references/foundations-detail.md +34 -26
  35. package/pipeline/skills/shared/external/hig-foundations/references/type-color-spacing.md +219 -0
  36. package/pipeline/skills/shared/external/hig-inputs/SKILL.md +5 -4
  37. package/pipeline/skills/shared/external/hig-patterns/SKILL.md +19 -3
  38. package/pipeline/skills/shared/external/hig-patterns/references/onboarding-and-states.md +188 -0
  39. package/pipeline/skills/shared/external/hig-patterns/references/patterns.md +5 -11
  40. package/pipeline/skills/shared/external/hig-platforms/SKILL.md +17 -5
  41. package/pipeline/skills/shared/external/hig-platforms/references/ipad-layout.md +218 -0
  42. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +4 -1
  43. package/pipeline/skills/shared/external/ios-accessibility/references/large-content-and-appearance.md +135 -0
  44. package/pipeline/skills/shared/external/ios-design-review/SKILL.md +146 -0
  45. package/pipeline/skills/shared/external/ios-design-review/evals/evals.json +48 -0
  46. package/pipeline/skills/shared/external/ios-design-review/evals/trigger-eval.json +22 -0
  47. package/pipeline/skills/shared/external/ios-design-review/references/appearance-matrix.md +135 -0
  48. package/pipeline/skills/shared/external/ios-design-review/references/checklist.md +193 -0
  49. package/pipeline/skills/shared/external/ios-haptics/SKILL.md +191 -0
  50. package/pipeline/skills/shared/external/ios-haptics/evals/evals.json +49 -0
  51. package/pipeline/skills/shared/external/ios-haptics/evals/trigger-eval.json +22 -0
  52. package/pipeline/skills/shared/external/ios-haptics/references/core-haptics.md +215 -0
  53. package/pipeline/skills/shared/external/ios-iphone-duo/NOTICE.md +53 -0
  54. package/pipeline/skills/shared/external/ios-iphone-duo/SKILL.md +170 -0
  55. package/pipeline/skills/shared/external/ios-iphone-duo/evals/evals.json +50 -0
  56. package/pipeline/skills/shared/external/ios-iphone-duo/evals/trigger-eval.json +22 -0
  57. package/pipeline/skills/shared/external/ios-iphone-duo/references/api-map.md +212 -0
  58. package/pipeline/skills/shared/external/ios-iphone-duo/references/fixed-assumptions.md +145 -0
  59. package/pipeline/skills/shared/external/ios-iphone-duo/references/poses-and-panes.md +122 -0
  60. package/pipeline/skills/shared/external/ios-sf-symbols/SKILL.md +177 -0
  61. package/pipeline/skills/shared/external/ios-sf-symbols/evals/evals.json +49 -0
  62. package/pipeline/skills/shared/external/ios-sf-symbols/evals/trigger-eval.json +22 -0
  63. package/pipeline/skills/shared/external/ios-sf-symbols/references/effects-and-custom-symbols.md +135 -0
  64. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +38 -50
  65. package/pipeline/skills/shared/external/swiftui-animation/evals/evals.json +47 -0
  66. package/pipeline/skills/shared/external/swiftui-animation/evals/trigger-eval.json +22 -0
  67. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +7 -73
  68. package/pipeline/skills/shared/external/swiftui-animation/references/scroll-effects.md +185 -0
  69. package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +6 -6
  70. package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-advanced.md +3 -253
  71. package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-basics.md +4 -47
  72. package/pipeline/skills/shared/external/swiftui-expert-skill/references/animation-transitions.md +3 -111
  73. package/pipeline/skills/shared/external/swiftui-expert-skill/references/liquid-glass.md +11 -381
  74. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +184 -224
  75. package/pipeline/skills/shared/external/swiftui-liquid-glass/evals/evals.json +47 -0
  76. package/pipeline/skills/shared/external/swiftui-liquid-glass/evals/trigger-eval.json +22 -0
  77. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +246 -33
  78. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/uikit-glass.md +227 -0
  79. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +15 -18
  80. package/pipeline/skills/shared/external/swiftui-ui-patterns/references/components-index.md +1 -1
  81. package/pipeline/skills/shared/external/swiftui-ui-patterns/references/haptics.md +6 -68
  82. package/pipeline/skills/skills-index.md +16 -11
  83. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +0 -786
@@ -1,12 +1,12 @@
1
1
  # SwiftUI Transitions
2
2
 
3
- Transitions for view insertion/removal, custom transitions, and the Animatable protocol.
3
+ Transitions for view insertion/removal and the Animatable protocol.
4
+
5
+ > Local trim: built-in, combined, asymmetric and custom transitions are maintained in the `swiftui-animation` skill, which owns SwiftUI motion. This file keeps the animation-context rule, identity and the Animatable protocol.
4
6
 
5
7
  ## Table of Contents
6
8
  - [Property Animations vs Transitions](#property-animations-vs-transitions)
7
9
  - [Basic Transitions](#basic-transitions)
8
- - [Asymmetric Transitions](#asymmetric-transitions)
9
- - [Custom Transitions](#custom-transitions)
10
10
  - [Identity and Transitions](#identity-and-transitions)
11
11
  - [The Animatable Protocol](#the-animatable-protocol)
12
12
 
@@ -76,114 +76,6 @@ if showDetail {
76
76
  }
77
77
  ```
78
78
 
79
- ### Built-in Transitions
80
-
81
- | Transition | Effect |
82
- |------------|--------|
83
- | `.opacity` | Fade in/out (default) |
84
- | `.scale` | Scale up/down |
85
- | `.slide` | Slide from leading edge |
86
- | `.move(edge:)` | Move from specific edge |
87
- | `.offset(x:y:)` | Move by offset amount |
88
-
89
- ### Combining Transitions
90
-
91
- ```swift
92
- // Parallel - both simultaneously
93
- .transition(.slide.combined(with: .opacity))
94
-
95
- // Chained
96
- .transition(.scale.combined(with: .opacity).combined(with: .offset(y: 20)))
97
- ```
98
-
99
- ---
100
-
101
- ## Asymmetric Transitions
102
-
103
- Different animations for insertion vs removal.
104
-
105
- ```swift
106
- // GOOD - different animations for insert/remove
107
- if showCard {
108
- CardView()
109
- .transition(
110
- .asymmetric(
111
- insertion: .scale.combined(with: .opacity),
112
- removal: .move(edge: .bottom).combined(with: .opacity)
113
- )
114
- )
115
- }
116
-
117
- // BAD - same transition when different behaviors needed
118
- if showCard {
119
- CardView()
120
- .transition(.slide) // Same both ways - may feel awkward
121
- }
122
- ```
123
-
124
- ---
125
-
126
- ## Custom Transitions
127
-
128
- ### Pre-iOS 17
129
-
130
- ```swift
131
- struct BlurModifier: ViewModifier {
132
- var radius: CGFloat
133
- func body(content: Content) -> some View {
134
- content.blur(radius: radius)
135
- }
136
- }
137
-
138
- extension AnyTransition {
139
- static func blur(radius: CGFloat) -> AnyTransition {
140
- .modifier(
141
- active: BlurModifier(radius: radius),
142
- identity: BlurModifier(radius: 0)
143
- )
144
- }
145
- }
146
-
147
- // Usage
148
- .transition(.blur(radius: 10))
149
- ```
150
-
151
- ### iOS 17+ (Transition Protocol)
152
-
153
- ```swift
154
- struct BlurTransition: Transition {
155
- var radius: CGFloat
156
-
157
- func body(content: Content, phase: TransitionPhase) -> some View {
158
- content
159
- .blur(radius: phase.isIdentity ? 0 : radius)
160
- .opacity(phase.isIdentity ? 1 : 0)
161
- }
162
- }
163
-
164
- // Usage
165
- .transition(BlurTransition(radius: 10))
166
- ```
167
-
168
- ### Good vs Bad Custom Transitions
169
-
170
- ```swift
171
- // GOOD - reusable transition
172
- if showContent {
173
- ContentView()
174
- .transition(BlurTransition(radius: 10))
175
- }
176
-
177
- // BAD - inline logic (won't animate on removal!)
178
- if showContent {
179
- ContentView()
180
- .blur(radius: showContent ? 0 : 10) // Not a transition
181
- .opacity(showContent ? 1 : 0)
182
- }
183
- ```
184
-
185
- ---
186
-
187
79
  ## Identity and Transitions
188
80
 
189
81
  View identity changes trigger transitions, not property animations.
@@ -1,26 +1,26 @@
1
1
  # SwiftUI Liquid Glass Reference (iOS 26+)
2
2
 
3
+ Local trim: the API reference, examples, fallbacks and checklist are
4
+ maintained in the `swiftui-liquid-glass` skill, which owns Liquid
5
+ Glass for SwiftUI and UIKit (where glass belongs, regular versus clear,
6
+ `GlassEffectContainer`, morphing, modifier order, concentric shapes, custom
7
+ bars, fallbacks, accessibility). This file keeps the guidance specific to how
8
+ this skill applies it.
9
+
3
10
  ## Table of Contents
4
11
 
5
12
  - [Overview](#overview)
6
13
  - [Availability](#availability)
7
- - [Core APIs](#core-apis)
8
- - [GlassEffectContainer](#glasseffectcontainer)
9
- - [Glass Button Styles](#glass-button-styles)
10
- - [Morphing Transitions](#morphing-transitions)
11
- - [Modifier Order](#modifier-order)
12
- - [Complete Examples](#complete-examples)
13
- - [Fallback Strategies](#fallback-strategies)
14
14
  - [Design System Notes](#design-system-notes)
15
- - [Best Practices](#best-practices)
16
- - [Checklist](#checklist)
17
15
 
18
16
  ## Overview
19
17
 
20
- Liquid Glass is Apple's new design language introduced in iOS 26. It provides translucent, dynamic surfaces that respond to content and user interaction. This reference covers the native SwiftUI APIs for implementing Liquid Glass effects.
18
+ Liquid Glass is Apple's design language introduced in iOS 26. It provides translucent, dynamic surfaces that respond to content and user interaction.
21
19
 
22
20
  **Only adopt Liquid Glass when explicitly requested by the user.** Do not proactively convert existing UI to glass effects.
23
21
 
22
+ For any implementation or review, load the `swiftui-liquid-glass` skill.
23
+
24
24
  ## Availability
25
25
 
26
26
  All Liquid Glass APIs require iOS 26 or later. Always provide fallbacks:
@@ -33,339 +33,6 @@ if #available(iOS 26, *) {
33
33
  }
34
34
  ```
35
35
 
36
- ## Core APIs
37
-
38
- ### glassEffect Modifier
39
-
40
- The primary modifier for applying glass effects to views:
41
-
42
- ```swift
43
- .glassEffect(_ style: GlassEffectStyle = .regular, in shape: some Shape = .rect)
44
- ```
45
-
46
- #### Basic Usage
47
-
48
- ```swift
49
- Text("Hello")
50
- .padding()
51
- .glassEffect() // Default regular style, rect shape
52
- ```
53
-
54
- #### With Shape
55
-
56
- ```swift
57
- Text("Rounded Glass")
58
- .padding()
59
- .glassEffect(in: .rect(cornerRadius: 16))
60
-
61
- Image(systemName: "star")
62
- .padding()
63
- .glassEffect(in: .circle)
64
-
65
- Text("Capsule")
66
- .padding(.horizontal, 20)
67
- .padding(.vertical, 10)
68
- .glassEffect(in: .capsule)
69
- ```
70
-
71
- ### GlassEffectStyle
72
-
73
- #### Prominence Levels
74
-
75
- ```swift
76
- .glassEffect(.regular) // Standard glass appearance
77
- .glassEffect(.prominent) // More visible, higher contrast
78
- ```
79
-
80
- #### Tinting
81
-
82
- Add color tint to the glass:
83
-
84
- ```swift
85
- .glassEffect(.regular.tint(.blue))
86
- .glassEffect(.prominent.tint(.red.opacity(0.3)))
87
- ```
88
-
89
- #### Interactivity
90
-
91
- Make glass respond to touch/pointer hover:
92
-
93
- ```swift
94
- // Interactive glass - responds to user interaction
95
- .glassEffect(.regular.interactive())
96
-
97
- // Combined with tint
98
- .glassEffect(.regular.tint(.blue).interactive())
99
- ```
100
-
101
- **Important**: Only use `.interactive()` on elements that actually respond to user input (buttons, tappable views, focusable elements).
102
-
103
- ## GlassEffectContainer
104
-
105
- Wraps multiple glass elements for proper visual grouping and spacing.
106
-
107
- **Glass cannot sample other glass.** The glass material reflects and refracts light by sampling content from an area larger than itself. Nearby glass elements in different containers will produce inconsistent visual results because they cannot sample each other. `GlassEffectContainer` gives grouped elements a shared sampling region, ensuring a consistent appearance.
108
-
109
- ```swift
110
- GlassEffectContainer {
111
- HStack {
112
- Button("One") { }
113
- .glassEffect()
114
- Button("Two") { }
115
- .glassEffect()
116
- }
117
- }
118
- ```
119
-
120
- ### With Spacing
121
-
122
- Control the visual spacing between glass elements:
123
-
124
- ```swift
125
- GlassEffectContainer(spacing: 24) {
126
- HStack(spacing: 24) {
127
- GlassChip(icon: "pencil")
128
- GlassChip(icon: "eraser")
129
- GlassChip(icon: "trash")
130
- }
131
- }
132
- ```
133
-
134
- **Note**: The container's `spacing` parameter should match the actual spacing in your layout for proper glass effect rendering.
135
-
136
- > Source: "Build a SwiftUI app with the new design" (WWDC25, session 323)
137
-
138
- ## Glass Button Styles
139
-
140
- Built-in button styles for glass appearance:
141
-
142
- ```swift
143
- // Standard glass button
144
- Button("Action") { }
145
- .buttonStyle(.glass)
146
-
147
- // Prominent glass button (higher visibility)
148
- Button("Primary Action") { }
149
- .buttonStyle(.glassProminent)
150
- ```
151
-
152
- ### Custom Glass Buttons
153
-
154
- For more control, apply glass effect manually:
155
-
156
- ```swift
157
- Button(action: { }) {
158
- Label("Settings", systemImage: "gear")
159
- .padding()
160
- }
161
- .glassEffect(.regular.interactive(), in: .capsule)
162
- ```
163
-
164
- ## Morphing Transitions
165
-
166
- Create smooth transitions between glass elements using `glassEffectID` and `@Namespace`:
167
-
168
- ```swift
169
- struct MorphingExample: View {
170
- @Namespace private var animation
171
- @State private var isExpanded = false
172
-
173
- var body: some View {
174
- GlassEffectContainer {
175
- if isExpanded {
176
- ExpandedCard()
177
- .glassEffect()
178
- .glassEffectID("card", in: animation)
179
- } else {
180
- CompactCard()
181
- .glassEffect()
182
- .glassEffectID("card", in: animation)
183
- }
184
- }
185
- .animation(.smooth, value: isExpanded)
186
- }
187
- }
188
- ```
189
-
190
- ### Requirements for Morphing
191
-
192
- 1. Both views must have the same `glassEffectID`
193
- 2. Use the same `@Namespace`
194
- 3. Wrap in `GlassEffectContainer`
195
- 4. Apply animation to the container or parent
196
-
197
- ## Modifier Order
198
-
199
- **Critical**: Apply `glassEffect` after layout and visual modifiers:
200
-
201
- ```swift
202
- // CORRECT order
203
- Text("Label")
204
- .font(.headline) // 1. Typography
205
- .foregroundStyle(.primary) // 2. Color
206
- .padding() // 3. Layout
207
- .glassEffect() // 4. Glass effect LAST
208
-
209
- // WRONG order - glass applied too early
210
- Text("Label")
211
- .glassEffect() // Wrong position
212
- .padding()
213
- .font(.headline)
214
- ```
215
-
216
- ## Complete Examples
217
-
218
- ### Toolbar with Glass Buttons
219
-
220
- ```swift
221
- struct GlassToolbar: View {
222
- var body: some View {
223
- if #available(iOS 26, *) {
224
- GlassEffectContainer(spacing: 16) {
225
- HStack(spacing: 16) {
226
- ToolbarButton(icon: "pencil", action: { })
227
- ToolbarButton(icon: "eraser", action: { })
228
- ToolbarButton(icon: "scissors", action: { })
229
- Spacer()
230
- ToolbarButton(icon: "square.and.arrow.up", action: { })
231
- }
232
- .padding(.horizontal)
233
- }
234
- } else {
235
- // Fallback toolbar
236
- HStack(spacing: 16) {
237
- // ... fallback implementation
238
- }
239
- }
240
- }
241
- }
242
-
243
- struct ToolbarButton: View {
244
- let icon: String
245
- let action: () -> Void
246
-
247
- var body: some View {
248
- Button(action: action) {
249
- Image(systemName: icon)
250
- .font(.title2)
251
- .frame(width: 44, height: 44)
252
- }
253
- .glassEffect(.regular.interactive(), in: .circle)
254
- }
255
- }
256
- ```
257
-
258
- ### Card with Glass Effect
259
-
260
- ```swift
261
- struct GlassCard: View {
262
- let title: String
263
- let subtitle: String
264
-
265
- var body: some View {
266
- if #available(iOS 26, *) {
267
- cardContent
268
- .glassEffect(.regular, in: .rect(cornerRadius: 20))
269
- } else {
270
- cardContent
271
- .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
272
- }
273
- }
274
-
275
- private var cardContent: some View {
276
- VStack(alignment: .leading, spacing: 8) {
277
- Text(title)
278
- .font(.headline)
279
- Text(subtitle)
280
- .font(.subheadline)
281
- .foregroundStyle(.secondary)
282
- }
283
- .padding()
284
- .frame(maxWidth: .infinity, alignment: .leading)
285
- }
286
- }
287
- ```
288
-
289
- ### Segmented Control
290
-
291
- ```swift
292
- struct GlassSegmentedControl: View {
293
- @Binding var selection: Int
294
- let options: [String]
295
- @Namespace private var animation
296
-
297
- var body: some View {
298
- if #available(iOS 26, *) {
299
- GlassEffectContainer(spacing: 4) {
300
- HStack(spacing: 4) {
301
- ForEach(options.indices, id: \.self) { index in
302
- Button(options[index]) {
303
- withAnimation(.smooth) {
304
- selection = index
305
- }
306
- }
307
- .padding(.horizontal, 16)
308
- .padding(.vertical, 8)
309
- .glassEffect(
310
- selection == index ? .prominent.interactive() : .regular.interactive(),
311
- in: .capsule
312
- )
313
- .glassEffectID(selection == index ? "selected" : "option\(index)", in: animation)
314
- }
315
- }
316
- .padding(4)
317
- }
318
- } else {
319
- Picker("Options", selection: $selection) {
320
- ForEach(options.indices, id: \.self) { index in
321
- Text(options[index]).tag(index)
322
- }
323
- }
324
- .pickerStyle(.segmented)
325
- }
326
- }
327
- }
328
- ```
329
-
330
- ## Fallback Strategies
331
-
332
- ### Using Materials
333
-
334
- ```swift
335
- if #available(iOS 26, *) {
336
- content.glassEffect()
337
- } else {
338
- content.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
339
- }
340
- ```
341
-
342
- ### Available Materials for Fallback
343
-
344
- - `.ultraThinMaterial` - Closest to glass appearance
345
- - `.thinMaterial` - Slightly more opaque
346
- - `.regularMaterial` - Standard blur
347
- - `.thickMaterial` - More opaque
348
- - `.ultraThickMaterial` - Most opaque
349
-
350
- ### Conditional Modifier Extension
351
-
352
- ```swift
353
- extension View {
354
- @ViewBuilder
355
- func glassEffectWithFallback(
356
- _ style: GlassEffectStyle = .regular,
357
- in shape: some Shape = .rect,
358
- fallbackMaterial: Material = .ultraThinMaterial
359
- ) -> some View {
360
- if #available(iOS 26, *) {
361
- self.glassEffect(style, in: shape)
362
- } else {
363
- self.background(fallbackMaterial, in: shape)
364
- }
365
- }
366
- }
367
- ```
368
-
369
36
  ## Design System Notes
370
37
 
371
38
  ### Toolbar Icons
@@ -374,43 +41,6 @@ In the new design, toolbar icons use **monochrome rendering** by default. The mo
374
41
 
375
42
  ### Sheet Presentations
376
43
 
377
- Partial-height sheets use a Liquid Glass background by default. If you previously used `presentationBackground(_:)` with a custom background, consider removing it to let the new material shine. Sheets can morph out of the glass controls that present them using `navigationZoomTransition`.
378
-
379
- ### Scroll Edge Effects
380
-
381
- An automatic scroll edge effect blurs and fades content under system toolbars to keep controls legible. Remove any custom background-darkening effects behind bar items, as they will interfere.
44
+ Partial-height sheets use a Liquid Glass background by default. If you previously used `presentationBackground(_:)` with a custom background, consider removing it to let the new material shine. Sheets can morph out of the glass controls that present them using a zoom navigation transition (`matchedTransitionSource(id:in:)` with `.navigationTransition(.zoom(sourceID:in:))`).
382
45
 
383
46
  > Source: "Build a SwiftUI app with the new design" (WWDC25, session 323)
384
-
385
- ## Best Practices
386
-
387
- ### Do
388
-
389
- - Use `GlassEffectContainer` for grouped glass elements (glass cannot sample other glass)
390
- - Apply glass after layout modifiers
391
- - Use `.interactive()` only on tappable elements
392
- - Match container spacing with layout spacing
393
- - Provide material-based fallbacks for older iOS
394
- - Keep glass shapes consistent within a feature
395
- - Remove custom `presentationBackground(_:)` on sheets to use the default glass material
396
-
397
- ### Don't
398
-
399
- - Apply glass to every element (use sparingly)
400
- - Use `.interactive()` on static content
401
- - Mix different corner radii arbitrarily
402
- - Forget iOS version checks
403
- - Apply glass before padding/frame modifiers
404
- - Nest `GlassEffectContainer` unnecessarily
405
- - Add custom darkening backgrounds behind toolbars (conflicts with scroll edge effect)
406
-
407
- ## Checklist
408
-
409
- - [ ] `#available(iOS 26, *)` with fallback
410
- - [ ] `GlassEffectContainer` wraps grouped elements
411
- - [ ] `.glassEffect()` applied after layout modifiers
412
- - [ ] `.interactive()` only on user-interactable elements
413
- - [ ] `glassEffectID` with `@Namespace` for morphing
414
- - [ ] Consistent shapes and spacing across feature
415
- - [ ] Container spacing matches layout spacing
416
- - [ ] Appropriate prominence levels used