| name | design-tokens |
| description | Material 3 design system foundation for Android apps. Use this skill for ANY
theming, color, spacing, shape, or elevation work — MaterialTheme, colorScheme,
ColorScheme roles, lightColorScheme, darkColorScheme, dynamicColorScheme,
primary/secondary/tertiary/surface/background tokens, onSurface, onBackground,
surfaceContainer, outline, spacing scale, 4dp grid, shape tokens, RoundedCornerShape,
Shapes, elevation, tonalElevation, shadowElevation, dark mode, isSystemInDarkTheme,
Material You, dynamic color, brand colors, semantic colors, Theme.kt, Color.kt.
Applies to ALL app categories: fintech, edtech, healthtech, ecommerce, social,
proptech, enterprise, productivity, entertainment, food, travel.
|
Design Tokens
The complete Material 3 design system foundation for Android. Every color,
spacing value, elevation, and shape in a production app must come from this
system. 22 rules covering all categories globally.
CRITICAL — Color System
Rule 1: Always Use Semantic Color Roles — Never Hardcode
Text(color = MaterialTheme.colorScheme.onSurface)
Text(color = MaterialTheme.colorScheme.onSurfaceVariant)
Box(Modifier.background(MaterialTheme.colorScheme.surfaceContainerLow))
Icon(tint = MaterialTheme.colorScheme.onSurfaceVariant)
Text(color = Color(0xFF212121))
Box(Modifier.background(Color.White))
The 6 color families — each has a surface + on-surface pair:
primary / onPrimary — brand color, key interactive elements
secondary / onSecondary — supporting brand color
tertiary / onTertiary — accent, contrasting highlight
error / onError — errors, destructive actions
surface / onSurface — cards, sheets (use onSurfaceVariant for secondary text)
background / onBackground — page background
Container variants — for filled backgrounds:
primaryContainer/onPrimaryContainer, secondaryContainer/onSecondaryContainer
Surface containers — layered depth (lowest→low→default→high→highest)
Always pair correctly: content on primaryContainer uses onPrimaryContainer, never onSurface.
Rule 2: Theme Structure — Complete Theme.kt Required
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(colorScheme = colorScheme, typography = AppTypography,
shapes = AppShapes, content = content)
}
Rule 3: Dark Mode — Shift Colors, Don't Invert
Dark mode is not if(dark) Color.White else Color.Black. Every semantic role
needs an independently chosen dark variant.
- Background:
#FAFAFA → #1C1B1F (dark gray, NOT black)
- Primary: dark green
#006C51 → light green #68DBA8 (shifts to maintain contrast)
- Text:
#212121 → #E6E1E5 (off-white, not pure white)
- Status bar: light icons when
darkTheme = true
SideEffect {
WindowCompat.getInsetsController(window, view)
.isAppearanceLightStatusBars = !darkTheme
}
Rule 4: Dynamic Color — Enable Correctly with Version Check
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
Rule 5: Semantic Colors for Status and Finance
object SemanticColors {
val SuccessLight = Color(0xFF2E7D32)
val SuccessContainer = Color(0xFFE8F5E9)
val WarningLight = Color(0xFFE65100)
val WarningContainer = Color(0xFFFFF3E0)
val InfoLight = Color(0xFF0277BD)
}
CRITICAL — Spacing
Rule 6: 4dp Grid — All Spacing from the Scale
object Spacing {
val xs = 4.dp
val sm = 8.dp
val md = 12.dp
val lg = 16.dp
val xl = 24.dp
val xxl = 32.dp
val xxxl = 48.dp
}
Category density guide:
- Fintech/Enterprise → dense (8-12dp vertical), maximize information
- Healthtech/Proptech → generous (16-24dp), open and calming
- Social feeds → compact (8-12dp between cards)
- Edtech → readable (16-24dp horizontal padding for text)
HIGH — Elevation
Rule 7: Tonal Elevation — Not Box Shadows
Surface(tonalElevation = 3.dp)
Card(elevation = CardDefaults.cardElevation(defaultElevation = 1.dp))
HIGH — Shapes
Rule 8: Shape Scale — Consistent Personality
val AppShapes = Shapes(
extraSmall = RoundedCornerShape(4.dp),
small = RoundedCornerShape(8.dp),
medium = RoundedCornerShape(12.dp),
large = RoundedCornerShape(16.dp),
extraLarge = RoundedCornerShape(28.dp),
)
ModalBottomSheet(shape = RoundedCornerShape(topStart = 28.dp, topEnd = 28.dp))
Category shape personalities:
- Fintech → conservative (4-12dp), pill shapes signal unreliability in banking
- Edtech → friendly (16-20dp for course cards), pill for tags
- Healthtech → soft (20-28dp for metric cards), circles for rings
- Enterprise → minimal (4-8dp), professional density
- Social → chat bubbles need asymmetric radius (large on 3 corners, small on sender corner)
HIGH — Brand Colors
Rule 9: Integrate Brand Without Breaking System
References
references/color-roles-reference.md — Full 30-role table, component→color mapping, surface container guide. Read when choosing which role to use for a new component.
rules/ — 8 individual rule files with complete examples and anti-patterns for all rules above.