bundled-skills/design-it/bento-ui/SKILL.md
Web and App implementation guide for Bento UI. Trigger when user wants modular grid cards, Apple-like dashboard style, or sections arranged like a bento box.
npx skillsauth add FrancoStino/opencode-skills-antigravity bento-uiInstall 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.
"Everything in its right place. A highly structured, modular grid of distinct compartments."
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.
SF Pro, Inter). Headlines are usually bold and placed at the top-left or bottom-left of each compartment..bento-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 200px;
gap: 24px;
padding: 24px;
background-color: var(--bg-primary); /* Slightly darker than cards */
}
.bento-card {
background-color: #fff;
border-radius: 32px; /* Very large border radius */
padding: 32px;
box-shadow: 0 4px 24px rgba(0,0,0,0.04);
/* Optional: subtle 1px border for crispness */
border: 1px solid rgba(0,0,0,0.05);
display: flex;
flex-direction: column;
justify-content: space-between;
}
/* Creating spans for different bento sizes */
.bento-span-2 { grid-column: span 2; }
.bento-span-2-row { grid-row: span 2; }
.bento-large { grid-column: span 2; grid-row: span 2; }
struct BentoGrid: View {
let columns = [
GridItem(.flexible(), spacing: 16),
GridItem(.flexible(), spacing: 16)
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 16) {
// 2x1 Span (Full width)
BentoCard(title: "Hero", color: .blue)
.frame(height: 180)
// 1x1 Spans
BentoCard(title: "Stats", color: .green)
.frame(height: 180)
BentoCard(title: "Graph", color: .purple)
.frame(height: 180)
// 1x2 Span (Tall)
BentoCard(title: "Activity", color: .orange)
.frame(height: 376) // (180 * 2) + 16 spacing
// 1x1 Spans next to the tall one
VStack(spacing: 16) {
BentoCard(title: "A", color: .pink).frame(height: 180)
BentoCard(title: "B", color: .cyan).frame(height: 180)
}
}
.padding(16)
}
.background(Color(.systemGroupedBackground))
}
}
struct BentoCard: View {
let title: String
let color: Color
var body: some View {
RoundedRectangle(cornerRadius: 24)
.fill(Color(.secondarySystemGroupedBackground))
.overlay(
Text(title).font(.headline).foregroundColor(color),
alignment: .topLeading
)
.padding(16)
// Soft bento shadow
.shadow(color: .black.opacity(0.04), radius: 12, x: 0, y: 4)
}
}
LazyVGrid for uniform grids.VStack and HStack inside the grid cells to fake the spans.cornerRadius (usually 24-32pt) and spacing (usually 16pt).import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
class BentoScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: StaggeredGrid.count(
crossAxisCount: 4, // 4 columns total
mainAxisSpacing: 16,
crossAxisSpacing: 16,
children: const [
// 2x1 (Full width in a 2-col layout, spans 4)
StaggeredGridTile.count(
crossAxisCellCount: 4,
mainAxisCellCount: 2,
child: BentoCard(title: 'Hero'),
),
// 1x1
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 2,
child: BentoCard(title: 'Stats'),
),
// 1x1
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 2,
child: BentoCard(title: 'Graph'),
),
// 1x2 (Tall)
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 4,
child: BentoCard(title: 'Activity'),
),
],
),
),
);
}
}
class BentoCard extends StatelessWidget {
final String title;
const BentoCard({required this.title});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(24),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
alignment: Alignment.topLeft,
child: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
);
}
}
flutter_staggered_grid_view package is practically mandatory for complex Bento grids in Flutter.StaggeredGridTile.count to explicitly declare the crossAxis and mainAxis span of each compartment.const BentoScreen = () => {
return (
<ScrollView
style={{ flex: 1, backgroundColor: '#F2F2F7' }}
contentContainerStyle={{ padding: 16 }}
>
{/* 2x1 Span */}
<View style={[styles.bentoCard, { height: 180, marginBottom: 16 }]}>
<Text style={styles.title}>Hero</Text>
</View>
<View style={{ flexDirection: 'row', gap: 16, marginBottom: 16 }}>
{/* 1x1 Spans */}
<View style={[styles.bentoCard, { flex: 1, height: 180 }]}>
<Text style={styles.title}>Stats</Text>
</View>
<View style={[styles.bentoCard, { flex: 1, height: 180 }]}>
<Text style={styles.title}>Graph</Text>
</View>
</View>
<View style={{ flexDirection: 'row', gap: 16 }}>
{/* 1x2 Span (Tall) */}
<View style={[styles.bentoCard, { flex: 1, height: 376 }]}>
<Text style={styles.title}>Activity</Text>
</View>
<View style={{ flex: 1, gap: 16 }}>
{/* Stacked 1x1s */}
<View style={[styles.bentoCard, { height: 180 }]}>
<Text style={styles.title}>A</Text>
</View>
<View style={[styles.bentoCard, { height: 180 }]}>
<Text style={styles.title}>B</Text>
</View>
</View>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
bentoCard: {
backgroundColor: '#FFFFFF',
borderRadius: 24,
padding: 24,
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.04,
shadowRadius: 12,
elevation: 2,
},
title: {
fontWeight: '700',
fontSize: 18,
}
});
flexDirection: 'row' and vertical stacks.gap property in React Native flexbox makes this significantly easier than using margins.@Composable
fun BentoGrid() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF2F2F7))
.verticalScroll(rememberScrollState())
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Full width
BentoCard(title = "Hero", modifier = Modifier.fillMaxWidth().height(180.dp))
// Two columns
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
BentoCard(title = "Stats", modifier = Modifier.weight(1f).height(180.dp))
BentoCard(title = "Graph", modifier = Modifier.weight(1f).height(180.dp))
}
// Complex span: 1x2 left, two 1x1s right
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
BentoCard(title = "Activity", modifier = Modifier.weight(1f).height(376.dp))
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
BentoCard(title = "A", modifier = Modifier.fillMaxWidth().height(180.dp))
BentoCard(title = "B", modifier = Modifier.fillMaxWidth().height(180.dp))
}
}
}
}
@Composable
fun BentoCard(title: String, modifier: Modifier = Modifier) {
Card(
modifier = modifier,
shape = RoundedCornerShape(24.dp),
colors = CardDefaults.cardColors(containerColor = Color.White),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Text(title, fontWeight = FontWeight.Bold, modifier = Modifier.padding(24.dp))
}
}
LazyVerticalGrid exists, for highly specific irregular bento layouts, manually building rows and columns with weight(1f) is often much more reliable.Arrangement.spacedBy(16.dp) on both Columns and Rows to ensure mathematically perfect gutters.tools
Authorized security assessment of LLM applications and AI agents: prompt injection, tool abuse, RAG exposure, memory poisoning, system-prompt extraction, and agent-compliance engineering per OWASP LLM/ASI Top 10.
development
Builds two parameterized UI modes—流光溢彩白 (iridescent white) and 五彩斑斓黑 (colorful black)—with OKLCH, WebGL/CSS fallback, vision gating, screenshot QA, and total/per-color intensity reports. Use when a UI request names either mode or needs measured color parameters.
tools
Delegate coding tasks to the Kimi Code CLI (`kimi`) only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.
development
Front-end JavaScript reverse engineering: locate signature chains, analyze encrypted request parameters, sample runtime behavior, and reproduce logic locally in Node for evidence-based output.