Theme
Customize the visual appearance of your Grafos site with CSS variables, dark mode, fonts, and the Tailwind preset.
Grafos uses Tailwind CSS v4 with CSS custom properties for theming. You can customize colors, fonts, dark mode behavior, and more without touching component code.
CSS Variables
All visual tokens in Grafos are defined as CSS custom properties. Override them in your global CSS to change the look of your site:
:root {
--grafos-bg: #ffffff;
--grafos-bg-secondary: #f9fafb;
--grafos-fg: #111827;
--grafos-fg-muted: #6b7280;
--grafos-accent: #6366f1;
--grafos-accent-fg: #ffffff;
--grafos-border: #e5e7eb;
--grafos-radius: 0.5rem;
--grafos-sidebar-width: 280px;
--grafos-toc-width: 240px;
}
The dark mode palette is defined under a .dark class:
.dark {
--grafos-bg: #0a0a0a;
--grafos-bg-secondary: #171717;
--grafos-fg: #f5f5f5;
--grafos-fg-muted: #a3a3a3;
--grafos-accent: #818cf8;
--grafos-accent-fg: #0a0a0a;
--grafos-border: #262626;
}
You can override any subset of these variables. Values you do not override will use the Grafos defaults.
The easiest way to make a Grafos site feel like your own is to change --grafos-accent to your brand color. This single change updates links, buttons, graph highlights, search results, and the active TOC indicator.
Dark Mode
Grafos is dark by default. The default mode is controlled in configuration:
theme: {
defaultMode: 'dark', // 'dark' | 'light'
}
The current mode is persisted in localStorage under the key grafos-theme. When a user toggles the mode, it is saved and restored on subsequent visits.
To prevent a flash of the wrong theme on page load, Grafos injects a small inline script in the <head> that reads localStorage and applies the .dark class before the page renders. This runs synchronously before any CSS or JavaScript loads, so there is no visible flash.
The toggle component reads and writes to the same localStorage key. You can place it anywhere in your layout:
import { ThemeToggle } from 'grafos/components'
export default function Header() {
return (
<header>
<ThemeToggle />
</header>
)
}
Fonts
Grafos uses the system font stack by default for both sans-serif and monospace text. You can override this in the config:
theme: {
fonts: {
sans: 'Inter, sans-serif',
mono: 'JetBrains Mono, monospace',
},
}
The font values are applied as CSS custom properties (--grafos-font-sans and --grafos-font-mono) and used throughout the Tailwind preset. Make sure the fonts are loaded in your project, either through next/font or a <link> tag.
Using next/font for optimal performance:
import { Inter, JetBrains_Mono } from 'next/font/google'
const sans = Inter({ subsets: ['latin'], variable: '--grafos-font-sans' })
const mono = JetBrains_Mono({ subsets: ['latin'], variable: '--grafos-font-mono' })
export default function RootLayout({ children }) {
return (
<html className={`${sans.variable} ${mono.variable}`}>
<body>{children}</body>
</html>
)
}
Tailwind Preset
Grafos ships a Tailwind CSS v4 preset that maps all CSS custom properties to Tailwind utilities. Add it to your Tailwind configuration:
@import "tailwindcss";
@import "grafos/tailwind";
The preset provides:
- Color utilities mapped to Grafos CSS variables (
bg-grafos-bg,text-grafos-accent, etc.) - Font family utilities (
font-grafos-sans,font-grafos-mono) - Spacing tokens for the sidebar and TOC widths
- Dark mode variant using the
.darkclass strategy
Because the preset uses CSS custom properties as values, changing a variable in your CSS automatically updates every Tailwind utility that references it. You do not need to modify the preset itself.
The Grafos preset uses Tailwind CSS v4's CSS-first configuration. It is not compatible with Tailwind v3's tailwind.config.js approach.
The current page is always rendered with the accent color and a larger radius so it stands out in both the local and global views. The accent color is controlled by the CSS variable. See theme for details on customizing colors.
For theme customization, see theme. For plugin development, see creating-plugins. For content organization, see content-directory.
- 3D Interactive Graph — force-directed graph visualization with local and global views, instanced rendering, and Web Worker physics. See graph for details. - Full-text Search — client-side search powered by MiniSearch with a Cmd+K keyboard shortcut and fuzzy matching. See search for details. - Wikilinks — Obsidian-compatible link syntax including page links, aliased links, heading links, and block embeds. See wikilinks for details. - Backlinks — automatic bidirectional link tracking that shows which pages link to the current page. See backlinks for details. - Syntax Highlighting — code blocks highlighted by Shiki with support for dozens of languages and themes. - LaTeX Math — inline and block math expressions rendered by KaTeX through remark-math and rehype-katex. - Callouts — Obsidian-style callout blocks for tips, warnings, notes, and other admonitions. - Table of Contents — automatically generated from page headings with scroll-tracking and smooth navigation. - Dark Mode — dark by default with a toggle that persists in localStorage and renders flash-free via an inline head script. - On-demand OG Images — social sharing images generated at request time through a Next.js API route, not at build time. - Plugin System — extend the markdown pipeline, graph data, and page layout with reusable plugins. See plugins for details. - Tailwind CSS v4 Preset — theming through CSS custom properties with a custom Tailwind preset for consistent styling. See theme for details.