Tips & Tricks (Updated: 6/2/2026)

Claude Code Dark Mode Implementation Guide

Build dark mode with CSS variables, prefers-color-scheme, localStorage, hydration safety, and a11y checks.

Claude Code Dark Mode Implementation Guide

Start with the Product Risk

Implementing dark mode with Claude Code is not about asking the agent to “make it pretty.” The practical goal is to improve a real interface without breaking conversion, readability, accessibility, or mobile layout. A beginner can get a demo quickly, but production quality depends on boring details: empty states, keyboard focus, loading states, reduced motion, stale data, dark backgrounds, and the parts of the page that make money. This article walks through introducing dark mode as a small, safe change and then growing it into something that does not break later.

Read this together with claude code design system, claude code accessibility, claude code code review. Keep the official references open: Claude Code docs, MDN prefers-color-scheme, MDN color-scheme, WCAG contrast. The useful pattern is to ask Claude Code for a constrained implementation, then ask for a second review pass before merging.

Prompt Claude Code with Boundaries

Implement this improvement with the smallest safe change.
Respect existing components, tokens, and routing.
Cover use case behavior, pitfall risks, accessibility, mobile layout, and failure states.
Return copy-paste-ready code plus a review checklist.

This prompt keeps the agent away from random redesign. It tells Claude Code what to optimize, what not to touch, and what evidence should come back with the patch.

Use Case Checklist

  1. Marketing and article pages where the reader must notice the next step without feeling pushed.
  2. SaaS dashboards where status, loading, empty data, and errors must be understood quickly.
  3. Checkout, signup, and consultation flows where visual polish must never hide the primary action.
  4. Team review workflows where Claude Code should produce code and a checklist that another person can verify.

Implementation Example

:root {
  color-scheme: light;
  --color-page: #ffffff;
  --color-surface: #f8fafc;
  --color-text: #0f172a;
  --color-muted: #475569;
  --color-border: #dbe3ef;
  --color-link: #2563eb;
  --color-focus: #f59e0b;
}

[data-theme="dark"] {
  color-scheme: dark;
  --color-page: #0b1120;
  --color-surface: #111827;
  --color-text: #f8fafc;
  --color-muted: #cbd5e1;
  --color-border: #334155;
  --color-link: #93c5fd;
  --color-focus: #fbbf24;
}

body {
  background: var(--color-page);
  color: var(--color-text);
}

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
}
const storageKey = "theme";
const root = document.documentElement;
const stored = localStorage.getItem(storageKey);
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const theme = stored === "light" || stored === "dark" ? stored : prefersDark ? "dark" : "light";

root.dataset.theme = theme;
type Theme = "light" | "dark" | "system";

export function ThemeToggle({ value, onChange }: { value: Theme; onChange: (theme: Theme) => void }) {
  return (
    <fieldset aria-label="Theme">
      {(["light", "dark", "system"] as const).map((theme) => (
        <button
          key={theme}
          type="button"
          aria-pressed={value === theme}
          onClick={() => onChange(theme)}
        >
          {theme}
        </button>
      ))}
    </fieldset>
  );
}

Prevent the Theme Flash (FOUC)

The first pitfall you hit with dark mode is the “flash” where a bright screen appears for a split second before turning dark. In English it is called FOUC (Flash of Unstyled Content) or a theme flash. The cause is that you switch the theme with JavaScript only after the HTML has already rendered. If you wait for CSS or React to load before applying data-theme, the initial colors (usually the light ones) show during that wait.

The fix is to run a very small script that decides the theme synchronously, before the body (inside <head>). Look only at the saved preference and the device setting, and lock in data-theme before the screen is painted, like this:

<script>
  (function () {
    var stored = localStorage.getItem("theme");
    var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    var theme = stored === "light" || stored === "dark" ? stored : prefersDark ? "dark" : "light";
    document.documentElement.dataset.theme = theme;
  })();
</script>

The key is to keep this script tiny and let it run before the body is rendered. If you put heavy work or React initialization in here, the flash comes back. In Astro or Next.js, treat just this small script specially so you can settle the theme without waiting for framework hydration (the process where the browser attaches behavior to server-rendered HTML). Because the server cannot know the device setting, an easy flow is to respect the device preference on the first visit, then save the user’s choice to localStorage and prefer it from the next visit onward.

Make Contrast, Images, and Shadows Readable in the Dark

Inverting the colors does not finish dark mode. Contrast that was plenty on a light screen can fall short on a dark background. Check the contrast ratio between body text and background against the WCAG target of 4.5:1 or higher. Faint gray supporting text, placeholders, and disabled buttons in particular tend to become unreadable on a dark background.

Images and shadows also need adjustment. Logos and icons built assuming white lose their edges on a dark background. For transparent PNGs, lay down a background color or prepare a dark variant. Shadows that look effective as dark gray on a light background are nearly invisible on a dark one. Boundaries that relied on shadows should be re-expressed with a border such as --color-border, so the structure reads in either theme.

ElementLight assumptionDark adjustment
Supporting textFaint gray is enoughRaise lightness to secure contrast
Logos and iconsWhite background assumedAdd a background or swap for a dark variant
ShadowsDark gray expresses boundariesRe-express with a border
Status colorsVivid green and redLower saturation and add an icon

Finally, revisit charts, diagrams, and status colors (green for success, red for warning, and so on). Highly saturated colors glare and become hard to read on a dark background, so prepare slightly calmer versions for dark mode. Do not convey state with color alone; adding icons and labels gets the message across to readers in low-contrast environments or with color vision differences. When you have Claude Code review the work, have it specifically hunt for “spots where contrast drops on a dark background,” “images that assume white,” and “boundaries expressed with shadows,” and you will miss fewer issues.

Pitfall Checklist

  • Do not optimize for a screenshot only. Test the actual user path from landing page to CTA.
  • Do not depend on color alone. Keep labels, text alternatives, focus states, and keyboard behavior.
  • Do not introduce a heavy dependency before checking whether CSS and a small helper are enough.
  • Do not trust generated code until it has been tested with empty data, long labels, mobile width, and reloads.
  • Do not let Claude Code rewrite unrelated components. Ask for a file-by-file explanation of the diff.

Review and Verification

Ask Claude Code for a second pass that only reviews the change. The review should list changed files, risks, deleted assumptions, browser checks, and manual checks. Then open the page at 375px width and verify there is no horizontal overflow, the code block scrolls normally, the CTA is still visible, and assistive text is still present.

Monetization Angle

This topic is useful because it affects revenue surfaces: ads, product cards, consultation links, pricing tables, and lead forms. If your team wants a guided rollout using your own repository, the Claude Code training and consultation page explains how to turn this into a repeatable workflow.

Extra Review Notes

  • Compare before and after screenshots and check CTA, ads, article text, forms, and code blocks.
  • Ask Claude Code what can be removed, which names do not match the project, and which assumptions are risky.
  • Before deployment, verify mobile, desktop, keyboard navigation, slow network, empty data, and reload behavior.

Hands-on Verification Note

I tested this pattern as a small, reviewable change: one implementation pass, one review pass, and one mobile browser pass. The result was easier to review than a large redesign prompt, and the checklist caught layout and accessibility issues before deployment.

#Claude Code #dark mode #CSS variables #frontend #accessibility
Free

Free PDF: Claude Code Cheatsheet

Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.

We handle your data with care and never send spam.

Level up your Claude Code workflow

Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.

Masa

About the Author

Masa

Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.