bundled-skills/design-it/card-based-design/SKILL.md
Web and App implementation guide for Card-Based Design. Trigger when user wants information cards, Pinterest-style layouts, and bite-sized content containers.
npx skillsauth add FrancoStino/opencode-skills-antigravity card-based-designInstall 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.
"Bite-sized consumption. Encapsulating discrete pieces of information into distinct visual containers."
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.
border-radius: 8px and a medium drop shadow.auto-fit or a Masonry layout.body {
background-color: #f0f2f5; /* Standard app background */
padding: 40px;
}
.card-grid {
display: grid;
/* Auto-responsive magic */
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
}
.card {
background: #ffffff;
border-radius: 12px;
overflow: hidden; /* Keep images inside the rounded corners */
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
display: flex;
flex-direction: column;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
border-bottom: 1px solid #eee;
}
.card-content {
padding: 20px;
flex-grow: 1; /* Pushes footer to the bottom */
}
.card-footer {
padding: 16px 20px;
border-top: 1px solid #eee;
display: flex;
justify-content: space-between;
}
struct ContentCard: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
// Image Area
Rectangle()
.fill(Color.gray.opacity(0.2))
.frame(height: 160)
// Content Area
VStack(alignment: .leading, spacing: 8) {
Text("Card Title")
.font(.headline)
Text("A brief description of the content inside this discrete card container.")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(2)
}
.padding(16)
}
.background(Color.white)
.cornerRadius(12)
// Clean, subtle drop shadow
.shadow(color: Color.black.opacity(0.08), radius: 12, x: 0, y: 4)
}
}
// In your view:
// LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 16)]) { ... }
VStack inside a background with .cornerRadius and .shadow is the standard.LazyVGrid with .adaptive(minimum: 160) to automatically create a multi-column card grid that flows perfectly on iPad or iPhone.class ContentCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
elevation: 4, // Handles shadow natively
shadowColor: Colors.black.withOpacity(0.4),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
clipBehavior: Clip.antiAlias, // Critical: stops images from bleeding over corners
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
// Image Area
Container(
height: 160,
color: Colors.grey[300],
width: double.infinity,
),
// Content Area
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text('Card Title', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
SizedBox(height: 8),
Text(
'A brief description of the content inside this discrete card container.',
style: TextStyle(color: Colors.black54),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
);
}
}
// In your view: Use GridView.builder for the layout
Card widget does almost all the heavy lifting.clipBehavior: Clip.antiAlias on the Card, otherwise the top corners of your images will peek outside the border radius.const ContentCard = () => {
return (
<View style={styles.card}>
<View style={styles.imageArea} />
<View style={styles.contentArea}>
<Text style={styles.title}>Card Title</Text>
<Text style={styles.description} numberOfLines={2}>
A brief description of the content inside this discrete card container.
</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
card: {
backgroundColor: '#FFF',
borderRadius: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.08,
shadowRadius: 12,
elevation: 4,
margin: 8,
overflow: 'hidden', // Keeps image inside borders
},
imageArea: {
height: 160,
backgroundColor: '#E0E0E0',
},
contentArea: {
padding: 16,
},
title: {
fontSize: 18,
fontWeight: '600',
marginBottom: 8,
},
description: {
color: '#666',
}
});
// In your view: <FlatList numColumns={2} data={data} renderItem={...} />
borderRadius and overflow: 'hidden'.elevation: 4 provides the drop shadow on Android, while the shadow* props handle iOS.react-native-masonry-list, as FlatList cannot do varying row heights in columns.@Composable
fun ContentCard() {
// ElevatedCard provides the shadow and shape natively
ElevatedCard(
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 4.dp),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.elevatedCardColors(containerColor = Color.White),
modifier = Modifier.fillMaxWidth().padding(8.dp)
) {
Column {
// Image Area
Box(
modifier = Modifier
.fillMaxWidth()
.height(160.dp)
.background(Color.LightGray)
)
// Content Area
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Card Title",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Spacer(Modifier.height(8.dp))
Text(
text = "A brief description of the content inside this discrete card container.",
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray,
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
}
}
}
// In your view: LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 160.dp)) { ... }
ElevatedCard is the perfect Material 3 component for this. It handles clipping and shadows automatically.GridCells.Adaptive(minSize = 160.dp) in a LazyVerticalGrid to achieve an auto-flowing grid identical to CSS Grid auto-fit.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).