New to Claude Skills? Learn how to install them →

sickn33 on GitHub

Dark Mode Design

Free

Guidelines for implementing dark mode aesthetics.

Get this skill

Free · Opens the source repo

What Dark Mode Design does

Dark Mode Design is a comprehensive guide for developers and designers looking to implement dark mode in their web and app interfaces. This skill emphasizes the importance of not merely inverting colors but creating a thoughtful visual hierarchy that enhances user experience while reducing eye strain. By following the principles outlined in this guide, users can achieve a sleek and modern aesthetic that is both functional and visually appealing.

The core principles of dark mode design include avoiding pure black backgrounds, which can cause smearing on OLED screens and discomfort for users. Instead, the guide recommends using dark greys, such as #121212, to create a more comfortable viewing experience. Additionally, it addresses the concept of elevation in dark mode; since shadows are less visible, elevated surfaces should be lighter than the background to maintain a sense of depth and structure.

The skill also provides practical implementation examples in CSS, SwiftUI, and Flutter, making it accessible for various platforms. For instance, the CSS example includes variables for background colors and text emphasis, while the SwiftUI and Flutter code snippets demonstrate how to utilize semantic colors for automatic dark mode transitions. These examples ensure that developers can easily integrate dark mode into their applications without compromising on design quality.

Targeted at UI/UX designers and front-end developers, this skill is ideal for anyone looking to enhance their applications with a modern dark mode feature that prioritizes user comfort and aesthetic appeal. By adhering to the guidelines provided, users can create dark mode designs that not only look good but also feel good to use.

When to use it

Use this skill when designing applications that require a dark mode aesthetic, particularly when user comfort and visual hierarchy are priorities.

When not to use it

This skill is not suitable for projects where dark mode is not a design consideration or where simple color inversion is acceptable.

What you can build with it

Creating a Dark Mode for a Mobile App

Use this skill to guide the design of a mobile application that features a dark mode, ensuring user comfort and aesthetic quality.

Implementing Dark Mode in a Web Application

Refer to the CSS examples in this skill when adding dark mode support to a web application, focusing on color hierarchy and readability.

Enhancing User Experience with Dark Mode

Utilize the principles outlined in this skill to improve the overall user experience of your application by implementing a well-designed dark mode.

How to install Dark Mode Design

View source

1. Install with the skills CLI

npx skills add sickn33/agentic-awesome-skills/dark-mode --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by sickn33

Dark Mode Design

"Not just inverted colors. A carefully constructed hierarchy of light on dark."

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. Never Pure Black: True #000000 causes smearing on OLED screens and extreme eye strain with white text. Use dark greys (e.g., #121212 or #0A0A0A).
  2. Elevation via Lightness: In light mode, shadows show elevation. In dark mode, shadows are invisible, so elevated surfaces must be lighter than the background.
  3. Desaturated Accents: Saturated colors vibrate painfully against dark backgrounds. Tone down the saturation of brand colors.

Visual DNA

  • Colors: Midnight Luxury or Minimalist Slate (inverted). Background #121212. Elevated cards #1E1E1E, #252525. Primary text #E1E1E1 (not #FFFFFF).
  • Typography: Standard highly readable sans-serifs, but often dropped down one font weight compared to light mode, as light text on dark backgrounds appears optically thicker.
  • Shadows: Pure black shadows, but with much lower opacity, mostly to separate slightly different shades of grey.

Web Implementation

  • CSS Example:
:root {
  --bg-base: #121212;
  --bg-elevated-1: #1E1E1E;
  --bg-elevated-2: #242424;
  --text-high-emphasis: rgba(255, 255, 255, 0.87);
  --text-medium-emphasis: rgba(255, 255, 255, 0.60);
  
  /* Accent color: Desaturated purple instead of bright purple */
  --accent-color: #BB86FC; 
}

body {
  background-color: var(--bg-base);
  color: var(--text-high-emphasis);
  font-weight: 300; /* Thinner weight for dark mode */
}

.dark-card {
  background-color: var(--bg-elevated-1);
  border-radius: 8px;
  padding: 24px;
  
  /* Very subtle border can help separate dark surfaces */
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.dark-card:hover {
  /* On hover, the element moves closer to the user, so it gets lighter */
  background-color: var(--bg-elevated-2);
}

.dark-btn {
  background-color: var(--accent-color);
  color: #000; /* Dark text on light accent is highly readable */
  font-weight: 600;
  border: none;
  padding: 12px 24px;
  border-radius: 4px;
}

App Implementation

SwiftUI

struct DarkModeView: View {
    // Force Dark Mode on this specific view (or use system settings)
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                // Primary elevated card
                VStack(alignment: .leading, spacing: 12) {
                    Text("Elevation via Lightness")
                        .font(.headline)
                        .foregroundColor(.primary) // Auto-adapts
                    Text("In dark mode, elevated surfaces are lighter grey, not shadowed.")
                        .font(.subheadline)
                        .foregroundColor(.secondary) // Auto-adapts
                }
                .padding()
                .frame(maxWidth: .infinity, alignment: .leading)
                // Use native semantic colors. .secondarySystemBackground is lighter than .systemBackground
                .background(Color(UIColor.secondarySystemBackground))
                .cornerRadius(12)
                
                // Desaturated Accent Button
                Button(action: {}) {
                    Text("Desaturated Accent")
                        .fontWeight(.semibold)
                        .foregroundColor(.black) // Dark text on light accent
                        .padding()
                        .frame(maxWidth: .infinity)
                        .background(Color(red: 0.73, green: 0.52, blue: 0.98)) // #BB86FC (Desaturated purple)
                        .cornerRadius(8)
                }
            }
            .padding()
        }
        // #121212 is the standard dark mode background, which systemBackground maps to closely
        .background(Color(UIColor.systemBackground))
    }
}
// .preferredColorScheme(.dark) to force
  • Rely on Semantics: SwiftUI's Color.primary, Color.secondary, Color(UIColor.systemBackground) and Color(UIColor.secondarySystemBackground) handle perfect dark mode transitions automatically.
  • Avoid forcing explicit hex codes for backgrounds unless you are building a custom-themed app.

Flutter

import 'package:flutter/material.dart';

class DarkModeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Configure the Dark Theme
      themeMode: ThemeMode.dark,
      darkTheme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: const Color(0xFF121212), // Standard dark background
        cardColor: const Color(0xFF1E1E1E), // Elevated surface
        colorScheme: const ColorScheme.dark().copyWith(
          primary: const Color(0xFFBB86FC), // Desaturated accent
          onPrimary: Colors.black, // Dark text on light accent
          surface: const Color(0xFF1E1E1E),
        ),
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text('Dark Mode', style: TextStyle(color: Colors.white70))),
        body: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            Card(
              elevation: 0, // Shadows don't show well anyway
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
                side: BorderSide(color: Colors.white.withOpacity(0.05)), // Subtle border
              ),
              child: const Padding(
                padding: EdgeInsets.all(16.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Elevation via Lightness', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    SizedBox(height: 8),
                    Text('Elevated surfaces use lighter greys.', style: TextStyle(color: Colors.white60)),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {},
              child: const Text('Desaturated Accent'),
            ),
          ],
        ),
      ),
    );
  }
}
  • When using ThemeData.dark(), actively override scaffoldBackgroundColor to #121212 and cardColor to #1E1E1E.
  • Ensure your colorScheme.onPrimary is black so text is readable when placed on top of your desaturated primary accent button.

React Native

import { useColorScheme } from 'react-native';

const DarkModeScreen = () => {
  const isDark = useColorScheme() === 'dark';
  
  // Custom dark theme dictionary
  const theme = {
    bgBase: isDark ? '#121212' : '#FFFFFF',
    bgElevated: isDark ? '#1E1E1E' : '#F5F5F5',
    textHigh: isDark ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)',
    textMedium: isDark ? 'rgba(255, 255, 255, 0.60)' : 'rgba(0, 0, 0, 0.60)',
    accent: isDark ? '#BB86FC' : '#6200EE', // Desaturated for dark, vibrant for light
    onAccent: isDark ? '#000' : '#FFF',
  };

  return (
    <View style={{ flex: 1, backgroundColor: theme.bgBase, padding: 16 }}>
      <View style={{
        backgroundColor: theme.bgElevated,
        padding: 24,
        borderRadius: 12,
        borderWidth: isDark ? 1 : 0,
        borderColor: 'rgba(255,255,255,0.05)',
        marginBottom: 20
      }}>
        <Text style={{ color: theme.textHigh, fontSize: 18, fontWeight: 'bold', marginBottom: 8 }}>
          Elevation via Lightness
        </Text>
        <Text style={{ color: theme.textMedium }}>
          Elevated surfaces use lighter greys.
        </Text>
      </View>

      <TouchableOpacity style={{
        backgroundColor: theme.accent,
        padding: 16,
        borderRadius: 8,
        alignItems: 'center'
      }}>
        <Text style={{ color: theme.onAccent, fontWeight: 'bold' }}>Desaturated Accent</Text>
      </TouchableOpacity>
    </View>
  );
};
  • Rely on useColorScheme() hook from React Native.
  • Define a strict dictionary of your color tokens. Notice how theme.accent shifts from a vibrant purple (#6200EE) in light mode to a desaturated pastel purple (#BB86FC) in dark mode.

Jetpack Compose

@Composable
fun DarkModeScreen() {
    // Typically this logic lives in your Theme.kt
    val darkColors = darkColorScheme(
        background = Color(0xFF121212),
        surface = Color(0xFF1E1E1E),
        primary = Color(0xFFBB86FC),
        onPrimary = Color.Black,
        onBackground = Color.White.copy(alpha = 0.87f),
        onSurface = Color.White.copy(alpha = 0.87f)
    )

    MaterialTheme(colorScheme = darkColors) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(MaterialTheme.colorScheme.background)
                .padding(16.dp)
        ) {
            Card(
                colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
                shape = RoundedCornerShape(12.dp),
                border = BorderStroke(1.dp, Color.White.copy(alpha = 0.05f))
            ) {
                Column(modifier = Modifier.padding(24.dp)) {
                    Text("Elevation via Lightness", 
                        style = MaterialTheme.typography.titleMedium, 
                        color = MaterialTheme.colorScheme.onSurface)
                    Spacer(Modifier.height(8.dp))
                    Text("Elevated surfaces use lighter greys.", 
                        style = MaterialTheme.typography.bodyMedium, 
                        color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f))
                }
            }
            
            Spacer(Modifier.height(20.dp))
            
            Button(
                onClick = {},
                colors = ButtonDefaults.buttonColors(
                    containerColor = MaterialTheme.colorScheme.primary,
                    contentColor = MaterialTheme.colorScheme.onPrimary
                ),
                modifier = Modifier.fillMaxWidth().height(50.dp)
            ) {
                Text("Desaturated Accent", fontWeight = FontWeight.Bold)
            }
        }
    }
}
  • Material 3 handles Dark Mode semantics perfectly. Define your darkColorScheme.
  • Use Color(0xFF1E1E1E) for surface and Color(0xFF121212) for background. Compose will automatically map these to Cards and Scaffolds.

Do's and Don'ts

  • DO: Meet WCAG contrast standards. Just because it's dark doesn't mean the text should be illegibly dim.
  • DON'T: Use bright, highly saturated primary colors.

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.

Frequently asked questions about Dark Mode Design

Similar skills