Light dark theming
Skill almasumdev/awesome-mobile-design-system-agent-skills/.github/skills/theming/light-dark-theming
Light and dark theming via system integration, per-surface semantics, and elevation overlays. Use this when wiring color themes to the platform or adding a new surface.From its SKILL.md
npx -y skills add almasumdev/awesome-mobile-design-system-agent-skills --skill light-dark-themingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.1 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Light / Dark Theming
Instructions
Dark mode is not a palette swap. It is a different alias mapping of the same tonal palettes with its own contrast and elevation rules.
1. System Integration
Follow the OS. Never ship an in-app toggle that ignores prefers-color-scheme — only an override.
- Android:
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM)by default; apps readConfiguration.UI_MODE_NIGHT_YESorisSystemInDarkTheme()in Compose. - iOS:
UITraitCollection.userInterfaceStyle/ SwiftUI@Environment(\.colorScheme). - Flutter:
MediaQuery.of(context).platformBrightnessorThemeMode.system. - React Native:
Appearance.getColorScheme()anduseColorScheme().
2. Per-Surface Semantics
Ship tokens for a small, named set of surfaces — not a single "background."
| Token | Light | Dark | Use |
|---|---|---|---|
color.surface.default | neutral.99 | neutral.10 | App background |
color.surface.subtle | neutral.95 | neutral.15 | Cards, sheets |
color.surface.raised | neutral.99 | neutral.20 | Elevated cards |
color.surface.overlay | neutral.99 α 95% | neutral.10 α 90% | Modals, popovers |
color.surface.inverse | neutral.10 | neutral.95 | Tooltips, toasts |
Each surface has a paired content token (color.content.*) whose contrast against the surface is verified AA.
3. Dark Elevation: Tint Over Shadow
On dark themes, shadows become invisible. Convey elevation with surface tint (Material 3) — a subtle tonal wash at higher levels.
val DarkColorScheme = darkColorScheme(
surface = ds.color.surface.default,
surfaceContainer = ds.color.surface.subtle,
surfaceContainerHigh = ds.color.surface.raised,
surfaceTint = ds.color.action.primary.bg, // Material 3 applies this at elevation
)
4. Compose Wiring
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
val scheme = if (darkTheme) DarkColorScheme else LightColorScheme
MaterialTheme(colorScheme = scheme, typography = AppTypography, content = content)
}
5. SwiftUI Wiring
Use asset catalog color sets with separate Any Appearance + Dark Appearance values, referenced semantically:
extension Color {
static let dsSurfaceDefault = Color("surface/default")
static let dsContentDefault = Color("content/default")
}
To force a theme locally:
ContentView().preferredColorScheme(.dark)
6. Flutter Wiring
MaterialApp(
themeMode: ThemeMode.system,
theme: AppTheme.light(),
darkTheme: AppTheme.dark(),
);
class AppTheme {
static ThemeData light() => ThemeData(
useMaterial3: true,
colorScheme: lightColorScheme,
extensions: [AppColors.light, AppSpacing.standard],
);
static ThemeData dark() => ThemeData(
useMaterial3: true,
colorScheme: darkColorScheme,
extensions: [AppColors.dark, AppSpacing.standard],
);
}
7. React Native Wiring
const scheme = useColorScheme();
const theme = scheme === 'dark' ? darkTheme : lightTheme;
return <ThemeProvider value={theme}>{children}</ThemeProvider>;
8. Edge Cases
- Images and illustrations: ship light and dark variants or use monochrome assets that inherit
color.content.default. - Status bar / navigation bar: set to match surface color and icon contrast (
WindowCompaton Android,preferredStatusBarStyle/UIStatusBarStyleon iOS,StatusBaron RN). - System keyboards and sheets: inherit dark mode automatically — do not override unless the design explicitly requires it.
- Screenshots and sharing: use
color.surface.defaultso exports are consistent.
9. Anti-Patterns
- Hardcoded
Color(0xFFFFFFFF)anywhere. - Using
Colors.white.withOpacity(0.7)as muted text — fails contrast in light mode. - A single "background" token used for app, card, and modal.
- Dark-only shadows; they are invisible and waste layout cost.
- Manual theme toggles that ignore the system preference as a default.
Checklist
- The app follows the system color scheme by default; any override persists but does not override system as initial state.
- Multiple named surface tokens exist (default, subtle, raised, overlay, inverse) with paired content tokens.
- Dark elevation uses surface tint, not shadows alone.
- Status bar / nav bar colors match the current surface on every screen.
- Contrast is verified AA for every content-on-surface pair in both themes.
- Images and illustrations have dark variants or inherit from tokens.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.