| name | neumorphism |
| description | Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation. |
| category | Creative & Media |
| source | antigravity |
| tags | ["react","ai","design","image","rag"] |
| url | https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/design-it/neumorphism |
Neumorphism (Soft UI)
"Elements extruded from the background material itself, shaped by a singular, persistent light source."
When to Use
Use this sub-style when the user's request matches the aesthetic described above. This is a child reference of the design-it skill and is not meant to be triggered directly.
Core Principles
- Unified Surface Color: The background and the elements MUST share the exact same base color.
- Dual Shadows: Elements are shaped by two shadows: a light shadow (highlight) on the side facing the light source, and a dark shadow on the opposite side.
- No Borders: The shape is entirely defined by the shadows.
Visual DNA
- Colors: Works best with mid-tone neutrals. Desert Mirage, Earth-Grounded Elegance, or Sophisticated Neutral are perfect. Avoid pure white or pure black (shadows/highlights won't show).
- Typography: Soft, rounded sans-serifs (e.g.,
Nunito, Quicksand).
- Shapes: Pill shapes, rounded rectangles. Sharp corners break the illusion of extruded material.
Web Implementation
- The magic is entirely in
box-shadow manipulating light and dark variants of the base color.
- CSS Example:
:root {
--base-color: #E6E2DD;
--highlight: #ffffff;
--shadow: #c4c0bc;
}
body {
background-color: var(--base-color);
}
.neu-element {
background-color: var(--base-color);
border-radius: 20px;
box-shadow: 9px 9px 18px var(--shadow),
-9px -9px 18px var(--highlight);
padding: 32px;
}
.neu-pressed {
border-radius: 20px;
background: var(--base-color);
box-shadow: inset 9px 9px 18px var(--shadow),
inset -9px -9px 18px var(--highlight);
}
App Implementation
SwiftUI
struct NeuCard: View {
let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87)
var body: some View {
VStack(spacing: 24) {
Text("Neumorphic Card")
.font(.system(size: 20, weight: .semibold, design: .rounded))
Text("Extruded from the surface itself.")
.font(.system(size: 15, design: .rounded))
.foregroundColor(.secondary)
}
.padding(32)
.background(baseColor)
.cornerRadius(20)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8)
.shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8)
}
}
struct NeuButton: View {
@State private var isPressed = false
let baseColor = (red: , green: , blue: )
body: {
(action: {}) {
()
.font(.system(size: , weight: .semibold, design: .rounded))
.foregroundColor(.primary)
.padding(.horizontal, )
.padding(.vertical, )
}
.background(
{
isPressed {
(cornerRadius: )
.fill(baseColor)
.overlay(
(cornerRadius: )
.stroke(baseColor, lineWidth: )
.shadow(color: .black.opacity(), radius: , x: , y: )
.clipShape((cornerRadius: ))
)
.overlay(
(cornerRadius: )
.stroke(baseColor, lineWidth: )
.shadow(color: .white.opacity(), radius: , x: , y: )
.clipShape((cornerRadius: ))
)
} {
(cornerRadius: )
.fill(baseColor)
.shadow(color: .white.opacity(), radius: , x: , y: )
.shadow(color: .black.opacity(), radius: , x: , y: )
}
}
)
.buttonStyle(.plain)
.simultaneousGesture(
(minimumDistance: )
.onChanged { isPressed }
.onEnded { isPressed }
)
}
}
- The key trick: two
.shadow() modifiers — one white (top-left), one dark (bottom-right).
- Inner shadow (pressed state) requires a ZStack/overlay hack since SwiftUI doesn't have native
inset shadows. Clip stroked shapes to simulate.
- The view's background color MUST match its parent's background exactly.
Flutter
class NeuCard extend