Skill

Design flat UI components with modern minimalist aesthetics

Design-style skill for Flat Design: zero depth, sharp geometry, and high-contrast solid colors with no shadows or gradients.

Works with figma

Maintainer of this project? Claim this page to edit the listing.


79
Spark score
out of 100
Updated 26 days ago
Version 13.6.1

Add to Favorites

Why it matters

Create clean, minimalist user interface designs following flat design principles-eliminating skeuomorphic elements, using bold colors, simple typography, and two-dimensional illustrations to build modern, accessible UI components and layouts.

Outcomes

What it gets done

01

Generate flat design UI components with minimal shadows and gradients

02

Create color palettes using bold, vibrant flat design color schemes

03

Design two-dimensional icons and illustrations without depth effects

04

Build responsive layouts with clean typography and generous whitespace

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-flat-design | bash

Overview

Flat Design

A design-style skill for Flat Design - zero depth, sharp geometry, high-contrast solid colors, and no shadows or gradients - with matching Web CSS, SwiftUI, and Flutter implementations. Use it for clean utility apps, civic/government tools, or interfaces that want honest, purely 2D clarity over physical depth metaphors.

What it does

Flat Design is a design-style child skill ('digital surfaces should look digital - embrace the 2D plane'), part of the design-it family and not meant to be triggered directly. Three core principles: Zero Depth (absolutely no drop shadows, bevels, gradients, or 3D effects - everything sits on the same z-axis), Sharp & Simple Geometries (perfect circles, sharp rectangles, no complex organic shapes), and High Contrast Solid Colors (stark contrast between solid color blocks delineates space instead of shadow or elevation).

When to use - and when NOT to

Use it when the user's request matches this deliberately unadorned, purely 2D aesthetic - clean utility apps, government or civic tools, or any interface that wants clarity and honesty about being a flat digital surface rather than mimicking physical depth. As a design sub-style, it's selected by the parent design-it skill's routing rather than invoked on its own.

Inputs and outputs

Visual DNA pairs well with Industrial Chic or Modern Editorial palettes, avoiding gradients entirely, with strong highly legible sans-serifs (Roboto, Open Sans) kept medium-to-bold weight, and solid, monochromatic glyph-style icons without intricate detail - icon complexity is deliberately minimized so it reads clearly at any size without relying on gradients or shading to convey form. The web implementation relies entirely on background colors and borders for structure - cards use border-radius: 0 for sharp corners and a solid border instead of box-shadow, and hover states only change opacity or swap a solid color, never lift or add shadow.

.flat-card {
  border: 2px solid var(--primary-text);
  border-radius: 0;
  /* NO box-shadow */
}
.flat-btn:hover { opacity: 0.8; }

Integrations

SwiftUI enforces the same zero-depth discipline explicitly: never use .shadow() or .cornerRadius(), use .overlay(Rectangle().stroke(...)) for visible borders instead of shadows to delineate space, and hover/tap states only change opacity or swap a solid background color rather than lifting the element. Flutter mirrors this with a Container's BoxDecoration explicitly omitting borderRadius and boxShadow, relying purely on a solid border for structure - the same restraint enforced identically across all three platform implementations.

Who it's for

Designers and developers building a clean, honest, purely 2D interface - utility apps, civic/government tools, or any product that wants clarity over skeuomorphic or elevated visual metaphors - and needs the same zero-depth discipline enforced consistently across web and native platforms - the restraint is the point: every shadow or gradient left in place undermines the flatness the style is built around.

Source README

Flat Design

"Digital surfaces should look digital. Embrace the 2D plane."

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

  1. Zero Depth: Absolutely no drop shadows, bevels, gradients, or 3D effects. Everything sits on the same z-axis.
  2. Sharp & Simple Geometries: Perfect circles, sharp rectangles. No complex organic shapes.
  3. High Contrast Solid Colors: Rely on stark contrast between solid blocks of color to delineate space.

Visual DNA

  • Colors: Pairs well with Industrial Chic or Modern Editorial. Avoid gradients entirely.
  • Typography: Strong, highly legible sans-serifs (e.g., Roboto, Open Sans). Keep it medium to bold.
  • Icons: Solid, monochromatic, glyph-style icons without intricate details.

Web Implementation

  • Rely entirely on background colors and borders for structure.
  • CSS Example:
.flat-card {
  background-color: var(--secondary-base);
  border: 2px solid var(--primary-text);
  border-radius: 0; /* Sharp corners preferred */
  padding: 32px;
  /* NO box-shadow */
}
.flat-btn {
  background-color: var(--cta-highlight);
  color: #fff;
  border: none;
  padding: 16px 32px;
  font-weight: 700;
  text-transform: uppercase;
  transition: opacity 0.2s;
}
.flat-btn:hover {
  opacity: 0.8; /* Only change opacity or solid color on hover, no lifting */
}

App Implementation

SwiftUI

struct FlatCard: View {
    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Card Title")
                .font(.system(size: 18, weight: .bold))
            
            Text("Content without any depth effects.")
                .font(.system(size: 15))
                .foregroundColor(.secondary)
            
            Button(action: {}) {
                Text("ACTION")
                    .font(.system(size: 14, weight: .bold))
                    .foregroundColor(.white)
                    .padding(.horizontal, 24)
                    .padding(.vertical, 12)
                    .background(Color.blue)
                    // No cornerRadius — sharp edges
            }
        }
        .padding(24)
        .background(Color(.secondarySystemBackground))
        // NO .shadow() — ever
        // NO .cornerRadius() — sharp rectangles
        .overlay(
            Rectangle().stroke(Color.primary.opacity(0.2), lineWidth: 1)
        )
    }
}
  • Never use .shadow() or .cornerRadius(). Elements are flat rectangles.
  • Use .overlay(Rectangle().stroke(...)) for visible borders instead of shadows to delineate space.
  • Hover/tap states should only change opacity or swap a solid background color.

Flutter

class FlatCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        color: Colors.grey[100],
        border: Border.all(color: Colors.black26, width: 1),
        // borderRadius: NONE — sharp corners
        // boxShadow: NONE — zero depth
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('Card Title',
            style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16),
          const Text('Content without any depth effects.',
            style: TextStyle(fontSize: 15, color: Colors.black54)),
          const SizedBox(height: 16),
          ElevatedButton(
            onPressed: () {},
            style: ElevatedButton.styleFrom(
              elevation: 0,           // Critical: no shadow
              backgroundColor: Colors.blue,
              foregroundColor: Colors.white,
              shape: const RoundedRectangleBorder(
                borderRadius: BorderRadius.zero, // Sharp corners
              ),
              padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
            ),
            child: const Text('ACTION',
              style: TextStyle(fontWeight: FontWeight.bold, letterSpacing: 1)),
          ),
        ],
      ),
    );
  }
}
  • Override ThemeData globally to kill all elevation:
    ThemeData(
      cardTheme: const CardTheme(elevation: 0, shape: RoundedRectangleBorder()),
      appBarTheme: const AppBarTheme(elevation: 0),
      floatingActionButtonTheme: const FloatingActionButtonThemeData(elevation: 0),
    )
    
  • Use Container with BoxDecoration instead of Card widget to avoid default elevation.

React Native

const FlatCard = () => (
  <View style={{
    padding: 24,
    backgroundColor: '#F0F0F0',
    borderWidth: 1,
    borderColor: '#CCCCCC',
    // NO borderRadius
    // NO elevation or shadow properties
  }}>
    <Text style={{ fontSize: 18, fontWeight: '700', marginBottom: 16 }}>
      Card Title
    </Text>
    <Text style={{ fontSize: 15, color: '#666', marginBottom: 16 }}>
      Content without any depth effects.
    </Text>
    <TouchableOpacity
      style={{
        backgroundColor: '#2196F3',
        paddingHorizontal: 24,
        paddingVertical: 12,
        alignSelf: 'flex-start',
        // NO borderRadius, NO elevation
      }}
      activeOpacity={0.7}
    >
      <Text style={{ color: '#FFF', fontWeight: '700', letterSpacing: 1 }}>
        ACTION
      </Text>
    </TouchableOpacity>
  </View>
);
  • Explicitly set elevation: 0 and remove ALL shadow properties (shadowColor, shadowOffset, etc.).
  • If using React Native Paper, override the theme: const theme = { ...DefaultTheme, roundness: 0, }.
  • Tap feedback should change backgroundColor directly, not add glow or lift.

Jetpack Compose

@Composable
fun FlatCard() {
    Column(
        modifier = Modifier
            .background(Color(0xFFF0F0F0))
            .border(1.dp, Color(0xFFCCCCCC))
            .padding(24.dp)
    ) {
        Text("Card Title", fontSize = 18.sp, fontWeight = FontWeight.Bold)
        Spacer(Modifier.height(16.dp))
        Text("Content without any depth effects.",
            fontSize = 15.sp, color = Color(0xFF666666))
        Spacer(Modifier.height(16.dp))
        Button(
            onClick = {},
            shape = RectangleShape,  // Sharp corners
            elevation = ButtonDefaults.buttonElevation(
                defaultElevation = 0.dp,  // No shadow
                pressedElevation = 0.dp,
            ),
            colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3)),
            contentPadding = PaddingValues(horizontal = 24.dp, vertical = 12.dp),
        ) {
            Text("ACTION", fontWeight = FontWeight.Bold, letterSpacing = 1.sp)
        }
    }
}
  • Override MaterialTheme shapes: shapes = Shapes(small = RectangleShape, medium = RectangleShape, large = RectangleShape).
  • Set all elevation to 0.dp on Card, TopAppBar, and FloatingActionButton.
  • Use Modifier.border() instead of elevation to separate UI regions.

Do's and Don'ts

  • DO: Use solid, contrasting borders to separate overlapping elements.
  • DON'T: Use any transparency (rgba) or blur effects.

Limitations

  • This is a styling reference and does not replace environment-specific validation, accessibility testing, or expert review.
  • Ensure appropriate contrast ratios and responsive behaviors are verified separately.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.