# Customization

URL: https://whitepaper.designervenkat.online/docs/ui-ux/customization
Markdown: https://whitepaper.designervenkat.online/llms.mdx/docs/ui-ux/customization
Site: White Papers - Designer Venkat
Author: Designer Venkat
Language: en

Override colors, fonts, layout, and components — most changes are a single CSS variable away.





Fumadocs is designed to look reasonable out of the box and bend to your brand without a fork. Most customization happens in two files: `app/globals.css` for design tokens, and `lib/layout.shared.ts` for structural options.

## Color tokens [#color-tokens]

Every color in the UI is driven by a CSS variable. The full set:

| Variable                        | Purpose                                   |
| ------------------------------- | ----------------------------------------- |
| `--color-fd-background`         | Page background                           |
| `--color-fd-foreground`         | Body text                                 |
| `--color-fd-primary`            | Accent — TOC active state, links on hover |
| `--color-fd-primary-foreground` | Text on primary backgrounds               |
| `--color-fd-muted`              | Secondary surfaces (sidebar, code blocks) |
| `--color-fd-muted-foreground`   | Secondary text (descriptions, captions)   |
| `--color-fd-border`             | All borders and dividers                  |
| `--color-fd-card`               | Card and callout backgrounds              |
| `--color-fd-accent`             | Hover state for nav items                 |

Override any of them in `app/globals.css`:

```css title="app/globals.css"
:root {
  --brand-blue-300: #93c5fd;
  --brand-sky-500: #0ea5e9;
  --gradient-primary: linear-gradient(
    to bottom,
    var(--brand-blue-300),
    var(--brand-sky-500)
  );
  --color-fd-primary: var(--brand-sky-500);
}
```

<Callout type="info" title="OKLCH 101">
  `oklch(L C H)` — Lightness (0–1), Chroma (0–0.4ish), Hue (0–360°). L=0.5 reads
  as the same brightness regardless of hue. For a light theme, set L between
  0.85 and 0.95; for dark, 0.15 to 0.30.
</Callout>

## Fonts [#fonts]

The site uses Geist by default. To swap, edit `app/layout.tsx`:

<Tabs items="['Geist (default)', 'Inter', 'Custom font']">
  <Tab value="Geist (default)">
    ```tsx
    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"] });

    ```
  </Tab>

  <Tab value="Inter">
    ```tsx
    import { Inter, JetBrains_Mono } from "next/font/google";

    const sans = Inter({ variable: "--font-geist-sans", subsets: ["latin"] });
    const mono = JetBrains_Mono({ variable: "--font-geist-mono", subsets: ["latin"] });
    ```

    Keep the variable names (`--font-geist-sans`, `--font-geist-mono`) — globals.css references them.
  </Tab>

  <Tab value="Custom font">
    ```tsx
    import localFont from "next/font/local";

    const customSans = localFont({
    src: "../public/fonts/MyFont.woff2",
    variable: "--font-geist-sans",
    });

    ```
  </Tab>
</Tabs>

## Layout structure [#layout-structure]

`lib/layout.shared.ts` exposes the props passed into Fumadocs' `DocsLayout`:

```ts title="lib/layout.shared.ts"
export const baseOptions = {
  nav: {
    title: "nxt-whitepapers",
    url: "/",
  },
  links: [
    { text: "Docs", url: "/docs" },
    { text: "GitHub", url: "https://github.com/your-org/nxt-whitepapers" },
  ],
  githubUrl: "https://github.com/your-org/nxt-whitepapers",
};
```

The `links` array shows in the top-right of the docs header. The `githubUrl` adds a small GitHub icon in the bottom-left of the sidebar.

## Sidebar sections [#sidebar-sections]

Group pages by editing `content/docs/meta.json`. The `pages` array supports three entry types:

* **A page slug** — `"installation"` → renders the page in order
* **A folder name** — `"coding-tutorials"` → renders the folder's contents (nested)
* **A separator** — `"---Label---"` → renders a section heading

Example:

```json title="content/docs/meta.json"
{
  "pages": [
    "index",
    "ai-machine-learning",
    "coding-tutorials",
    "security",
    "ui-ux",
    "performances"
  ]
}
```

## Overriding the page component [#overriding-the-page-component]

If you need to add custom content above or below every page — a banner, an author bio, related links — edit `app/docs/[[...slug]]/page.tsx`:

```tsx title="app/docs/[[...slug]]/page.tsx"
<DocsBody>
  <MDX components={{ ...defaultMdxComponents }} />
  <RelatedPapers slug={page.slugs} />
  <Feedback onSendAction={...} />
</DocsBody>
```

Anything inside `<DocsBody>` inherits the typography styles. Anything outside it doesn't.

<Callout type="warn" title="Don't fork the layout">
  It's tempting to copy `DocsLayout` from `node_modules` and modify it. Don't —
  you lose upstream improvements and bug fixes. Override via props (`sidebar`,
  `nav`, `containerProps`) instead. Fumadocs exposes most of what you'd want to
  change.
</Callout>

## Dark mode [#dark-mode]

Fumadocs ships with a theme toggle in the sidebar footer. The toggle writes to `localStorage` and adds a `dark` class to `<html>`. To force a default:

```ts title="app/layout.tsx"
<RootProvider theme={{ defaultTheme: "dark", enableSystem: false }}>
  {children}
</RootProvider>
```

Setting `enableSystem: false` ignores the user's OS preference and uses `defaultTheme` for first-time visitors only.
