The Footer Icons That Vanished When the Card Turned White
Hardcoded white GitHub and Next.js icons disappeared the moment the light-mode footer card turned solid white. The fix: var(--foreground).
TL;DR
Fixing the footer card to solid white made hardcoded white icons vanish on white. Swapping every #ffffff in Footer.tsx for var(--foreground) lets icons adapt automatically across themes. Same for the neon gradient: added a denser light-mode variant so it stays visible on white.
Commit d6b73b2 made the footer card solid white in light mode. I checked, looked fine. But when I scrolled to the bottom, the GitHub icon and the Next.js badge in the footer were nowhere to be seen. Completely gone.
I inspected the element. The SVG tags were still there in the Footer component. But the color was white, on a white background.
First guess: maybe I deleted them during a refactor. Turns out, no. The icons had always been hardcoded white hex. The exact same color as the card background I had just fixed. Before commit d6b73b2, the footer card was transparent or dark — white icons looked normal. Once the background changed to solid white, white-on-white became invisible.
Fixing one part exposed a bug in another. The commit that made the card look good is what made the icons disappear. A small paradox that comes up a lot in theming work: a change that's locally correct can shift the failure to its neighbor, and the victim only shows up in a part of the page nobody touched.
Replacing Hardcoded White with Theme Variables
Every #ffffff reference in the fill and stroke of icons in Footer.tsx got replaced with var(--foreground). The foreground variable value is already defined in the global styles file per theme: black in light, white in dark. The icons automatically contrast against any background, with no conditional logic added in JavaScript. What I removed wasn't just a line of code, but an entire class of problems: components that carry their own theme assumptions inside them. As long as colors are written directly, every time the theme changes, every component holding that assumption becomes the next bug candidate.
CSS custom properties were designed exactly for cases like this. Values accessed through var() get reused across the whole document, and you only change the definition in one place [6]. It's not just about DRY, it's so elements adapt automatically without having to think "if light mode, the color is X, if dark mode, it's Y" in every component.
Neon Gradient That Fades on White
Second problem: text-gradient-tri in the footer. In dark mode, the green-blue-purple neon gradient looks vivid. In light mode, the same gradient looks washed out. Neon colors on white are like a neon sign in broad daylight — it's there, but you can't see it.
The fix: create a light variant in globals.css using a denser GitHub brand palette.
.light .text-gradient-tri {
background: linear-gradient(90deg, #1a7f37, #0969da, #8250df);
}
Green, blue, purple — three colors identical to GitHub's brand. Darker than the original neon, but that's exactly what's needed for contrast on a white background.
This per-theme variant pattern is already standard in Tailwind, bg-white dark:bg-gray-800 for example [7]. The difference is I use a manual .light class on the parent element, because theme switching in this project is handled by the dark class on the html element. Not a hack, but also not Tailwind's built-in mechanism.
I prefer this approach over adding a dark: variant to each element one by one, because in this project theme logic is already handled by CSS variables, not Tailwind utilities. The rule I took from this incident: colors that need to change with the theme get written as theme variables, hex literals are only for colors that are genuinely the same in every theme. I hit a similar case before when fixing an accent color that looked great in dark but faded in light.
The thing that got me thinking wasn't the fix — that was just swapping hex for a variable. What got me thinking was when the bug showed up. Not in dark mode. Not on the first deploy. It appeared when I fixed light mode in the previous commit.
If the icons had used var(--foreground) from the start instead of #ffffff, this problem would never have existed. One hardcoded hex literal whose detonation depends on what else changes in the codebase [7]. Theme-attached color values should use a variable that's also theme-attached; any hex literal in a theme-aware component is a time bomb that just hasn't found its detonator yet.