# Material3 Design System

> >

- **Type:** Skill
- **Install:** `agentstack add skill-iammohdzaki-kmp-skills-material3`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [iammohdzaki](https://agentstack.voostack.com/s/iammohdzaki)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [iammohdzaki](https://github.com/iammohdzaki)
- **Source:** https://github.com/iammohdzaki/kmp-skills/tree/main/skills/design-system/material3

## Install

```sh
agentstack add skill-iammohdzaki-kmp-skills-material3
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Material Design 3 — KMP / Compose Multiplatform Skill

This skill guides implementation of Google's **Material Design 3 (MD3 / Material You)** using
**Jetpack Compose** and **Compose Multiplatform** for KMP projects (Android + Desktop).

> **Attribution**: This skill is adapted from and gives credit to
> **[hamen/material-3-skill](https://github.com/hamen/material-3-skill)** by Hamen.
> The original skill covers web and Flutter targets. This KMP edition strips all web/CSS/Flutter
> patterns and replaces them with pure Compose Multiplatform APIs, adds the audit report system,
> and extends the reference set for adaptive layout, navigation, and versioning.

> **Scope**: Compose-only. All examples use `androidx.compose.material3` APIs — the same API
> surface is available in KMP `commonMain` via `org.jetbrains.compose.material3:material3`
> (declared explicitly in `libs.versions.toml`). No web CSS, no `@material/web` elements, no Flutter.

---

## MD3 Philosophy

| Principle | What it means in Compose |
|---|---|
| **Personal** | Dynamic color from user wallpaper (Android 12+). Static fallback for Desktop. |
| **Adaptive** | `WindowSizeClass` drives layout changes across compact → expanded screens. |
| **Expressive** | Spring-based motion, shape morphing, emphasized typography. |

### Google I/O 2026 Key Updates

- **Compose-first on Android**: For all new Android work, use `androidx.compose.material3`.
- **Expressive layout scaffold**: Design screens to adapt across mobile, desktop, foldables. Use `Material3Adaptive` scaffold APIs.
- **8dp spacing system**: Define spacing as tokens — never scatter raw `Dp` literals.
- **New expressive components**: Lists, menus, search, and search app bars have refreshed expressive guidance; check your Material3 BOM for expressive variants.

---

## Design Token System

All MD3 values come through `MaterialTheme`. **Never hardcode** raw values inline.

| Token category | Access in Compose |
|---|---|
| Color | `MaterialTheme.colorScheme.*` |
| Typography | `MaterialTheme.typography.*` |
| Shape | `MaterialTheme.shapes.*` |
| Spacing | Define a `Dimens` object (no built-in API) |

---

## Decision Tree

```
What are you building?

Full app scaffold        → AppTheme setup + references/theming-and-dynamic-color.md
Single component         → references/component-catalog.md
Custom color theme       → references/color-system.md
Typography / fonts       → references/typography-and-shape.md
Navigation structure     → references/navigation-patterns.md
Adaptive layout          → references/layout-and-responsive.md
```

---

## Color Token Summary

Full details in [references/color-system.md](references/color-system.md).

### Key Roles (Compose token → usage)

| Role | Token | Primary Usage |
|---|---|---|
| Primary | `colorScheme.primary` | FAB, key buttons, active states |
| On Primary | `colorScheme.onPrimary` | Text/icons on primary |
| Primary Container | `colorScheme.primaryContainer` | Tonal buttons, selected chips |
| On Primary Container | `colorScheme.onPrimaryContainer` | Text on primary container |
| Secondary | `colorScheme.secondary` | Less prominent accents, filters |
| Secondary Container | `colorScheme.secondaryContainer` | Recessive fills |
| Tertiary | `colorScheme.tertiary` | Contrasting accent sections |
| Surface | `colorScheme.surface` | Cards, sheets, menus |
| Surface Container | `colorScheme.surfaceContainer` | Navigation areas |
| On Surface | `colorScheme.onSurface` | Body text, icons |
| On Surface Variant | `colorScheme.onSurfaceVariant` | Placeholder, helper text |
| Outline | `colorScheme.outline` | Input borders, dividers |
| Error | `colorScheme.error` | Error states |

---

## Typography Token Summary

Full details in [references/typography-and-shape.md](references/typography-and-shape.md).

| Category | Styles | Usage |
|---|---|---|
| Display | L / M / S | Hero text, large numbers |
| Headline | L / M / S | Screen/section headers |
| Title | L / M / S | Toolbar titles, card headers |
| Body | L / M / S | Paragraph text, descriptions |
| Label | L / M / S | Buttons, chips, captions |

```kotlin
// ✅ Always via MaterialTheme
Text("Title", style = MaterialTheme.typography.titleLarge)
Text("Body", style = MaterialTheme.typography.bodyMedium)

// ❌ Never inline
Text("Title", fontSize = 22.sp, fontWeight = FontWeight.Normal)
```

---

## Shape Token Summary

| Token | Corner Radius | Typical Components |
|---|---|---|
| `shapes.extraSmall` | 4dp | Chips, snackbars |
| `shapes.small` | 8dp | Text fields, menus |
| `shapes.medium` | 12dp | Cards |
| `shapes.large` | 16dp | FABs, nav drawer |
| `shapes.extraLarge` | 28dp | Dialogs, bottom sheets |

---

## Elevation

MD3 communicates depth through **tonal surface color**, not drop shadows.

| Level | Compose API | Tonal Offset | Use |
|---|---|---|---|
| 0 | `Elevation.Level0` / `0.dp` | None | Flat surfaces at rest |
| 1 | `Elevation.Level1` / `1.dp` | +5% primary | Elevated cards |
| 2 | `Elevation.Level2` / `3.dp` | +8% primary | Menus, nav bar |
| 3 | `Elevation.Level3` / `6.dp` | +11% primary | FAB, dialogs |

```kotlin
// Cards respect tonal elevation automatically via surfaceTonalElevation
ElevatedCard(elevation = CardDefaults.elevatedCardElevation(defaultElevation = 6.dp)) { }
```

---

## Motion Summary

Full details in [references/typography-and-shape.md](references/typography-and-shape.md) §Motion.

| Easing | Compose | Usage |
|---|---|---|
| Emphasized | `CubicBezierEasing(0.2f, 0f, 0f, 1f)` | Elements staying on screen |
| Emphasized Decelerate | `CubicBezierEasing(0.05f, 0.7f, 0.1f, 1f)` | Entering screen |
| Emphasized Accelerate | `CubicBezierEasing(0.3f, 0f, 0.8f, 0.15f)` | Leaving screen |
| Standard | `FastOutSlowInEasing` | Utility animations |

### Standard Durations

| Token | Duration | Usage |
|---|---|---|
| Short | 100–200ms | Icon/color state changes |
| Medium | 300–400ms | Component expand/collapse |
| Long | 400–500ms | Screen-level transitions |

---

## Component Quick Reference

| Component | Compose API | Category |
|---|---|---|
| Button (Filled) | `Button {}` | Actions |
| Button (Tonal) | `FilledTonalButton {}` | Actions |
| Button (Outlined) | `OutlinedButton {}` | Actions |
| Button (Text) | `TextButton {}` | Actions |
| FAB | `FloatingActionButton {}` | Actions |
| Extended FAB | `ExtendedFloatingActionButton {}` | Actions |
| Icon Button | `IconButton {}`, `FilledIconButton {}` | Actions |
| Segmented Button | `SegmentedButton {}` | Actions |
| Card | `Card {}`, `ElevatedCard {}`, `OutlinedCard {}` | Containment |
| Dialog | `AlertDialog {}`, `Dialog {}` | Containment |
| Bottom Sheet | `ModalBottomSheet {}` | Sheets |
| Snackbar | `SnackbarHost {}` | Communication |
| Progress | `CircularProgressIndicator()`, `LinearProgressIndicator()` | Communication |
| Badge | `BadgedBox {}` | Communication |
| Checkbox | `Checkbox()` | Input |
| RadioButton | `RadioButton()` | Input |
| Switch | `Switch()` | Input |
| Slider | `Slider()`, `RangeSlider()` | Input |
| TextField | `TextField()`, `OutlinedTextField()` | Input |
| Chips | `FilterChip`, `AssistChip`, `InputChip`, `SuggestionChip` | Input |
| TopAppBar | `TopAppBar`, `CenterAlignedTopAppBar`, `LargeTopAppBar` | Navigation |
| Navigation Bar | `NavigationBar {}` | Navigation |
| Navigation Rail | `NavigationRail {}` | Navigation |
| Navigation Drawer | `ModalNavigationDrawer {}` | Navigation |
| Tabs | `TabRow {}`, `ScrollableTabRow {}` | Navigation |

Full Compose API + examples: [references/component-catalog.md](references/component-catalog.md)

---

## AppTheme Setup (Quick Start)

```kotlin
@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is Android 12+ only — always falls back to static on Desktop
    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
    )
}
```

> For **Compose Multiplatform Desktop**: Remove `Build.VERSION_SDK_INT` check and always use
> `LightColorScheme` / `DarkColorScheme`. Dynamic color has no JVM equivalent.

Full theming guide: [references/theming-and-dynamic-color.md](references/theming-and-dynamic-color.md)

---

## Core Rules

- **Never** hardcode `Color(0xFF...)` in composables — always `MaterialTheme.colorScheme.*`
- **Never** inline `fontSize`, `fontFamily`, `fontWeight` — always `MaterialTheme.typography.*`
- **Never** inline `RoundedCornerShape(12.dp)` — always `MaterialTheme.shapes.*`
- **Always** wrap content in `AppTheme` at the root — never in individual screens
- **Always** support dark mode — test every screen with `isSystemInDarkTheme()`
- **Always** use `Scaffold` — it handles `topBar`, `bottomBar`, `FAB`, `snackbarHost`, padding
- Minimum touch target: **48×48dp** for all interactive elements
- Spacing tokens: **always multiples of 4dp** — define a `Dimens` object
- For Desktop/JVM: always use static color schemes — no dynamic color API on JVM

---

## MD3 Compliance Audit

When the user asks for an **audit**, a **compliance check**, or passes code / a screen name
with the `audit` argument, run a full MD3 compliance report using the template below.

### How to trigger

```
audit [screen name or paste code here]
audit HomeScreen
audit 
check this screen against material 3
run md3 audit
```

### Audit Process

1. **Scan the target** — read the provided code or ask the user to paste the composable(s) to audit.
2. **Check each category** below in order.
3. **Output the report** using the exact format specified.
4. **Offer fixes** — for every ❌ or ⚠️, provide the corrected Compose code snippet inline.

---

### Audit Report Format

Output the report in this exact structure:

```
╔══════════════════════════════════════════════════════════╗
║          MD3 COMPLIANCE AUDIT — [Screen/File Name]       ║
║          KMP / Compose Multiplatform Edition             ║
╚══════════════════════════════════════════════════════════╝

Score: [X / 10]   Grade: [A / B / C / D / F]

┌─────────────────────────────────────────────────────────┐
│ CATEGORY RESULTS                                        │
└─────────────────────────────────────────────────────────┘

[✅ / ⚠️ / ❌]  COLOR SYSTEM          [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  TYPOGRAPHY            [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  SHAPE                 [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  SPACING               [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  ELEVATION             [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  COMPONENTS            [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  LAYOUT & ADAPTIVE     [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  NAVIGATION            [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  MOTION & ANIMATION    [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  DARK MODE             [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  ACCESSIBILITY         [PASS / WARN / FAIL]
[✅ / ⚠️ / ❌]  THEMING SETUP         [PASS / WARN / FAIL]

┌─────────────────────────────────────────────────────────┐
│ FINDINGS                                                │
└─────────────────────────────────────────────────────────┘

[findings listed per category — see check rules below]

┌─────────────────────────────────────────────────────────┐
│ FIXES                                                   │
└─────────────────────────────────────────────────────────┘

[corrected code snippets for every ❌ and ⚠️]
```

---

### Audit Check Rules — Per Category

#### 1. COLOR SYSTEM

| Check | Pass condition | Fail condition |
|---|---|---|
| No hardcoded colors in composables | `MaterialTheme.colorScheme.*` used | `Color(0xFF…)` literal in UI code |
| No swapped semantic roles | `error` used for errors only | `error` used for success/warning |
| Both schemes defined | `LightColorScheme` + `DarkColorScheme` exist | Only one scheme present |
| Dynamic color has static fallback | `if (dynamicColor && SDK >= S)` with else branch | Dynamic color used unconditionally |
| Extended colors use `CompositionLocal` | `LocalExtendedColors` pattern | Raw color passed as parameter |
| Desktop: no dynamic color API | `jvmMain` uses static scheme | `dynamicDarkColorScheme()` in `jvmMain` |

#### 2. TYPOGRAPHY

| Check | Pass condition | Fail condition |
|---|---|---|
| No inline font sizes | `MaterialTheme.typography.*` used | `fontSize = 16.sp` inline |
| No inline font weights | `MaterialTheme.typography.*` used | `fontWeight = FontWeight.Bold` inline |
| Custom font loaded via `Res.font.*` | `Font(Res.font.*)` for KMP | Hardcoded path or `fontFamily` literal |
| All 15 styles defined if custom typography | `Typography(displayLarge = …, labelSmall = …)` | Missing styles in custom `Typography` |
| Body text uses `bodyLarge`/`bodyMedium` | Correct role applied | `displayLarge` on body copy |

#### 3. SHAPE

| Check | Pass condition | Fail condition |
|---|---|---|
| No inline `RoundedCornerShape` | `MaterialTheme.shapes.*` used | `RoundedCornerShape(12.dp)` inline |
| Shape token matches component | Cards use `shapes.medium`, FABs use `shapes.extraLarge` | FAB with `shapes.small` |
| Custom shapes defined in `AppShapes` | `val AppShapes = Shapes(…)` in theme | Shape overrides scattered in UI |

#### 4. SPACING

| Check | Pass condition | Fail condition |
|---|---|---|
| Spacing uses `Dimens` object | `Dimens.md`, `Dimens.lg`, etc. | Scattered `16.dp`, `24.dp` literals |
| Values are multiples of 4dp | 4, 8, 12, 16, 24, 32, 48dp | 15.dp, 7.dp, 11.dp literals |
| Screen margins consistent | `Dimens.screenHorizontal` used | Mixed margin values per screen |

#### 5. ELEVATION

| Check | Pass condition | Fail condition |
|---|---|---|
| Tonal elevation used | `tonalElevation` / `CardDefaults.elevatedCardElevation()` | `Modifier.shadow(8.dp)` for depth |
| Shadow used only for busy backgrounds | Rare `Modifier.shadow` with clear reason | Shadows on all cards for styling |

#### 6. COMPONENTS

| Check | Pass condition | Fail condition |
|---|---|---|
| Only one `Button` (filled) per section | Single primary action | Multiple filled buttons per section |
| FAB in `Scaffold.floatingActionButton` | `Scaffold(floatingActionButton = {…})` | FAB positioned manually with `Box` |
| `Scaffold` used on every screen | `Scaffold {}` wraps each screen | No `Scaffold`, manual layout |
| `AlertDialog` for destructive actions | `confirmButton` + `dismissButton` both present | No dismiss option on destructive dialog |
| Lists use `ListItem` | `ListItem(headlineContent = …)` | Custom `Row` replacing `ListItem` |
| Buttons use correct emphasis hierarchy | Filled → Tonal → Elevated → Outlined → Text | Multiple filled buttons, no hierarchy |

#### 7. LAYOUT & ADAPTIVE

| Check | Pass condition | Fail condition |
|---|---|---|
| `WindowSizeClass` used | `calculateWindowSizeClass()` or `currentWindowAdaptiveInfo()` | Fixed-width `if (isTablet)` hack |
| No hardcoded breakpoints | `WindowWidthSizeClass.*` enum | `if (width > 600.dp)` check |
| Canonical layout pattern used | Feed / List-Detail / Supporting Pane | None of the canonical patterns applied |
| Edge-to-edge enabled | `enableEdgeToEdge()` in Activity | Status bar not handled |
| `WindowInsets` applied | `Modifier.statusBarsPadding()` or `Scaffold` | Content hidden behind system bars |
| Adaptive API used for list-detail | `NavigableListDetailPaneScaffold` | Manual `Row` reimplementing list-detail |

#### 8. NAVIGATION

| Check | Pass condition | Fail condition |
|---|---|---|
| Nav component matches window size | `NavigationBar` on compact, `NavigationRail` on medium, drawer on expanded | Bottom nav on tablet |
| Bottom nav has 3–5 items | Dest

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [iammohdzaki](https://github.com/iammohdzaki)
- **Source:** [iammohdzaki/kmp-skills](https://github.com/iammohdzaki/kmp-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-iammohdzaki-kmp-skills-material3
- Seller: https://agentstack.voostack.com/s/iammohdzaki
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
