Typography and color
Add a dark color scheme
Use dark variants to define deliberate alternate colors instead of mechanically inverting the interface.
8 minute lesson
Add a dark variant beside the default:
<div class="bg-white text-gray-950 dark:bg-gray-950 dark:text-white">...</div>
By default, Tailwind’s dark: variant follows the browser’s prefers-color-scheme media feature. The base utility remains the light/default decision; the variant overrides the properties that genuinely change.
For a manual theme switch in Tailwind v4, define the variant against a class or data attribute:
@import "tailwindcss";
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
Now an ancestor activates it:
<html data-theme="dark">...</html>
A three-way control—light, dark, system—must store the explicit choice and observe the system preference when “system” is selected. Apply the initial attribute before first paint when possible so the page does not flash the wrong theme.
Review every semantic color: page and elevated surfaces, normal and muted text, borders, links, controls, focus indicators, success, warnings, errors, code, shadows, and images. Dark mode is not a mechanical inversion. Pure black/white everywhere can create glare, while weak gray-on-gray combinations can fail contrast.
Set an appropriate CSS color-scheme as well so browser-provided controls, form widgets, and scrollbars can match. Tailwind includes color-scheme utilities, but choose them to match the theme actually active.
Theme tokens reduce duplication. If every component repeats the same light/dark palette pair, semantic surface and text variables may express the system more clearly.
Your action is to implement light, dark, and system choices for one card. Reload before and after changing the system theme, watch for flash, and audit every interactive state in both schemes.
Lesson completed