Add theme toggle, hero snippet, and reorganize homepage components

- Set up next-themes with a light/dark toggle in the header and move all
  sections onto theme tokens; dark mode stays pure black
- Replace the hero terminal line with the AI Elements Snippet component
- Restructure components into layout/, sections/, and shared/ with
  site-wide config in lib/site.ts

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Rami Bitar
2026-09-18 09:29:12 -04:00
co-authored by Claude Fable 5.1
parent a40edbffa9
commit 07a99b441c
28 changed files with 812 additions and 437 deletions
+43
View File
@@ -0,0 +1,43 @@
'use client';
import { useSyncExternalStore } from 'react';
import { RiMoonLine, RiSunLine } from '@remixicon/react';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
const emptySubscribe = () => () => {};
export function ThemeToggle() {
const mounted = useSyncExternalStore(
emptySubscribe,
() => true,
() => false,
);
const { resolvedTheme, setTheme } = useTheme();
const isDark = mounted && resolvedTheme === 'dark';
return (
<Button
type="button"
variant="ghost"
size="icon-lg"
aria-label={
mounted ? `Switch to ${isDark ? 'light' : 'dark'} theme` : 'Toggle theme'
}
className="text-foreground/70 hover:bg-foreground/5 hover:text-foreground"
onClick={() => setTheme(isDark ? 'light' : 'dark')}
>
{mounted ? (
isDark ? (
<RiSunLine className="size-4" />
) : (
<RiMoonLine className="size-4" />
)
) : (
<span className="size-4" aria-hidden="true" />
)}
</Button>
);
}