dark-mode — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited dark-mode (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are in AUTONOMOUS MODE. Do NOT ask questions. Execute the full pipeline below without pausing for user input. Make reasonable decisions using sensible defaults.
PURPOSE: Implement a complete dark mode for the current project. Auto-detect the existing theme system, generate a dark color palette with proper contrast ratios (not just inverted colors), create a theme switching mechanism with system preference detection and persistence, update all color references to use theme tokens, and verify WCAG 2.1 AA contrast ratios for both light and dark modes.
INPUT: $ARGUMENTS
The user may specify:
If no arguments, implement full dark mode with system detection + manual toggle + localStorage.
============================================================ PHASE 1 -- FRAMEWORK AND THEME DETECTION ============================================================
Detect the frontend framework and existing theme system:
| Indicator | Framework | Theme Mechanism |
|---|---|---|
| pubspec.yaml | Flutter | ThemeData.light() / ThemeData.dark() + ThemeMode |
| tailwind.config.* with darkMode | Tailwind CSS | class or media strategy |
| next-themes or package.json with "next" | Next.js | next-themes or CSS variables |
| package.json with "react" | React | CSS variables + context/state |
| package.json with "vue" | Vue | CSS variables + composable/plugin |
| package.json with "@angular/core" | Angular | CSS variables + service |
| styled-components/emotion | CSS-in-JS | ThemeProvider with theme object |
| package.json with "@mui/material" | MUI | createTheme with mode |
| package.json with "@chakra-ui/react" | Chakra UI | useColorMode |
Check for existing dark mode infrastructure:
prefers-color-scheme media query usageRecord: FRAMEWORK, THEME_SYSTEM, EXISTING_DARK_MODE, LIGHT_PALETTE, TOKEN_FILE
============================================================ PHASE 2 -- LIGHT PALETTE ANALYSIS ============================================================
Extract the complete light mode color palette:
Step 2.1 -- Catalog Light Colors
Read the existing theme/token files and all color references:
For each color, record:
| Token/Variable | Light Value | Usage Category | Contrast Context |
|---|
Step 2.2 -- Identify Contrast Pairs
Map which colors appear together as foreground/background pairs:
These pairs will be validated for contrast in both modes.
============================================================ PHASE 3 -- DARK PALETTE GENERATION ============================================================
Generate a dark color palette following established dark mode design principles.
Step 3.1 -- Background Scale
Create the dark background hierarchy (surfaces layer UP in darkness):
Step 3.2 -- Text Colors
Generate text colors for dark mode:
Step 3.3 -- Brand Color Adaptation
Adapt brand/primary colors for dark backgrounds:
Step 3.4 -- Semantic Color Adaptation
Adapt semantic colors (error, success, warning, info):
Step 3.5 -- Shadow and Elevation Adaptation
Adjust shadows for dark mode:
Step 3.6 -- Produce Dark Palette
Generate the complete dark palette table:
| Token | Light Value | Dark Value | Contrast (dark bg) | WCAG |
|---|
============================================================ PHASE 4 -- THEME IMPLEMENTATION ============================================================
Step 4.1 -- Create Dark Theme Definition
Based on the detected framework:
Flutter:
ThemeData.dark() or ThemeData(brightness: Brightness.dark) in theme fileColorScheme with all slots filledThemeMode.system / ThemeMode.light / ThemeMode.dark in MaterialAppTailwind CSS:
darkMode: 'class' in tailwind.config (allows both manual and system control)dark: prefixed classes to all color-dependent elementsCSS Custom Properties:
:root[data-theme="dark"] or @media (prefers-color-scheme: dark)MUI:
createTheme({ palette: { mode: 'dark', ... } })Chakra UI:
styled-components/emotion:
Step 4.2 -- Create Theme Switching Mechanism
System Preference Detection:
@media (prefers-color-scheme: dark) -- automatic, no JS requiredwindow.matchMedia('(prefers-color-scheme: dark)') with change listenerMediaQuery.platformBrightnessOf(context)Manual Toggle:
Persistence:
localStorage.setItem('theme', 'dark') -- check on page load before renderSharedPreferences -- load theme mode before MaterialApp buildsnext-themes which handles SSR flash-of-wrong-theme<html> via script in <head> to prevent flashFlash of Wrong Theme Prevention:
<head> that reads localStorage and sets the theme classBEFORE the page renders -- this prevents the flash of light/dark mode
Step 4.3 -- Create Theme Provider
Set up the theme state management:
React/Next.js:
ThemeContext + useTheme hook
- theme: 'light' | 'dark' | 'system'
- resolvedTheme: 'light' | 'dark' (actual applied theme)
- setTheme(theme): update preference and persistFlutter:
ThemeNotifier (ChangeNotifier or Riverpod)
- themeMode: ThemeMode.system | ThemeMode.light | ThemeMode.dark
- toggleTheme(): cycle or set theme mode
- Persist via SharedPreferencesVue:
useTheme composable or Pinia store
- theme, resolvedTheme, setThemeCommit: "feat(theme): implement dark mode with system detection and manual toggle"
============================================================ PHASE 5 -- COLOR REFERENCE MIGRATION ============================================================
Update all color references in the codebase to use theme-aware tokens:
Step 5.1 -- Replace Hardcoded Colors
Scan every file for color references that are not theme-aware:
color: #333 -> color: var(--text-primary)text-gray-900 -> text-gray-900 dark:text-gray-100Colors.white -> Theme.of(context).colorScheme.surfaceStep 5.2 -- Handle Special Cases
Images with light backgrounds:
Shadows in dark mode:
Form inputs:
Third-party components:
Charts and data visualizations:
Commit: "fix(theme): migrate all color references to theme-aware tokens"
============================================================ PHASE 6 -- CONTRAST VERIFICATION ============================================================
Verify WCAG 2.1 AA contrast ratios for BOTH light and dark modes:
Step 6.1 -- Automated Contrast Check
For every foreground/background pair identified in Phase 2:
Calculate contrast ratio using the formula: (L1 + 0.05) / (L2 + 0.05) where L1 is lighter, L2 is darker relative luminance.
Requirements:
| Pair | Light Ratio | Light Pass | Dark Ratio | Dark Pass |
|---|---|---|---|---|
| body text on page bg | N:1 | YES/NO | N:1 | YES/NO |
Step 6.2 -- Fix Contrast Failures
For each failing pair:
Step 6.3 -- Focus Indicator Visibility
Verify focus indicators are visible in both modes:
Commit: "fix(a11y): ensure WCAG AA contrast ratios in both light and dark modes"
============================================================ PHASE 7 -- VERIFICATION ============================================================
Step 7.1 -- Static Analysis
Run the framework's analyzer/linter:
flutter analyzetsc --noEmitFix all errors and warnings.
Step 7.2 -- Theme Toggle Verification
Verify the complete theme switching flow:
============================================================ SELF-HEALING VALIDATION (max 3 iterations) ============================================================
After completing fixes, re-validate:
STOP when:
IF STILL FAILING after 3 iterations:
============================================================ OUTPUT ============================================================
## Dark Mode Implementation Complete
### Framework: [detected]
### Theme System: [mechanism]
### Toggle: [system + manual / system only / manual only]
### Persistence: [localStorage / SharedPreferences / cookies]
### Files Created/Modified
| File | Purpose |
|------|---------|
| [path] | [description] |
### Dark Palette
| Token | Light | Dark | Category |
|-------|-------|------|----------|
| background | #FFFFFF | #121212 | Surface |
| text-primary | #1A1A1A | #E0E0E0 | Text |
| primary | #3B82F6 | #60A5FA | Brand |
### Contrast Verification
| Pair | Light Ratio | Dark Ratio | Status |
|------|------------|-----------|--------|
| [pair] | N:1 | N:1 | PASS/FIXED |
### Summary
- Color tokens migrated: N
- Hardcoded colors replaced: N
- Contrast failures found: N (all fixed)
- Special cases handled: images(N), forms(N), third-party(N)============================================================ NEXT STEPS ============================================================
After dark mode implementation:
/ux to audit UX quality in both light and dark modes."/responsive to verify dark mode works at all breakpoints."/design-system to ensure dark tokens are part of the design system."/qa to verify dark mode did not break any functionality."============================================================ SELF-EVOLUTION TELEMETRY ============================================================
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
~/.claude/projects/skill-telemetry.md in that memory directoryEntry format:
### /dark-mode — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
============================================================ DO NOT ============================================================
filter: invert(1) as a dark mode strategy -- it breaks images, brand colors, and semantics.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.