Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.aspfox.com/llms.txt

Use this file to discover all available pages before exploring further.

How dark mode works

next-themes manages the dark class on the <html> element. Tailwind’s darkMode: 'class' strategy reads this class to activate dark-mode variants. The user’s preference (light / dark / system) is stored in localStorage and restored on every page load. The theme toggle in the top navigation bar cycles through three states: Light → Dark → System. “System” follows the OS preference. When a user changes their theme, the change takes effect immediately with no flash of unstyled content (FOUC). next-themes injects a small blocking script before the page renders that reads localStorage and applies the correct class before the first paint.

The CSS variable system

All colors are defined as CSS custom properties in index.css. Tailwind uses these variables through its theme configuration. Every component uses semantic variable names, not hardcoded colors.
/* index.css */
:root {
  --background: 0 0% 100%;
  --foreground: 222 47% 11%;
  --muted: 210 40% 96%;
  --muted-foreground: 215 16% 47%;
  --border: 214 32% 91%;
  --input: 214 32% 91%;
  --primary: 221 83% 47%;        /* #1A56DB */
  --primary-foreground: 0 0% 100%;
  --secondary: 210 40% 96%;
  --secondary-foreground: 222 47% 11%;
  --accent: 210 40% 96%;
  --accent-foreground: 222 47% 11%;
  --destructive: 0 84% 60%;
  --destructive-foreground: 0 0% 100%;
  --ring: 221 83% 47%;
  --radius: 0.5rem;
}

.dark {
  --background: 222 47% 4%;
  --foreground: 213 31% 91%;
  --muted: 223 47% 11%;
  --muted-foreground: 215 16% 57%;
  --border: 216 34% 17%;
  --input: 216 34% 17%;
  --primary: 221 83% 57%;
  --primary-foreground: 0 0% 100%;
  --secondary: 222 47% 11%;
  --secondary-foreground: 213 31% 91%;
  --accent: 216 34% 17%;
  --accent-foreground: 213 31% 91%;
  --destructive: 0 63% 50%;
  --destructive-foreground: 213 31% 91%;
  --ring: 221 83% 57%;
}
Tailwind maps these variables to utility classes via tailwind.config.ts:
theme: {
  extend: {
    colors: {
      background: 'hsl(var(--background))',
      foreground: 'hsl(var(--foreground))',
      muted: {
        DEFAULT: 'hsl(var(--muted))',
        foreground: 'hsl(var(--muted-foreground))',
      },
      primary: {
        DEFAULT: 'hsl(var(--primary))',
        foreground: 'hsl(var(--primary-foreground))',
      },
      // ...
    }
  }
}

Writing dark-mode-compatible components

Use semantic class names. The variable flips between light and dark values automatically — you do not write dark: variants for basic colors. Correct — semantic classes:
function ProjectCard({ name, description }: ProjectCardProps) {
  return (
    <div className="rounded-lg border border-border bg-background p-4">
      <h3 className="font-semibold text-foreground">{name}</h3>
      <p className="mt-1 text-sm text-muted-foreground">{description}</p>
    </div>
  );
}
Incorrect — hardcoded colors:
// This breaks dark mode. Never do this.
function ProjectCard({ name, description }: ProjectCardProps) {
  return (
    <div className="rounded-lg border border-gray-200 bg-white p-4">
      <h3 className="font-semibold text-gray-900">{name}</h3>
      <p className="mt-1 text-sm text-gray-500">{description}</p>
    </div>
  );
}
The semantic classes and their meaning:
ClassLightDarkUse for
bg-backgroundwhitenear-blackPage and card backgrounds
text-foregrounddark graynear-whitePrimary text
bg-mutedlight graydark graySubtle backgrounds, table rows
text-muted-foregroundmedium graylighter graySecondary text, placeholders
border-borderlight graydark grayAll borders and dividers
bg-primaryblueslightly lighter blueCTA buttons, active states
text-primary-foregroundwhitewhiteText on primary backgrounds
bg-destructivereddarker redDelete buttons, error states

Customizing the brand color

To change the primary color from AspFox blue to your brand color:
  1. Update --primary and --ring in :root in index.css
  2. Update --primary and --ring in .dark in index.css
  3. Update the primary color values in tailwind.config.ts to match
The new color propagates to every component using bg-primary, text-primary, border-primary, ring-primary, or text-primary-foreground. No other changes are needed. Example — changing to green:
:root {
  --primary: 142 76% 36%;     /* #16A34A green */
  --primary-foreground: 0 0% 100%;
  --ring: 142 76% 36%;
}

.dark {
  --primary: 142 69% 42%;
  --primary-foreground: 0 0% 100%;
  --ring: 142 69% 42%;
}