Your comprehensive guide to creating stunning, modern, and truly premium Android apps using Material Design 3 Expressive.
Last Updated: January 19, 2026
Author: Compiled for IvorMusic Project
- Introduction - What Makes M3 Expressive Special
- The 7 Emphasis Tactics
- Highlight Features
- Variable Fonts & Emphasized Typography
- 35 New Shapes + Shape Morphing
- MaterialShapes Class (35 Predefined Shapes!)
- Physics-Based Motion System
- New Components (14 Total!)
- Dynamic Color Evolution
- Design Tokens
- Material Symbols Icons
- Accessibility Guidelines
- Additional Components
- Micro-Interactions That Delight
- Design Process & Tips from Designers
- Case Studies & Inspiration
- Implementation Guide
- Premium Design Checklist
- Resources & Links
Material 3 Expressive isn't just an update—it's a philosophy shift. Released in May 2025 alongside Android 16, it represents Google's vision for design through the 2030s.
"Make products more engaging, desirable, and user-friendly by fostering an emotional connection."
Google's research found that expressive designs:
- Help users find key UI elements up to 4x faster
- Are universally preferred by users across demographics
- Improve perceived usability and satisfaction
- Create stronger emotional connections with products
Material 3 Expressive is about making interfaces feel:
- Alive - Through physics-based motion
- Personal - Through dynamic theming
- Delightful - Through micro-interactions
- Clear - Through visual hierarchy
These are the official design tactics from Google for creating expressive interfaces:
Go beyond uniform shapes! Mix classic and abstract forms, combine round and square corner radii to create visual tension or cohesion.
// Mix different corner radii for visual interest
val heroCard = RoundedCornerShape(32.dp) // Large, prominent
val actionButton = RoundedCornerShape(16.dp) // Medium, interactive
val infoChip = RoundedCornerShape(8.dp) // Small, subtleUse the full spectrum of Material's color roles. Mix primary, secondary, and tertiary colors strategically.
| Role | Usage | Emphasis Level |
|---|---|---|
| Primary | FABs, key CTAs | Maximum |
| Secondary | Filter chips, toggles | Medium |
| Tertiary | Badges, accents | Complementary |
| Surface Variants | Cards, depth | Layering |
Use emphasized text styles—heavier weights, larger sizes, distinct colors, and adjusted spacing.
Organize content into logical groupings. Use cards and surfaces to:
- Create clarity
- Draw attention to specific elements
- Make key actions stand out
Replace mechanical animations with physics-based motion using springs.
Use the new, more configurable components with enhanced shape and motion options.
Layer multiple tactics together for key moments—like when a user completes an action or discovers a new feature.
Material 3 Expressive introduces visually emphasized typography through new type styles:
| Style | Standard | → | Emphasized |
|---|---|---|---|
| Display | displayLarge |
→ | displayLargeEmphasized |
| Headline | headlineMedium |
→ | headlineMediumEmphasized |
| Title | titleLarge |
→ | titleLargeEmphasized |
| Body | bodyLarge |
→ | bodyLargeEmphasized |
| Label | labelMedium |
→ | labelMediumEmphasized |
- Heavier weights (Black instead of Bold)
- Larger optical sizes
- Tighter letter spacing for headlines
- More generous line height for body text
Roboto Flex and similar variable fonts allow:
- Dynamic weight adjustment based on context
- Size-specific optical adjustments
- Device-aware legibility improvements
- Single font file = multiple weights (better performance!)
// Using emphasized typography
Text(
text = "Your Library",
style = MaterialTheme.typography.headlineLarge.copy(
fontWeight = FontWeight.Black,
letterSpacing = (-0.5).sp
)
)
// For body text - generous, readable
Text(
text = "Discover new music tailored just for you",
style = MaterialTheme.typography.bodyLarge.copy(
lineHeight = 28.sp
)
)| Font | Characteristics | Best For |
|---|---|---|
| Inter | Clean, versatile, excellent legibility | General UI |
| Outfit | Geometric, modern, friendly | Headlines |
| Plus Jakarta Sans | Rounded, approachable | Casual apps |
| Montserrat | Classic, elegant | Premium feel |
| Poppins | Geometric, contemporary | Modern apps |
Material 3 Expressive includes 35 new abstract shapes beyond basic rounded rectangles:
- Stars, flowers, clover shapes
- Organic, nature-inspired forms
- Geometric patterns
- Pill and squircle variations
The MaterialShapes class in androidx.compose.material3 provides instant access to all 35 predefined shapes:
import androidx.compose.material3.MaterialShapes
// Access predefined shapes (returns RoundedPolygon)
val circleShape = MaterialShapes.Circle
val pillShape = MaterialShapes.Pill
val diamondShape = MaterialShapes.Diamond
val arrowShape = MaterialShapes.Arrow| Category | Shapes |
|---|---|
| Basic | Circle, Square, Oval, Pill |
| Geometric | Triangle, Diamond, Pentagon, Hexagon, Octagon |
| Directional | Arrow, SemiCircle, Arch, Fan |
| Organic | ClamShell, Flower, Clover, Leaf, Cookie |
| Decorative | Slanted, Bun, Boom, Ghostish, Heart |
| Specialty | SoftBurst, SunnyNew, VerySunny, FourPointStar, SixPointStar, EightPointStar |
| Plus more! | 35 total unique shapes |
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun ExpressiveAvatar() {
// Use a flower shape for profile avatar
val flowerShape = remember {
MaterialShapes.Flower.toShape()
}
Box(
modifier = Modifier
.size(80.dp)
.clip(flowerShape)
.background(MaterialTheme.colorScheme.primaryContainer)
) {
AsyncImage(
model = avatarUrl,
contentDescription = "Profile",
contentScale = ContentScale.Crop
)
}
}@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun MorphingButton(isSelected: Boolean) {
val startShape = MaterialShapes.Circle
val endShape = MaterialShapes.SoftBurst
val progress by animateFloatAsState(
targetValue = if (isSelected) 1f else 0f,
animationSpec = spring(Spring.DampingRatioMediumBouncy)
)
val morph = remember { Morph(startShape, endShape) }
val morphedShape = morph.toShape(progress)
Box(
modifier = Modifier
.size(56.dp)
.clip(morphedShape)
.background(
if (isSelected) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.surfaceVariant
)
)
}// MaterialShapes requires the experimental opt-in
@OptIn(ExperimentalMaterial3ExpressiveApi::class)One of the most delightful new features—shapes can smoothly transition between forms:
// Enable built-in shape morphing on buttons
IconButton(
onClick = { /* action */ },
shapes = IconButtonDefaults.shapes(), // Magic happens here!
) {
Icon(Icons.Default.PlayArrow, "Play")
}The corner radius system is now more granular:
| Token | Value | Use Case |
|---|---|---|
| None | 0dp | Sharp, technical |
| Extra Small | 4dp | Badges, tiny elements |
| Small | 8dp | Chips, text fields |
| Medium | 12dp | Standard cards |
| Large | 16dp | Prominent cards |
| Extra Large | 20dp | Featured elements |
| Extra Extra Large | 28dp | Hero cards |
| Full Round | 32dp+ | Pills, avatars |
// Create a custom clover shape
val cloverPolygon = RoundedPolygon.star(
numVerticesPerRadius = 4,
innerRadius = 0.5f,
rounding = CornerRounding(radius = 0.2f)
)
// Convert to Compose Shape for clipping
class PolygonShape(private val polygon: RoundedPolygon) : Shape {
override fun createOutline(
size: Size,
layoutDirection: LayoutDirection,
density: Density
): Outline {
val path = polygon.toPath().asComposePath()
// Scale and position...
return Outline.Generic(path)
}
}// Animate between two shapes
val morphProgress by animateFloatAsState(
targetValue = if (isExpanded) 1f else 0f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy
)
)
// Use morph progress to interpolate between shapes
val morph = remember { Morph(startShape, endShape) }
Canvas(modifier) {
drawPath(
path = morph.toPath(progress = morphProgress),
color = color
)
}Material 3 Expressive replaces the old easing + duration system with physics-based springs.
| Old System | New System |
|---|---|
tween(300ms, easeInOut) |
spring(dampingRatio, stiffness) |
| Linear interpolation | Natural physics simulation |
| Fixed duration | Dynamic, responsive |
| Robotic feel | Alive, organic feel |
Expressive Scheme (Default)
- Animations slightly overshoot their target
- Creates a noticeable "bounce"
- Perfect for hero moments, key interactions
Standard Scheme
- Minimal bounce, restrained
- Professional, functional feel
- Better for frequent, utilitarian actions
// Configure motion scheme in your theme
MaterialTheme(
motionScheme = MotionScheme.expressive() // or .standard()
) {
// Your app content
}| Parameter | What It Does |
|---|---|
| dampingRatio | How quickly oscillation stops (higher = faster) |
| stiffness | How fast/snappy the animation is |
// Very bouncy (playful apps, games)
spring(dampingRatio = Spring.DampingRatioHighBouncy)
// Balanced bounce (most apps)
spring(dampingRatio = Spring.DampingRatioMediumBouncy)
// Subtle, professional
spring(dampingRatio = Spring.DampingRatioLowBouncy)
// No bounce, smooth settle
spring(dampingRatio = Spring.DampingRatioNoBouncy)Spring.StiffnessHigh // 10000f - Very fast, snappy
Spring.StiffnessMedium // 1500f - Moderate speed
Spring.StiffnessLow // 200f - Slow, gentle
Spring.StiffnessVeryLow // 50f - Very slow, dramaticA button with a primary action + dropdown for related options.
SplitButtonLayout(
leadingButton = {
FilledButton(
onClick = { primaryAction() }
) {
Text("Save")
}
},
trailingButton = {
FilledIconButton(
onClick = { showMenu = true }
) {
Icon(Icons.Default.ArrowDropDown, null)
}
}
)Replaces stacked FABs—expands to show 2-6 related actions.
FloatingActionButtonMenu(
expanded = menuExpanded,
button = {
ToggleFloatingActionButton(
checked = menuExpanded,
onCheckedChange = { menuExpanded = it }
) {
Icon(
if (menuExpanded) Icons.Default.Close
else Icons.Default.Add,
null
)
}
}
) {
FloatingActionButtonMenuItem(
onClick = { /* action */ },
icon = { Icon(Icons.Default.Photo, null) },
text = { Text("Gallery") }
)
// More items...
}A new expressive loading animation for short waits (<5 seconds).
LoadingIndicator(
modifier = Modifier.size(48.dp)
)
// Features a looping shape-morph sequence of 7 Material shapes!Replaces segmented buttons with connected button groups featuring shape morphing.
Row(
horizontalArrangement = Arrangement.spacedBy(
ButtonGroupDefaults.ConnectedSpaceBetween
)
) {
ToggleButton(
checked = selected == 0,
onCheckedChange = { selected = 0 },
shapes = ButtonGroupDefaults.connectedLeadingButtonShapes()
) {
Text("Day")
}
ToggleButton(
checked = selected == 1,
onCheckedChange = { selected = 1 },
shapes = ButtonGroupDefaults.connectedMiddleButtonShapes()
) {
Text("Week")
}
ToggleButton(
checked = selected == 2,
onCheckedChange = { selected = 2 },
shapes = ButtonGroupDefaults.connectedTrailingButtonShapes()
) {
Text("Month")
}
}Flexible, undocked toolbars that can appear anywhere.
HorizontalFloatingToolbar(
expanded = true,
modifier = Modifier
.align(Alignment.BottomCenter)
.navigationBarsPadding()
.padding(bottom = 20.dp)
) {
// Your toolbar content
}Multi-browse and uncontained carousels with parallax effects.
HorizontalMultiBrowseCarousel(
state = rememberCarouselState { items.size },
preferredItemWidth = 200.dp,
itemSpacing = 8.dp
) { index ->
// Carousel item with automatic sizing and parallax
}- Broader color range for primary, secondary, and tertiary roles
- More surface container variants for depth
- Enhanced contrast options (Standard, Medium, High)
- Better brand color integration for non-dynamic themes
MaterialTheme.colorScheme.surface // Base
MaterialTheme.colorScheme.surfaceContainerLowest // Recessed
MaterialTheme.colorScheme.surfaceContainerLow // Slightly recessed
MaterialTheme.colorScheme.surfaceContainer // Default cards
MaterialTheme.colorScheme.surfaceContainerHigh // Elevated
MaterialTheme.colorScheme.surfaceContainerHighest // Most prominentMaterial 3 supports three contrast levels for accessibility:
| Level | Ratio | Use Case |
|---|---|---|
| Standard | Minimum WCAG | Default, meets basic accessibility |
| Medium | 3:1 | Enhanced readability |
| High | 7:1 | Maximum clarity, reduced visual noise |
Create professional icon backgrounds with alpha color:
Box(
modifier = Modifier
.size(48.dp)
.clip(RoundedCornerShape(14.dp))
.background(accentColor.copy(alpha = 0.12f)), // 12% opacity
contentAlignment = Alignment.Center
) {
Icon(
imageVector = icon,
tint = accentColor, // Full opacity
modifier = Modifier.size(26.dp)
)
}Design tokens are the building blocks of Material 3. They ensure consistency across your entire design system.
Tokens are named values that represent design decisions:
- Colors →
colorScheme.primary,colorScheme.surface - Typography →
typography.headlineLarge,typography.bodyMedium - Shapes →
shapes.medium,shapes.large - Spacing → Multiples of 8dp
- Consistency - Same values everywhere
- Theming - Change one token, update everywhere
- Dynamic Color - Tokens enable wallpaper-based theming
- Accessibility - Easy to adjust for contrast needs
// ✅ Use tokens
Text(
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge
)
// ❌ Avoid hardcoded values
Text(
color = Color.Black, // Bad - ignores dark mode!
fontSize = 16.sp // Bad - ignores user font preferences!
)Material 3 uses Material Symbols - a modern, variable icon set.
- Variable font technology - Single file, multiple styles
- 4 adjustable axes:
- Fill (0-1): Outlined ↔ Filled
- Weight (100-700): Thin ↔ Bold
- Grade (-25 to 200): Light ↔ Heavy emphasis
- Optical Size (20-48): Adapts to display size
| Variant | Characteristics | Best For |
|---|---|---|
| Outlined | Clean, minimal | Default state |
| Rounded | Friendly, approachable | Most apps |
| Sharp | Precise, technical | Pro/developer tools |
| Filled | Bold, prominent | Selected/active states |
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
// ✅ Rounded icons look more modern
Icon(Icons.Rounded.PlayArrow, "Play")
Icon(Icons.Rounded.Home, "Home")
Icon(Icons.Rounded.Settings, "Settings")
// Use Filled for selected states
Icon(
if (isSelected) Icons.Filled.Home else Icons.Outlined.Home,
"Home"
)| Context | Size | Icon Token |
|---|---|---|
| Dense lists | 20dp | Small |
| Standard lists | 24dp | Default |
| Buttons | 24dp | Default |
| FABs | 24-36dp | Medium-Large |
| Navigation | 24dp | Default |
| Hero displays | 48dp+ | Large |
Material 3 Expressive is built with accessibility as a core value.
Always respect the user's motion preferences:
@Composable
fun AccessibleAnimation() {
// Check if user prefers reduced motion
val reduceMotion = LocalReducedMotion.current
val animationSpec = if (reduceMotion) {
snap<Float>() // Instant, no animation
} else {
spring(dampingRatio = Spring.DampingRatioMediumBouncy)
}
val scale by animateFloatAsState(
targetValue = targetScale,
animationSpec = animationSpec
)
}| Element | Minimum Ratio |
|---|---|
| Normal text | 4.5:1 |
| Large text (18sp+ or 14sp bold) | 3:1 |
| UI components | 3:1 |
| Focus indicators | 3:1 |
// Minimum touch target: 48dp x 48dp
IconButton(
onClick = { /* action */ },
modifier = Modifier.size(48.dp) // Meets accessibility minimum
) {
Icon(
Icons.Rounded.Add,
modifier = Modifier.size(24.dp) // Icon can be smaller
)
}Always use sp for text sizes to respect user preferences:
// ✅ Respects user font size preferences
Text(fontSize = 16.sp)
// ❌ Ignores user preferences
Text(fontSize = 16.dp) // DON'T DO THISFor side-docked or vertical layouts:
VerticalFloatingToolbar(
expanded = isExpanded,
modifier = Modifier
.align(Alignment.CenterEnd)
.systemBarsPadding()
.padding(end = 16.dp)
) {
IconButton(onClick = { /* action */ }) {
Icon(Icons.Rounded.Edit, "Edit")
}
IconButton(onClick = { /* action */ }) {
Icon(Icons.Rounded.Share, "Share")
}
IconButton(onClick = { /* action */ }) {
Icon(Icons.Rounded.Delete, "Delete")
}
}Updated with thicker, wavy designs:
// Linear - now thicker and wavy
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
.height(8.dp) // Thicker than before
)
// Circular - enhanced styling
CircularProgressIndicator(
modifier = Modifier.size(48.dp),
strokeWidth = 4.dp
)
// NEW: Loading Indicator for short waits
LoadingIndicator(
modifier = Modifier.size(48.dp)
// Morphs through 7 different shapes!
)Modern search with expressive transitions:
var searchQuery by remember { mutableStateOf("") }
var isExpanded by remember { mutableStateOf(false) }
SearchBar(
inputField = {
SearchBarDefaults.InputField(
query = searchQuery,
onQueryChange = { searchQuery = it },
onSearch = { /* handle search */ },
expanded = isExpanded,
onExpandedChange = { isExpanded = it },
placeholder = { Text("Search songs...") },
leadingIcon = { Icon(Icons.Rounded.Search, null) },
trailingIcon = {
if (searchQuery.isNotEmpty()) {
IconButton(onClick = { searchQuery = "" }) {
Icon(Icons.Rounded.Close, "Clear")
}
}
}
)
},
expanded = isExpanded,
onExpandedChange = { isExpanded = it }
) {
// Search suggestions/results here
}Small details that create a premium feel:
@Composable
fun ShimmerCard() {
val shimmer = rememberInfiniteTransition()
val alpha by shimmer.animateFloat(
initialValue = 0.3f,
targetValue = 0.7f,
animationSpec = infiniteRepeatable(
animation = tween(1000),
repeatMode = RepeatMode.Reverse
)
)
Box(
modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.clip(RoundedCornerShape(16.dp))
.background(
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = alpha)
)
)
}var showSuccess by remember { mutableStateOf(false) }
AnimatedVisibility(
visible = showSuccess,
enter = scaleIn(
initialScale = 0.5f,
animationSpec = spring(Spring.DampingRatioMediumBouncy)
) + fadeIn()
) {
Icon(
imageVector = Icons.Rounded.CheckCircle,
tint = Color(0xFF4CAF50),
modifier = Modifier.size(32.dp)
)
}val haptic = LocalHapticFeedback.current
Button(
onClick = {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
// Your action
}
) {
Text("Save")
}Before touching components, establish:
- What emotions should your app evoke?
- What's your brand personality (fun, professional, playful, calm)?
- What are your brand colors?
Generate a complete color scheme from your brand color:
- https://m3.material.io/theme-builder
- Export to Compose, XML, or Figma
- Includes both light and dark themes automatically
Use the official Material 3 Design Kit:
- Customize colors, typography, shapes
- Create component variants for your brand
- Document your decisions
"Begin with one screen or component, then expand."
- Don't try to redesign everything at once
- Implement expressive tactics one at a time
- Test with real users early
- Spring animations can feel different on various devices
- Test dynamic color on devices with different wallpapers
- Verify motion respects "Reduce motion" settings
"We explored brand identity through the Material Theme Builder plugin. The colors needed to maintain personality even when dynamic color adapted them to user wallpapers."
Key Insight: Your brand should shine through regardless of dynamic color choices.
"Users described our Material 2 design as 'functional but forgettable.' Material 3 transformed it into something personal and engaging."
Key Insight: The design system enables expression—but you have to choose to be expressive.
"We used Material 3's 26+ color roles to create clear hierarchy. Every component was thoroughly tested to ensure consistent visual hierarchy."
Key Insight: Color roles exist for a reason—use them purposefully.
What they did well:
- Bold, vibrant brand colors
- Clear visual hierarchy through color roles
- Consistent component customization
- Design file publicly available
Link: Search "Now in Android Material 3 case study" on Medium
What makes it special:
- One of the first Material 3 Expressive redesigns
- Delightful animations throughout
- Interface feels "alive and responsive"
- Great example of shape morphing in action
What to learn:
- Carousel implementation
- Card hierarchy and depth
- Dynamic color integration
- Search bar design
What to learn:
- Floating toolbar implementation
- FAB design
- List interactions
- Navigation patterns
| Source | What You'll Find |
|---|---|
| Dribbble | Visual inspiration, concept designs |
| Material.io | Official guidelines, component specs |
| Medium | Case studies, design process articles |
| Android Dev Blog | Implementation details, new features |
| YouTube | Tutorials, Google I/O sessions |
// Required dependency (use alpha for Expressive features)
implementation("androidx.compose.material3:material3:1.4.0-alpha14")
// For graphics-shapes (custom shapes)
implementation("androidx.graphics:graphics-shapes:1.0.0")@Composable
fun IvorMusicTheme(
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
)
}@Composable
fun PressableCard(
onClick: () -> Unit,
content: @Composable () -> Unit
) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val scale by animateFloatAsState(
targetValue = if (isPressed) 0.97f else 1f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
Box(
modifier = Modifier
.scale(scale)
.clip(RoundedCornerShape(16.dp))
.clickable(
interactionSource = interactionSource,
indication = ripple()
) { onClick() }
) {
content()
}
}@Composable
fun AnimatedList(items: List<Item>) {
LazyColumn {
itemsIndexed(items) { index, item ->
var visible by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
delay(index * 50L) // 50ms stagger
visible = true
}
AnimatedVisibility(
visible = visible,
enter = fadeIn(tween(300)) +
slideInVertically(
initialOffsetY = { it / 3 },
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy
)
)
) {
ItemCard(item)
}
}
}
}- Spring animations on all interactive elements
- Consistent corner radii (pick 2-3 sizes)
- Generous whitespace (16-24dp padding)
- High-quality images (use high-res where available)
- Pull-to-refresh on content screens
- Ripple effects on all clickable elements
- Clear visual hierarchy (size, color, spacing)
- Accessibility (respects system font size, reduce motion)
- Shape morphing on buttons
- Staggered list animations
- Loading skeletons (not spinners)
- Success animations (checkmarks, etc.)
- Dynamic color support
- Custom shapes for brand identity
- Emphasized typography for key text
- Flat buttons without interaction feedback
- Abrupt state changes without transitions
- Generic icons (use Rounded/Filled variants)
- Crowded, cluttered layouts
- Inconsistent spacing
- Snap/instant animations for user-facing actions
- Ignoring reduced motion preferences
- Using spinners for short loading times
| Resource | URL | Description |
|---|---|---|
| Material Design 3 | https://m3.material.io/ | Official guidelines |
| M3 Expressive | https://material.io/blog/material-3-expressive | Overview blog post |
| Compose Material 3 | https://developer.android.com/develop/ui/compose/designsystems/material3 | Android implementation |
| Motion Guidelines | https://m3.material.io/styles/motion | Animation specs |
| Shape Guidelines | https://m3.material.io/styles/shape | Shape system |
| Color Guidelines | https://m3.material.io/styles/color | Color roles |
| Typography | https://m3.material.io/styles/typography | Type scale |
| Tool | URL | What It Does |
|---|---|---|
| Theme Builder | https://m3.material.io/theme-builder | Generate color schemes |
| Figma M3 Kit | https://www.figma.com/community/file/1035203688168086460 | Design components |
| Material Symbols | https://fonts.google.com/icons | Icon library |
| Channel/Source | Content |
|---|---|
| Material Design YouTube | Official tutorials |
| Google I/O Sessions | Annual design updates |
| Android Developers | Implementation guides |
| Philipp Lackner | Compose tutorials |
| Stevdza-San | UI/Compose examples |
| Topic | Where to Find |
|---|---|
| Now in Android Case Study | Medium |
| M3 App Redesign Stories | Medium, Dev.to |
| Compose Samples | Android Developer docs |
| Community Examples | GitHub |
| Source | URL |
|---|---|
| Dribbble | https://dribbble.com/tags/material3 |
| Mobbin | https://mobbin.com/browse/android |
| Awwwards | https://www.awwwards.com/websites/mobile/ |
"Good design is obvious. Great design is transparent."
— Joe Sparano
Material 3 Expressive gives you the tools to create truly exceptional apps. But tools are just tools—the magic comes from:
- Understanding your users and their emotional needs
- Making intentional choices about every design decision
- Testing and iterating based on real feedback
- Caring about the details that users feel but might not articulate
The best Material 3 apps don't just implement the guidelines—they use them as a foundation to express something unique. Your app should feel like you made it, not like Google made it.
Happy Designing! 🎨✨
This guide is a living document. Update it as Material Design evolves and as you learn new techniques.