Skip to content

Commit 018e129

Browse files
Ajit Pratap Singhclaude
authored andcommitted
fix(website): comprehensive light mode CSS override layer
The light mode was broken because all 300+ component class strings use hardcoded dark-mode Tailwind utilities (text-white, text-zinc-300, bg-white/[0.06], border-white/[0.06]). The CSS custom property overrides were useless since components don't reference them. Fix: add a comprehensive html.light CSS layer that overrides every hardcoded dark-mode class — text colors, backgrounds, borders, glass cards, buttons, navbar (including dynamic rgba bg), footer, search modal, code blocks (kept dark per convention), accent colors, badges, bar charts, and section borders. Also fix Navbar to detect light class via MutationObserver and swap the hardcoded rgba(9,9,11) bg to rgba(250,251,252) in light mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3192055 commit 018e129

2 files changed

Lines changed: 235 additions & 26 deletions

File tree

website/src/app/globals.css

Lines changed: 225 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -107,55 +107,255 @@ body {
107107
--tw-prose-pre-bg: #12121A;
108108
}
109109

110-
/* Light mode overrides */
110+
/* ==========================================================================
111+
LIGHT MODE — Comprehensive override layer
112+
All components use hardcoded dark-mode Tailwind classes (text-white,
113+
text-zinc-300, bg-white/[0.06], border-white/[0.06], etc.).
114+
We override them here to avoid touching 300+ JSX class strings.
115+
========================================================================== */
116+
117+
/* --- Design token overrides --- */
118+
html.light {
119+
--color-primary: #FAFBFC;
120+
--color-surface: #FFFFFF;
121+
--color-elevated: #F3F4F6;
122+
--color-bg-deep: #FAFBFC;
123+
--color-bg-surface: #FFFFFF;
124+
--color-bg-elevated: #F3F4F6;
125+
--color-bg-hover: #E5E7EB;
126+
--color-text-primary: #1A1A2E;
127+
--color-text-secondary: #4B5563;
128+
--color-text-muted: #9CA3AF;
129+
--color-border-default: rgba(0, 0, 0, 0.08);
130+
--color-border-hover: rgba(0, 0, 0, 0.15);
131+
}
132+
133+
/* --- Body --- */
111134
html.light body {
112135
background-color: #FAFBFC;
113136
color: #1A1A2E;
114137
}
115138

139+
/* --- Global text color overrides --- */
140+
html.light .text-white { color: #1A1A2E; }
141+
html.light .text-zinc-100 { color: #1F2937; }
142+
html.light .text-zinc-200 { color: #374151; }
143+
html.light .text-zinc-300 { color: #4B5563; }
144+
html.light .text-zinc-400 { color: #6B7280; }
145+
html.light .text-zinc-500 { color: #6B7280; }
146+
html.light .text-indigo-300 { color: #4338CA; }
147+
html.light .text-emerald-400 { color: #059669; }
148+
149+
/* --- Heading gradient: dark-to-dark on light bg --- */
150+
html.light .bg-gradient-to-r.from-white.via-zinc-200.to-zinc-400 {
151+
--tw-gradient-from: #0F172A;
152+
--tw-gradient-via: #1E293B;
153+
--tw-gradient-to: #475569;
154+
}
155+
156+
/* --- Glass cards --- */
116157
html.light .glass {
117158
background: rgba(255, 255, 255, 0.80);
118-
border: 1px solid rgba(0, 0, 0, 0.08);
119-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
159+
border: 1px solid rgba(0, 0, 0, 0.10);
160+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8);
120161
}
121-
122162
html.light .glass-hover:hover {
123-
background: rgba(255, 255, 255, 0.90);
163+
background: rgba(255, 255, 255, 0.95);
164+
border-color: rgba(0, 0, 0, 0.15);
165+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.9);
166+
}
167+
168+
/* --- Borders (white/opacity → black/opacity) --- */
169+
html.light [class*="border-white\\/"] { border-color: rgba(0, 0, 0, 0.10); }
170+
html.light [class*="divide-white\\/"] { --tw-divide-opacity: 1; border-color: rgba(0, 0, 0, 0.08); }
171+
172+
/* --- Backgrounds (white/opacity → light surface) --- */
173+
html.light [class*="bg-white\\/\\[0\\.0"] { background-color: rgba(0, 0, 0, 0.03); }
174+
html.light [class*="bg-white\\/\\[0\\.1"] { background-color: rgba(0, 0, 0, 0.06); }
175+
html.light [class*="bg-white\\/5"] { background-color: rgba(0, 0, 0, 0.03); }
176+
html.light [class*="bg-white\\/10"] { background-color: rgba(0, 0, 0, 0.05); }
177+
178+
/* --- Primary bg (used as bg-primary on mobile menu, etc.) --- */
179+
html.light .bg-primary { background-color: #FAFBFC; }
180+
181+
/* --- Navbar --- */
182+
html.light header[class*="border-b"] { border-color: rgba(0, 0, 0, 0.08); }
183+
html.light nav .text-lg.font-semibold { color: #1A1A2E; }
184+
185+
/* Navbar link hover */
186+
html.light [class*="hover\\:bg-white\\/\\[0\\.04\\]"]:hover { background-color: rgba(0, 0, 0, 0.04); }
187+
188+
/* Search button */
189+
html.light button[aria-label="Search documentation"],
190+
html.light button[aria-label="Search documentation"]:hover {
191+
background-color: rgba(0, 0, 0, 0.03);
124192
border-color: rgba(0, 0, 0, 0.12);
125-
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08),
126-
inset 0 1px 0 rgba(255, 255, 255, 0.6);
193+
color: #6B7280;
194+
}
195+
html.light button[aria-label="Search documentation"] kbd {
196+
color: #9CA3AF;
197+
border-color: rgba(0, 0, 0, 0.10);
198+
background-color: rgba(0, 0, 0, 0.03);
199+
}
200+
201+
/* GitHub icon */
202+
html.light a[aria-label="GitHub"],
203+
html.light a[aria-label="GitHub"]:hover { color: #374151; }
204+
205+
/* Hamburger bars */
206+
html.light .bg-zinc-300 { background-color: #4B5563; }
207+
208+
/* --- Buttons --- */
209+
/* Primary button stays the same (white bg dark text) — but invert for light mode */
210+
html.light .bg-white.text-zinc-950 {
211+
background-color: #1A1A2E;
212+
color: #FFFFFF;
213+
}
214+
html.light .bg-white.text-zinc-950:hover {
215+
background-color: #2D2D44;
216+
}
217+
218+
/* Ghost button */
219+
html.light [class*="bg-white\\/\\[0\\.06\\]"][class*="border"][class*="text-zinc-300"] {
220+
background-color: rgba(0, 0, 0, 0.04);
221+
border-color: rgba(0, 0, 0, 0.12);
222+
color: #374151;
223+
}
224+
html.light [class*="bg-white\\/\\[0\\.06\\]"][class*="border"][class*="text-zinc-300"]:hover {
225+
background-color: rgba(0, 0, 0, 0.08);
226+
color: #1A1A2E;
227+
}
228+
229+
/* GitHub star button */
230+
html.light a[class*="bg-white\\/5"][class*="border-white\\/10"] {
231+
background-color: rgba(0, 0, 0, 0.03);
232+
border-color: rgba(0, 0, 0, 0.10);
233+
color: #374151;
234+
}
235+
html.light a[class*="bg-white\\/5"][class*="border-white\\/10"]:hover {
236+
background-color: rgba(0, 0, 0, 0.06);
237+
}
238+
239+
/* --- Version badge --- */
240+
html.light .bg-accent-indigo\\/10 {
241+
background-color: rgba(99, 102, 241, 0.08);
242+
}
243+
html.light .border-accent-indigo\\/30 {
244+
border-color: rgba(99, 102, 241, 0.25);
245+
}
246+
247+
/* --- Hero background gradients: hide on light mode --- */
248+
html.light section > [aria-hidden="true"] { opacity: 0.3; }
249+
250+
/* --- Code blocks / pre elements --- */
251+
html.light pre[class*="font-mono"] {
252+
background-color: #1E1E2E;
253+
color: #D4D4D8;
254+
}
255+
html.light code { color: inherit; }
256+
257+
/* Code in MiniPlayground, hero, etc. — keep dark code blocks */
258+
html.light .font-mono[class*="text-zinc-300"],
259+
html.light .font-mono[class*="text-zinc-400"] {
260+
color: #D4D4D8;
127261
}
128262

129-
html.light ::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.12); }
130-
html.light ::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.2); }
263+
/* Keep code blocks dark in light mode (standard convention) */
264+
html.light pre, html.light textarea[class*="font-mono"] {
265+
background-color: #1E1E2E !important;
266+
color: #D4D4D8 !important;
267+
}
268+
269+
/* Accent colors on code stay vivid */
270+
html.light pre .text-accent-green,
271+
html.light pre .text-accent-orange,
272+
html.light textarea .text-accent-green,
273+
html.light textarea .text-accent-orange {
274+
color: inherit;
275+
}
276+
277+
/* --- Stats / accent-colored numbers --- */
278+
html.light .text-accent-orange { color: #EA580C; }
279+
html.light .text-accent-green { color: #16A34A; }
280+
html.light .text-accent-indigo { color: #4F46E5; }
281+
html.light .text-accent-purple { color: #7C3AED; }
282+
283+
/* --- Section borders --- */
284+
html.light section[class*="border-t"] { border-color: rgba(0, 0, 0, 0.06); }
285+
html.light [class*="border-b"][class*="border-white"] { border-color: rgba(0, 0, 0, 0.06); }
131286

287+
/* --- Feature card icon tinted backgrounds --- */
288+
html.light [class*="bg-accent-purple\\/10"] { background-color: rgba(124, 58, 237, 0.08); }
289+
html.light [class*="bg-accent-green\\/10"] { background-color: rgba(22, 163, 74, 0.08); }
290+
html.light [class*="bg-accent-orange\\/10"] { background-color: rgba(234, 88, 12, 0.08); }
291+
html.light [class*="bg-accent-indigo\\/10"] { background-color: rgba(79, 70, 229, 0.08); }
292+
html.light [class*="bg-red-500\\/10"] { background-color: rgba(220, 38, 38, 0.08); }
293+
html.light [class*="bg-cyan-500\\/10"] { background-color: rgba(6, 182, 212, 0.08); }
294+
295+
/* --- Footer --- */
296+
html.light footer { border-color: rgba(0, 0, 0, 0.06); }
297+
html.light footer .text-white { color: #1A1A2E; }
298+
html.light footer .text-zinc-300 { color: #4B5563; }
299+
html.light footer .text-zinc-300:hover { color: #1F2937; }
300+
html.light footer .text-sm.text-zinc-300 { color: #6B7280; }
301+
302+
/* --- Scrollbar --- */
303+
html.light ::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.12); }
304+
html.light ::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.2); }
305+
306+
/* --- Prose / docs --- */
132307
html.light .prose-dark {
133-
--tw-prose-body: rgba(0,0,0,0.75);
308+
--tw-prose-body: rgba(0, 0, 0, 0.75);
134309
--tw-prose-headings: #1A1A2E;
135310
--tw-prose-links: #4F46E5;
136311
--tw-prose-code: #1A1A2E;
137-
--tw-prose-pre-bg: #F3F4F6;
312+
--tw-prose-pre-bg: #1E1E2E;
138313
}
139314

140-
/* Light mode design token overrides */
141-
html.light {
142-
--color-primary: #FAFBFC;
143-
--color-surface: #FFFFFF;
144-
--color-elevated: #F3F4F6;
315+
/* --- ThemeToggle button --- */
316+
html.light button[aria-label*="Switch to"] {
317+
color: #4B5563;
318+
}
319+
html.light button[aria-label*="Switch to"]:hover {
320+
color: #1A1A2E;
321+
background-color: rgba(0, 0, 0, 0.04);
322+
}
145323

146-
--color-bg-deep: #FAFBFC;
147-
--color-bg-surface: #FFFFFF;
148-
--color-bg-elevated: #F3F4F6;
149-
--color-bg-hover: #E5E7EB;
324+
/* --- Comparison page / bar charts --- */
325+
html.light .bg-zinc-700 { background-color: #D1D5DB; }
326+
html.light .from-green-500 { --tw-gradient-from: #22C55E; }
327+
html.light .to-emerald-400 { --tw-gradient-to: #10B981; }
150328

151-
--color-text-primary: #1A1A2E;
152-
--color-text-secondary: #4B5563;
153-
--color-text-muted: #9CA3AF;
329+
/* --- Benchmarks / Compare table highlights --- */
330+
html.light [class*="bg-accent-indigo\\/5"],
331+
html.light [class*="bg-indigo-500\\/5"] {
332+
background-color: rgba(79, 70, 229, 0.05);
333+
}
154334

155-
--color-border-default: rgba(0, 0, 0, 0.08);
156-
--color-border-hover: rgba(0, 0, 0, 0.15);
335+
/* --- Dialects badge colors remain vibrant --- */
336+
html.light .bg-green-500\\/10 { background-color: rgba(22, 163, 74, 0.10); }
337+
html.light .text-green-400 { color: #16A34A; }
338+
html.light .bg-blue-500\\/10 { background-color: rgba(59, 130, 246, 0.10); }
339+
html.light .text-blue-400 { color: #2563EB; }
340+
html.light .bg-yellow-500\\/10 { background-color: rgba(234, 179, 8, 0.10); }
341+
html.light .text-yellow-400 { color: #B45309; }
342+
html.light .bg-zinc-500\\/10 { background-color: rgba(107, 114, 128, 0.10); }
343+
344+
/* --- Search modal --- */
345+
html.light [class*="bg-zinc-950\\/"] {
346+
background-color: rgba(0, 0, 0, 0.4);
347+
}
348+
html.light [class*="bg-zinc-900"] {
349+
background-color: #FFFFFF;
157350
}
158351

352+
/* --- Shadow adjustments --- */
353+
html.light .shadow-2xl { --tw-shadow-color: rgba(0, 0, 0, 0.08); }
354+
html.light [class*="shadow-indigo-500\\/"] { --tw-shadow-color: rgba(99, 102, 241, 0.06); }
355+
356+
/* --- Gradient accent line in footer --- */
357+
html.light .opacity-40[class*="bg-gradient"] { opacity: 0.2; }
358+
159359
/* Respect prefers-reduced-motion for all animations */
160360
@media (prefers-reduced-motion: reduce) {
161361
*, *::before, *::after {

website/src/components/layout/Navbar.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,18 @@ export function Navbar() {
4444
const pathname = usePathname();
4545
const { open: searchOpen, setOpen: setSearchOpen } = useSearchShortcut();
4646
const { scrollY } = useScroll();
47+
const [isLight, setIsLight] = useState(false);
48+
useEffect(() => {
49+
const check = () => setIsLight(document.documentElement.classList.contains('light'));
50+
check();
51+
const observer = new MutationObserver(check);
52+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
53+
return () => observer.disconnect();
54+
}, []);
55+
4756
const bgOpacity = useTransform(scrollY, [0, 100], [0.6, 0.9]);
4857
const blurAmount = useTransform(scrollY, [0, 100], [8, 16]);
49-
const bgColor = useTransform(bgOpacity, (v) => `rgba(9, 9, 11, ${v})`);
58+
const bgColor = useTransform(bgOpacity, (v) => isLight ? `rgba(250, 251, 252, ${v})` : `rgba(9, 9, 11, ${v})`);
5059
const blur = useTransform(blurAmount, (v) => `blur(${v}px)`);
5160

5261
// Close mobile menu on resize

0 commit comments

Comments
 (0)