toolkit/packages/skills/liquid-glass/SKILL.md
iOS 26 Liquid Glass design system for SwiftUI. Implements Apple's glassmorphism material effects, depth-based layering, and adaptive tinting. Follows Apple Human Interface Guidelines for glass materials. Use when: (1) Building iOS 26+ SwiftUI interfaces, (2) Implementing glassmorphism effects, (3) Creating translucent/frosted UI elements, (4) Designing with Apple's Liquid Glass aesthetic, (5) User mentions liquid glass, glassmorphism, or frosted glass UI.
npx skillsauth add stevengonsalvez/agents-in-a-box liquid-glassInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Liquid Glass is Apple's design language introduced in iOS 26 (2025). It features translucent, depth-aware materials that react to content behind them. This skill provides patterns for implementing Liquid Glass effects in SwiftUI.
// Thin material — barely visible, subtle blur
.background(.thinMaterial)
// Regular material — standard glass effect
.background(.regularMaterial)
// Thick material — more opaque, stronger effect
.background(.thickMaterial)
// Ultra-thin material — maximum transparency
.background(.ultraThinMaterial)
// Ultra-thick material — nearly opaque
.background(.ultraThickMaterial)
// Bar material — for navigation/tab bars
.background(.bar)
// New in iOS 26: native liquid glass effect
.glassEffect(.regular)
// With tinting
.glassEffect(.regular.tint(.blue))
// Interactive glass (responds to hover/press)
.glassEffect(.regular.interactive())
struct GlassCard<Content: View>: View {
let content: () -> Content
var body: some View {
content()
.padding(20)
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
.shadow(color: .black.opacity(0.1), radius: 10, y: 5)
.overlay(
RoundedRectangle(cornerRadius: 20, style: .continuous)
.stroke(.white.opacity(0.2), lineWidth: 0.5)
)
}
}
// Usage
GlassCard {
VStack(alignment: .leading, spacing: 8) {
Text("Title").font(.headline)
Text("Subtitle").font(.subheadline).foregroundStyle(.secondary)
}
}
struct GlassNavBar: View {
let title: String
var body: some View {
HStack {
Text(title)
.font(.largeTitle.bold())
Spacer()
}
.padding(.horizontal, 20)
.padding(.vertical, 12)
.background(.bar)
.overlay(alignment: .bottom) {
Divider().opacity(0.3)
}
}
}
struct GlassTabBar: View {
@Binding var selection: Int
let items: [(icon: String, label: String)]
var body: some View {
HStack {
ForEach(items.indices, id: \.self) { index in
Button {
withAnimation(.spring(response: 0.3)) {
selection = index
}
} label: {
VStack(spacing: 4) {
Image(systemName: items[index].icon)
.font(.system(size: 20))
Text(items[index].label)
.font(.caption2)
}
.foregroundStyle(selection == index ? .primary : .secondary)
.frame(maxWidth: .infinity)
}
}
}
.padding(.vertical, 8)
.background(.ultraThinMaterial)
.clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous))
.padding(.horizontal, 20)
}
}
struct GlassButton: View {
let title: String
let icon: String?
let action: () -> Void
var body: some View {
Button(action: action) {
HStack(spacing: 8) {
if let icon {
Image(systemName: icon)
}
Text(title).fontWeight(.medium)
}
.padding(.horizontal, 20)
.padding(.vertical, 12)
.background(.ultraThinMaterial)
.clipShape(Capsule())
.overlay(Capsule().stroke(.white.opacity(0.2), lineWidth: 0.5))
}
}
}
struct GlassSheet<Content: View>: View {
let content: () -> Content
var body: some View {
content()
.frame(maxWidth: .infinity)
.padding(24)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 32, style: .continuous))
.overlay(
RoundedRectangle(cornerRadius: 32, style: .continuous)
.stroke(.white.opacity(0.15), lineWidth: 0.5)
)
.shadow(color: .black.opacity(0.2), radius: 20, y: 10)
.padding(16)
}
}
// Glass that picks up color from content beneath
.background(.ultraThinMaterial)
.environment(\.colorScheme, .dark) // Force dark glass
// Tinted glass
ZStack {
Color.blue.opacity(0.15)
content
}
.background(.ultraThinMaterial)
// Text that adapts to material behind it
Text("Label")
.foregroundStyle(.primary) // Adapts to material
Text("Secondary")
.foregroundStyle(.secondary) // Reduced prominence
// Use semantic colors — they adapt to materials
Text("Vibrant")
.foregroundStyle(.primary)
.environment(\.backgroundMaterial, .ultraThinMaterial)
+-----------------------------------------+
| Background (image, gradient, video) | Layer 0: Content
+-----------------------------------------+
| Ultra-thin material overlay | Layer 1: Ambient glass
+-----------------------------------------+
| Regular material cards | Layer 2: Content glass
+-----------------------------------------+
| Thick material controls | Layer 3: Interactive glass
+-----------------------------------------+
| Bar material navigation | Layer 4: Chrome glass
+-----------------------------------------+
Rule: Each layer up uses a thicker material. Never put thin material on top of thick.
struct ScrollGlassHeader: View {
@State private var scrollOffset: CGFloat = 0
var body: some View {
ZStack(alignment: .top) {
ScrollView {
// Content with offset tracking
GeometryReader { geo in
Color.clear.preference(
key: ScrollOffsetKey.self,
value: geo.frame(in: .named("scroll")).minY
)
}
.frame(height: 0)
// Actual content
LazyVStack { /* ... */ }
.padding(.top, 60)
}
.coordinateSpace(name: "scroll")
.onPreferenceChange(ScrollOffsetKey.self) { scrollOffset = $0 }
// Glass header that intensifies on scroll
Text("Title")
.font(.headline)
.frame(maxWidth: .infinity)
.padding()
.background(
scrollOffset < -10
? AnyShapeStyle(.regularMaterial)
: AnyShapeStyle(.clear)
)
.animation(.easeInOut(duration: 0.2), value: scrollOffset < -10)
}
}
}
.material modifiers.continuous corner style — Apple's superellipse, not circular.primary, .secondary, not raw colors.white.opacity(0.15-0.25) with 0.5pt strokedocumentation
Report reflect drain spend over a time window — tokens split by cached (cache_read), uncached writes (cache_creation), and io (input+output), with a $ estimate, grouped by day / outcome / model / transcript. Reads the drainer's cost log and surfaces outlier runs and cache-reuse health (the 41.5M-token failure mode = low cache reuse + high cache writes). Use to answer "what is reflection costing me" for the last day / week.
development
Show fleet status — every claude session running on the host, merged across ainb + claude-peers broker + background jobs. Use when you need to enumerate sessions before composing an action, see which sessions have a peer registered (broker-routable) vs tmux-only, check the `summary` of each session, or pipe the list into jq for filtering. Default output: text table. Pass --format json for LLM consumption.
testing
Ordered multi-step prompts to fleet targets, ack-gated between steps via JSONL assistant-turn-end detection. Use for cycles like disconnect→reconnect→verify, or any flow where step N+1 requires step N to have completed first. The skill BLOCKS until each target's transcript shows the next assistant turn finishing OR per-step timeout fires (default 300s).
development
Center control panel — enumerate every claude session that is blocked waiting on something: a user answer (AskUserQuestion fired), an API error retry, an idle assistant turn-end with no follow-up, or an explicit WAITING: marker. Returns rich JSON with signal kind + context per session. Use this when you've stepped away from the fleet and want one place to see everything that wants your attention and answer it.