bundled-skills/design-it/neumorphism/SKILL.md
Web and App implementation guide for Neumorphism (Soft UI). Trigger when user wants soft shadows, extruded appearance, and light source simulation.
npx skillsauth add FrancoStino/opencode-skills-antigravity neumorphismInstall 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.
"Elements extruded from the background material itself, shaped by a singular, persistent light source."
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.
Nunito, Quicksand).box-shadow manipulating light and dark variants of the base color.:root {
--base-color: #E6E2DD; /* From Sophisticated Neutral */
--highlight: #ffffff;
--shadow: #c4c0bc;
}
body {
background-color: var(--base-color);
}
.neu-element {
background-color: var(--base-color);
border-radius: 20px;
/* Top-left highlight, Bottom-right shadow */
box-shadow: 9px 9px 18px var(--shadow),
-9px -9px 18px var(--highlight);
padding: 32px;
}
.neu-pressed {
/* Inset shadows for pressed/active state */
border-radius: 20px;
background: var(--base-color);
box-shadow: inset 9px 9px 18px var(--shadow),
inset -9px -9px 18px var(--highlight);
}
struct NeuCard: View {
let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87) // #E6E2DD
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)
// Light shadow (top-left)
.shadow(color: Color.white.opacity(0.7), radius: 10, x: -8, y: -8)
// Dark shadow (bottom-right)
.shadow(color: Color.black.opacity(0.15), radius: 10, x: 8, y: 8)
}
}
// Pressed / inset neumorphic button
struct NeuButton: View {
@State private var isPressed = false
let baseColor = Color(red: 0.90, green: 0.89, blue: 0.87)
var body: some View {
Button(action: {}) {
Text("Press Me")
.font(.system(size: 16, weight: .semibold, design: .rounded))
.foregroundColor(.primary)
.padding(.horizontal, 32)
.padding(.vertical, 16)
}
.background(
Group {
if isPressed {
// Inset effect using inner shadow (ZStack trick)
RoundedRectangle(cornerRadius: 16)
.fill(baseColor)
.overlay(
RoundedRectangle(cornerRadius: 16)
.stroke(baseColor, lineWidth: 4)
.shadow(color: Color.black.opacity(0.2), radius: 4, x: 4, y: 4)
.clipShape(RoundedRectangle(cornerRadius: 16))
)
.overlay(
RoundedRectangle(cornerRadius: 16)
.stroke(baseColor, lineWidth: 4)
.shadow(color: Color.white.opacity(0.7), radius: 4, x: -4, y: -4)
.clipShape(RoundedRectangle(cornerRadius: 16))
)
} else {
RoundedRectangle(cornerRadius: 16)
.fill(baseColor)
.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)
}
}
)
.buttonStyle(.plain)
.simultaneousGesture(
DragGesture(minimumDistance: 0)
.onChanged { _ in isPressed = true }
.onEnded { _ in isPressed = false }
)
}
}
.shadow() modifiers — one white (top-left), one dark (bottom-right).inset shadows. Clip stroked shapes to simulate.class NeuCard extends StatelessWidget {
final Color baseColor = const Color(0xFFE6E2DD);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: baseColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
// Dark shadow (bottom-right)
BoxShadow(
color: Colors.black.withOpacity(0.15),
offset: const Offset(8, 8),
blurRadius: 16,
),
// Light shadow (top-left)
BoxShadow(
color: Colors.white.withOpacity(0.7),
offset: const Offset(-8, -8),
blurRadius: 16,
),
],
),
child: Column(
children: [
const Text('Neumorphic Card',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600)),
const SizedBox(height: 16),
Text('Extruded from the surface itself.',
style: TextStyle(fontSize: 15, color: Colors.black54)),
],
),
);
}
}
BoxShadow.flutter_inset_box_shadow package OR fake it with a layered Stack: place a Container with a dark gradient overlay on top and a light gradient below.Scaffold background to the SAME baseColor so elements look extruded.const NeuCard = () => (
<View style={{
padding: 32,
backgroundColor: '#E6E2DD',
borderRadius: 20,
// Light shadow (top-left) — iOS only supports one shadow
shadowColor: '#FFFFFF',
shadowOffset: { width: -8, height: -8 },
shadowOpacity: 0.7,
shadowRadius: 10,
// Android — use elevation for basic shadow
elevation: 8,
}}>
<Text style={{ fontSize: 20, fontWeight: '600' }}>Neumorphic Card</Text>
<Text style={{ fontSize: 15, color: '#888', marginTop: 16 }}>
Extruded from the surface itself.
</Text>
</View>
);
react-native-shadow-2 or react-native-neomorph-shadows which provide multi-shadow support.Views — the outer one has the dark shadow, the inner one has the light shadow.@Composable
fun NeuCard() {
val baseColor = Color(0xFFE6E2DD)
Box(
modifier = Modifier
.padding(24.dp)
.shadow(
elevation = 8.dp,
shape = RoundedCornerShape(20.dp),
ambientColor = Color.Black.copy(alpha = 0.15f),
spotColor = Color.Black.copy(alpha = 0.15f),
)
.background(baseColor, RoundedCornerShape(20.dp))
.padding(32.dp)
) {
Column {
Text("Neumorphic Card",
fontSize = 20.sp, fontWeight = FontWeight.SemiBold)
Spacer(Modifier.height(16.dp))
Text("Extruded from the surface itself.",
fontSize = 15.sp, color = Color(0xFF888888))
}
}
}
Modifier.shadow() only supports a single directional shadow.Modifier.drawBehind { } with drawIntoCanvas to paint two separate shadow paths (one light, one dark).neumorphic-compose library provides a pre-built Modifier.neumorphic() that handles both shadows.Scaffold background to the same baseColor — this is non-negotiable.data-ai
Snapshot a site's SEO state and detect ranking, indexation, metadata, canonical, robots, schema, and on-page regressions over time.
development
Coordinate focused subagents on substantial work, keep their ownership non-overlapping, and integrate verified results. Use for large-scope Codex tasks; keep trivial work with the coordinator.
data-ai
Use when an owner asks to find a cofounder or project partner. Assess only that agent's own owner and rank only approved profiles other agents posted for their own owners.
devops
Install, configure, verify, repair, update, and uninstall Hyprland on Fedora Linux with GPU-aware detection (NVIDIA/AMD/Intel).