dark-mode-implementation
Dark Mode Implementation
Coverage
A dark mode implementation handles five concerns: detecting the user's preference (system, explicit choice, persisted choice), applying the right theme before first paint, propagating theme changes at runtime, swapping color-sensitive assets, and updating browser-chrome hints. Each has well-defined web platform primitives.
Detection uses the prefers-color-scheme media query (window.matchMedia('(prefers-color-scheme: dark)')), which reflects the operating system or browser-level preference. Most products offer three user choices — System, Light, Dark — where System defers to the media query and the other two override it. The chosen mode is persisted (localStorage or a cookie) and read on every load. The CSS color-scheme property tells the user agent which schemes a page supports, enabling correct rendering of native form controls, scrollbars, and the default page background; declare color-scheme: light dark on :root for sites that support both.
Flash-of-incorrect-theme (sometimes called FOUC for theme) occurs when the browser paints the light default before the persisted dark preference is applied. The fix is a small, blocking inline script in that reads the persisted preference and sets a class or data attribute on synchronously before stylesheets resolve. Frameworks with server-side rendering must serialize the resolved theme into the HTML response, often by reading a cookie on the server.
The CSS Color Module Level 5 light-dark() function (light-dark(white, black)) lets a property declare both schemes inline and the user agent picks based on color-scheme. This is supported in current browsers and reduces the boilerplate of paired custom properties for simple cases; for token-driven systems, paired :root and [data-theme="dark"] custom property assignments remain the typical approach.
Asset handling covers three categories. Raster images that have brand-color elements need dark variants delivered via with (the markup-driven approach) or via CSS background-image swapping. SVG illustrations can use currentColor or CSS custom properties for fill/stroke and update automatically. Favicons can declare a dark variant via . Embedded videos and iframes (YouTube, Maps) often have their own theme parameter that needs to be passed via URL.
Browser chrome hints include the meta theme-color tag (), which sets the address bar color on mobile browsers, the Safari toolbar tint, and the PWA splash screen. Pair it with a light variant via media= so the chrome matches the active theme. Apple-specific apple-mobile-web-app-status-bar-style is now overridden by theme-color on supported versions.
Philosophy
Dark mode is not a re-skin; it is a parallel design surface. Image contrast, shadow strategy (shadows on dark backgrounds work differently — often replaced with subtle borders or elevated background tints), focus ring visibility, and chart palettes all need attention. Treating dark mode as a CSS-only change produces a dark mode that technically works and feels half-finished.
The user's explicit choice overrides the system. A user who has toggled to Dark on your site once expects Dark on the next visit regardless of what their OS is doing. Persistence is not optional, and a System option is a separate, third state from "no preference saved."
More from jacob-balslev/skills
layout-composition
Use when deciding responsive page or screen structure: section order, scan pattern, grid/flex composition, breakpoints, viewport hierarchy, responsive media, and density. Do NOT use for user-goal decomposition (use `task-analysis`), navigation taxonomy (use `information-architecture`), visual polish (use `visual-design-foundations`), or component/token contracts (use `design-system-architecture`).
8context-graph
Use when designing or auditing the multi-graph context architecture of an AI-coding workspace: skill graph, document routing graph, memory index, script registry, and the cross-graph edges between them. Covers edge typing, orphan detection, connectivity health, deterministic graph synthesis signals, change-propagation checks, and drift or hub-and-spoke anti-patterns. Do NOT use for authoring one SKILL.md (use `skill-scaffold`), validating one skill (use `graph-audit`), live routing decisions (use `skill-router`), context-window budgeting (use `context-window`), or session load/drop choices (use `context-management`).
8visual-design-foundations
Use when designing or auditing visual craft: color palette, typography, spacing, elevation, rhythm, density, visual hierarchy, brand fit, contrast intent, and motion feel. Do NOT use for sign-system meaning (use `semiotics`), token/component architecture (use `design-system-architecture`), responsive structure (use `layout-composition`), or accessibility compliance (use `a11y`).
7project-knowledge-extraction
Use when extracting durable project knowledge from code, docs, issues, incidents, reports, screenshots, or conversations into reusable context such as skills, ADRs, glossaries, context docs, or memory. Do NOT use for writing a new skill contract (use `skill-scaffold`), maintaining library tooling (use `skill-infrastructure`), or generic documentation polish (use `documentation`).
6problem-framing
Use when a team is converging on solutions before agreeing on the problem, when a brief reads as a feature request, when symptoms and root needs are tangled, or when assumptions need surfacing before design work proceeds. Do NOT use for code-level bug triage, runtime failure diagnosis, or root-cause analysis of system errors — those are engineering investigation tasks, not design problem framing.
6ai-native-development
Use when reasoning about agent autonomy levels, designing auto-improve loops, evaluating AI-generated code quality, or measuring agent productivity in an LLM-assisted codebase. Covers Karpathy's three eras of software (1.0 explicit / 2.0 learned / 3.0 natural-language), the vibe-coding-vs-agentic-engineering distinction, the 0–5 autonomy slider with task-type recommendations, the one-asset / one-metric / one-time-box AutoResearch loop, Software 3.0 productivity metrics, and the documented quality regressions of ungated AI-generated code (the 'vibe hangover'). Do NOT use for choosing a specific autonomy-loop topology (use `agent-engineering`), for the per-prompt authoring discipline (use `prompt-craft`), or for reviewing the AI-generated code that comes out of a Software 3.0 workflow (use `code-review`).
6