# How the Foundation Build Phase Sets Up Fonts, Colors, and Global Styles in Next.js

> Discover how the foundation build phase in Next.js sets up fonts, colors, and global styles using CSS variables, OKLCH color tokens, and Tailwind utilities for a robust visual system.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-06-26

---

**The foundation build phase initializes the visual system by loading Google Fonts as CSS variables, declaring OKLCH color tokens in an `@theme inline` block, and applying global Tailwind utilities to the document root.**

The **ai-website-cloner-template** repository establishes a consistent design system through a three-step foundation process that runs before any UI components render. By combining Next.js font optimization, CSS custom properties, and Tailwind's theming capabilities, the template ensures every cloned website inherits a unified typographic and color baseline. This architectural approach separates design tokens from implementation details, making the codebase maintainable and themeable.

## Font Initialization with next/font/google

The foundation phase begins in [`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx) by importing the **Geist** font family from Google Fonts using Next.js's built-in optimization.

```typescript
import { Geist, Geist_Mono } from "next/font/google";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

```

The `variable` option instructs Next.js to expose each font as a CSS custom property rather than injecting standard `@font-face` rules. These variables attach to the `<html>` element through the className prop:

```tsx
<html className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}>

```

This technique makes the **Geist Sans** and **Geist Mono** typefaces globally available without additional network requests or layout shift, as the fonts are self-hosted and preloaded by the framework.

## Design Token Architecture in globals.css

The second step occurs in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css), where the foundation declares a comprehensive set of design tokens using modern CSS features. The file begins with standard Tailwind imports, then defines an `@theme inline` block that maps high-level abstractions to concrete values.

```css
@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;
  --radius-lg: var(--radius);
  --color-border: var(--border);
}

```

Concrete values are supplied in the `:root` block using **OKLCH** color notation for perceptual uniformity:

```css
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --border: oklch(0.922 0 0);
  --radius: 0.625rem;
}

```

A dark mode variant overrides these values under the `.dark` selector:

```css
.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.985 0 0);
}

```

This token architecture decouples component styling from specific color values, allowing the entire interface to shift between light and dark modes by toggling a single CSS class.

## Global Style Application with Tailwind

The final foundation step applies these tokens to the document root using Tailwind's `@layer base` directive. This ensures every element inherits the design system automatically.

```css
@layer base {
  * { @apply border-border outline-ring/50; }
  body { @apply bg-background text-foreground; }
  html { @apply font-sans; }
}

```

The `@apply` directives resolve to the CSS variables defined in the previous step:

- `bg-background` maps to `--background` (OKLCH white in light mode, near-black in dark mode)
- `text-foreground` maps to `--foreground` (high-contrast text colors)
- `font-sans` resolves to the Geist font family loaded in [`layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/layout.tsx)
- `border-border` applies the standardized border color token

Additionally, the foundation imports `tw-animate-css` and Shadcn UI styles to support motion and component-specific theming without conflicting with the global baseline.

## Summary

- **Font Loading**: The foundation phase uses `next/font/google` in [`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx) to load Geist fonts as CSS variables (`--font-geist-sans`, `--font-geist-mono`), ensuring zero layout shift and global availability.
- **Token Declaration**: [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css) defines design tokens in an `@theme inline` block using OKLCH color values for perceptually uniform theming, with automatic dark mode support via the `.dark` class.
- **Global Application**: The `@layer base` directive applies background, text, and font-family utilities to the `<html>` and `<body>` elements, establishing the visual baseline for all child components.
- **Component Integration**: Shadcn UI components and custom elements consume these tokens through standard Tailwind classes (e.g., `bg-primary`, `text-foreground`), maintaining consistency across the application.

## Frequently Asked Questions

### How does the foundation handle dark mode switching?

The foundation implements dark mode through CSS custom properties defined in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css). When the `.dark` class is applied to the `<html>` element—typically via a theme toggle component—the browser automatically switches from `:root` to `.dark` variable values. This approach requires no JavaScript runtime for style calculations; the browser's CSS engine handles the transition instantly.

### Why does the template use OKLCH instead of HEX or RGB?

The foundation uses **OKLCH** (OK Lightness, Chroma, Hue) in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css) because it provides perceptual uniformity, meaning color adjustments maintain consistent visual contrast across different hues. Unlike HEX or RGB, which can appear to shift brightness when modifying saturation, OKLCH ensures that the `--primary`, `--background`, and `--foreground` tokens remain accessible and visually balanced in both light and dark contexts.

### Can I replace Geist with a different font family?

Yes, you can modify the font configuration in [`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx) by importing a different font from `next/font/google` or `next/font/local`. Change the `variable` names to match your new font (e.g., `--font-inter`) and update the corresponding `--font-sans` and `--font-mono` declarations in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css) to point to your new CSS variables. The foundation architecture remains intact as long as the CSS variable names in the layout match the references in the theme configuration.

### Where should I add custom color tokens to the foundation?

Add custom color tokens to the `:root` block in [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css) using the `--color-name` convention, then map them in the `@theme inline` block using `--color-token-name: var(--color-name)`. For example, adding `--brand: oklch(0.6 0.2 250)` to `:root` and `--color-brand: var(--brand)` to `@theme inline` makes the `bg-brand` and `text-brand` utilities available throughout your Tailwind configuration.