Claude liquid glass
Skill zakisheriff/Claude-Liquid-Glass-Skill/claude-liquid-glass
iOS Liquid Glass Skill for Swift and React Native
npx -y skills add zakisheriff/Claude-Liquid-Glass-Skill --skill claude-liquid-glassAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 20 days oldThe repository was created 20 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Enforces native iOS 26+ Liquid Glass in all iOS UI — SwiftUI, UIKit, and React Native / Expo (expo-glass-effect + expo-router NativeTabs). Covers buttons, icons, navbars, tab bars, search bars, text inputs, sheets, cards, every interactive element. Two hard laws: (1) never hand-roll or custom-make Liquid Glass — always use the platform's native component (SwiftUI `.glassEffect`/ `.buttonStyle(.glass)`, or RN `GlassView`/`GlassContainer`/`NativeTabs`); never fake it with BlurView/ultraThinMaterial/opacity on iOS. (2) every touch fires a haptic. Use when writing, reviewing, or refactoring any iOS UI code (Swift or React Native/Expo), even if the user just says "make a button" or "add a nav bar" without mentioning liquid glass, haptics, or iOS 26. Trigger on SwiftUI views, buttons, NavigationStack/toolbar, TabView, .searchable, TextField, sheets; and on RN/Expo Pressable/TouchableOpacity, expo-router layouts, expo-glass-effect, expo-haptics, or any styling / press-feedback decision.
SKILL.md
14.4 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it
Claude Liquid Glass Skill
Applies to both native Apple UI (SwiftUI/UIKit) and React Native / Expo apps targeting iOS 26+.
The Two Hard Laws
- Never custom-make Liquid Glass. Always render it with the platform's own native component. Do not hand-roll glass from
BlurView,.ultraThinMaterial, blur+opacity+border stacks, or gradients on iOS. If a native glass primitive exists for the job, you MUST use it and nothing else. - Every single touch fires a haptic. Every button, tab, toggle, card tap, chip, list row, and gesture triggers native haptic feedback. A tappable element with no haptic is a bug. (See Mandatory Haptics.)
Core Rule
This app uses only the OS's native Liquid Glass material system (shipped iOS 26, WWDC 2025). Every interactive surface — buttons, icons, nav bars, tab bars, search bars, text inputs, sheets, cards, toolbars — must use the real system APIs below. Never substitute:
- ❌ Manual "glassmorphism":
.background(.ultraThinMaterial)/Color.white.opacity(0.1)+ custom border/shadow, or RN<BlurView>used as glass on iOS - ❌ Flat, opaque, hard-edged controls with no material
- ❌ RN/RN-style press feedback (
.opacity(pressed ? 0.5 : 1), manualscaleEffect/Animatedon tap) instead of native glass button behavior - ❌ Custom
RoundedRectangle/Viewbackgrounds that don't match system concentricity - ❌ Reinventing blur/refraction by stacking
.blur()+.opacity()layers
If you catch yourself about to write any of the above, stop and reach for the native glass primitive for that platform instead.
Part A — Native SwiftUI / UIKit (iOS 26+)
Golden Rules (from Apple's HIG)
- Glass belongs to the navigation/control layer, floating above content — not the content itself. Don't apply glass to body text, list rows, or backgrounds behind bars.
- Recompiling with Xcode 26 already gives you most of this for free — standard
NavigationStack,.toolbar,TabView,.searchable, and sheets adopt Liquid Glass automatically. Only reach for manual.glassEffect()on custom controls. - Group related glass elements in a
GlassEffectContainerso they blend/morph as one shape instead of separate floating blobs. - Tint with meaning only — reserve tint for real semantic state (destructive, primary, selection), not decoration.
- Test with Reduce Transparency, Increase Contrast, and Reduce Motion on. If it breaks, it's decoration, not Liquid Glass.
Component → API Map (SwiftUI)
| Component | Native API | Notes |
|---|---|---|
| Standard button | .buttonStyle(.glass) | default for secondary/tertiary actions |
| Primary/CTA button | .buttonStyle(.glassProminent) | one per screen, ideally |
| Circular icon button | .buttonStyle(.glass or .glassProminent) + .buttonBorderShape(.circle) | preferred icon-button idiom — not a fixed frame + raw glassEffect |
| Custom shaped control | .glassEffect(.regular, in: shape) | e.g. .rect(cornerRadius:), .circle, Capsule() |
| Interactive glass (custom tappable) | .glassEffect(.regular.interactive()) | for custom surfaces that respond to touch |
| Tinted selectable glass (pills, segmented, status chips) | .glassEffect(.regular.tint(color).interactive(), in: shape) | tint the glass value itself, chained — different from a Button's .tint() modifier |
| Grouped floating controls (icon clusters, FABs) | GlassEffectContainer(spacing:) { ... } | blends + enables morphing |
| Morph between states | .glassEffectID(_:in:) inside a container + matched transition | smooth shape transform |
| Nav bar / toolbar | NavigationStack + .toolbar (automatic) | don't hand-roll a bar |
| Tab bar | TabView (automatic) | don't hand-roll a bar |
| Search bar | .searchable(text:) (preferred) | see note below |
| Text input | System TextField/SecureField, wrapped in .glassEffect(.regular, in:) capsule/rect when custom-framed | avoid flat bordered fields |
| Sheet / popover | System .sheet/.popover (automatic) | glass chrome applied by system |
Search bar nuance
Prefer .searchable(text:) — it adopts Liquid Glass automatically. A custom TextField wrapped in a real .glassEffect(.regular, in: RoundedRectangle(...)) is acceptable when you need inline placement, a controlled placeholder color, or custom trailing controls (this is the pattern in the Halal-It reference app's search + sign-in fields). What is never acceptable is a search field faked with .ultraThinMaterial/opacity instead of .glassEffect.
Quick Snippets (SwiftUI)
Tinted, selectable, interactive glass pill (the workhorse pattern for chips/segments):
Text(label)
.padding(.horizontal, 14).padding(.vertical, 8)
.glassEffect(.regular.tint(isOn ? Brand.greenSoft : .clear).interactive(), in: Capsule())
Circular icon button:
Button { HapticManager.shared.trigger(.lightImpact); action() } label: {
Image(systemName: "location.fill")
}
.buttonStyle(.glassProminent)
.buttonBorderShape(.circle)
.tint(Brand.green)
Grouped icon cluster (morphing):
GlassEffectContainer(spacing: 24) {
HStack(spacing: 24) {
Image(systemName: "scribble.variable").frame(width: 72, height: 72).glassEffect()
Image(systemName: "eraser.fill").frame(width: 72, height: 72).glassEffect()
}
}
Primary / secondary buttons:
Button("Confirm") { }.buttonStyle(.glassProminent)
Button("Cancel", role: .cancel) { }.buttonStyle(.glass)
Fallback / Availability (SwiftUI)
Only pre-iOS-26 targets get an .ultraThinMaterial fallback, and only inside an #available(iOS 26, *) branch. If the deployment target is iOS 26+, delete the fallback — keep no legacy styling.
Part B — React Native / Expo (iOS 26+)
React Native reaches the same native Liquid Glass, through native modules. You still never custom-make glass. On iOS you use the real native views; a custom BlurView dock is allowed only as a non-iOS (Android/Web) fallback, never as the iOS path.
Libraries (the only sanctioned glass on iOS)
| Need | Library / API | Notes |
|---|---|---|
| Tab bar / nav | NativeTabs from expo-router/unstable-native-tabs | real native Liquid Glass tab bar. blurEffect="systemChromeMaterial", SF Symbol icons via icon: { sf: '...' }, native haptics + scroll-to-top for free |
| Any custom glass surface | GlassView from expo-glass-effect | `glassEffectStyle="regular" |
| Grouped/merging glass | GlassContainer from expo-glass-effect | RN equivalent of GlassEffectContainer; pass spacing |
| Availability gate | isLiquidGlassAvailable() + isGlassEffectAPIAvailable() from expo-glass-effect | true only on iOS 26+ capable devices |
| SF Symbols | expo-symbols (SymbolView) | monochrome system symbols, not flat icon assets |
| Haptics | expo-haptics | see Mandatory Haptics |
Do not use expo-blur <BlurView> as glass on iOS. It is a fallback for platforms without native Liquid Glass only.
The required RN patterns (as used in the Akhi-AI mobile + Medhive Frontend reference apps)
1. Platform-split layouts — native on iOS, custom fallback elsewhere. Use Expo's platform file extensions so iOS gets the real native tab bar and other platforms get a custom dock:
app/(tabs)/_layout.ios.tsx → NativeTabs (native Liquid Glass) ✅ iOS
app/(tabs)/_layout.tsx → custom GlassmorphicTabBar (BlurView) — Android/Web ONLY
// _layout.ios.tsx
import { NativeTabs } from 'expo-router/unstable-native-tabs';
<NativeTabs blurEffect="systemChromeMaterial" tintColor={brand}>
<NativeTabs.Trigger name="history"
options={{ title: t('tabs.history'), icon: { sf: 'clock' }, selectedIcon: { sf: 'clock.fill' } }} />
</NativeTabs>
2. Wrap GlassView once, gate on availability + Reduce Transparency, fall back to a plain View. Never render fake glass when native glass is unavailable — degrade to a normal opaque view:
// LiquidGlassSurface.tsx (thin wrapper over expo-glass-effect)
const liquidGlassEnabled = useLiquidGlassEnabled(); // canUseLiquidGlass() && !reduceTransparency
if (!liquidGlassEnabled) return <View style={style}>{children}</View>;
return (
<GlassView glassEffectStyle={glassStyle} isInteractive={interactive} tintColor={tintColor} style={style}>
{children}
</GlassView>
);
// availability + accessibility gate
export function canUseLiquidGlass() {
if (Platform.OS !== 'ios') return false;
try { return isLiquidGlassAvailable() && isGlassEffectAPIAvailable(); } catch { return false; }
}
// useLiquidGlassEnabled() additionally subscribes to reduceTransparencyChanged and returns false when on
3. Group with GlassContainer (RN's GlassEffectContainer):
<GlassContainer spacing={14} style={style}>{children}</GlassContainer>
4. glassStyle/glassEffectStyle: "regular" for cards/panels/modals, "clear" for control-like chrome (buttons, pills, segmented controls). Pass tintColor (rgba) only for semantic state/selection, matching the SwiftUI tint rule.
RN mapping cheat-sheet (SwiftUI → RN)
| SwiftUI | React Native / Expo |
|---|---|
.glassEffect(.regular, in:) | <GlassView glassEffectStyle="regular"> |
.glassEffect(.clear, ...) | <GlassView glassEffectStyle="clear"> |
.glassEffect(.regular.interactive()) | <GlassView isInteractive> |
.glassEffect(.regular.tint(c)....) | <GlassView tintColor="rgba(...)"> |
GlassEffectContainer(spacing:) | <GlassContainer spacing={n}> |
TabView (auto glass) | NativeTabs (expo-router/unstable-native-tabs) |
#available(iOS 26,*) fallback | useLiquidGlassEnabled() → plain <View> |
Mandatory Haptics
Every touch must produce a haptic. This is non-negotiable and applies to both platforms. Buttons, tabs, chips, toggles, card taps, list rows, long-press, swipe actions, pull-to-refresh commit, sheet dismiss — all of them.
Intensity guide (both platforms):
- Light impact — most taps, secondary buttons, chips, list rows
- Medium impact — primary/CTA actions, tab switches, meaningful toggles
- Heavy / rigid — significant or destructive confirmations
- Selection — picker/segment scrubbing, incremental selection changes
- Success / warning / error notification — operation results (save done, validation fail)
React Native / Expo
Use expo-haptics through a shared useHaptics() hook and call it in every onPress/gesture handler:
// hooks/useHaptics.ts
import * as Haptics from 'expo-haptics';
export const useHaptics = () => ({
light: () => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light),
medium: () => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium),
heavy: () => Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy),
selection: () => Haptics.selectionAsync(),
success: () => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success),
warning: () => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning),
error: () => Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error),
});
const { light, success } = useHaptics();
<Pressable onPress={() => { light(); onPress(); }} />
// notifications on outcomes: success() after a completed action, error() on failure
NativeTabsfires native tab haptics automatically — don't double-fire on tab changes.
SwiftUI / UIKit
Prefer a central manager + a .hapticTap() view modifier (as in the Halal-It reference app), or SwiftUI's .sensoryFeedback:
Button { HapticManager.shared.trigger(.lightImpact); action() } label: { ... }
// or attach to any tappable view:
someCard.hapticTap(.selection)
// or native modifier:
.sensoryFeedback(.impact(weight: .light), trigger: isPressed)
Review Checklist (auditing existing code)
Liquid Glass:
- Any
.ultraThinMaterial/opacity "glass" on iOS (SwiftUI or RN<BlurView>) outside a documented non-iOS/pre-26 fallback → replace with the native glass primitive - Any hand-rolled nav/tab/search bar →
NavigationStack/TabView/.searchable(SwiftUI) orNativeTabs(RN) - RN app rendering glass on iOS via anything other than
expo-glass-effect/NativeTabs→ replace - RN glass not gated by availability + Reduce Transparency (no plain-
Viewfallback) → add the gate - Manual
scaleEffect/opacity/Animatedpress hack instead of native glass button behavior → replace - Adjacent glass elements not grouped →
GlassEffectContainer/GlassContainer - Circular icon buttons (SwiftUI) not using
.buttonBorderShape(.circle)→ fix - Decorative-only tint on glass → remove or justify semantically
Haptics:
- Any tappable element with no haptic → add one (light default; medium for primary; selection for scrubbing; success/error for outcomes)
- Haptics scattered inline instead of via a shared
useHaptics()/HapticManager→ centralize - Double-firing haptics on
NativeTabstab changes (native already fires) → remove the manual one
Accessibility:
- Tested with Reduce Transparency / Increase Contrast / Reduce Motion → still legible; RN falls back to plain views
Resources
references/liquid-glass-reference.md— deeper snippets (concentricity, custom shapes, glassEffectID morphing, sheets, toolbar nuance, point-release quirks) and links to Apple's WWDC 2025 sessions (219, 323) + HIG "Materials".
What ships with it: 1 file
7.1 KB alongside SKILL.md
references/
Gives 0 of the 12 instructions most context ai engineering skills give in ~3.4k tokens
Counted across 1,193 of the 1,976 authors here whose files we hold, read 2026-08-07
- Dispatch a fresh implementer subagent per taskin 48 of 1193, across 19 files
- Dispatch a final code reviewer after all tasksin 33 of 1193, across 8 files
- Provide full task text to the subagentin 30 of 1193, across 9 files
- Review spec compliance before code qualityin 27 of 1193, across 10 files
- Make the hook script executablein 26 of 1193, across 8 files
- Re-snapshot after navigation or DOM changesin 25 of 1193, across 19 files
- Read files before editing themin 22 of 1193, across 11 files
- Answer subagent questions before proceedingin 22 of 1193, across 7 files
- Mark task complete in TodoWrite after approvalin 22 of 1193, across 6 files
- Merge hook into existing settingsin 21 of 1193, across 3 files
- Ask if installation is global or projectin 20 of 1193, across 2 files
- Copy the hook script to target locationin 20 of 1193, across 2 files
Said here and by no other author read
- use native platform components for liquid glass
- fire a haptic on every single touch
- use SwiftUI glassEffect modifier for custom controls
- use GlassView and GlassContainer in React Native
- use NativeTabs for native React Native tab bars
- group related glass elements in a container
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.