Custom Fonts
Font Property Architecture
This design system enforces complete decoupling of visual fonts from the primitive files. Everything resolves through two standard CSS variables defined at the document root:
--font-displayUsed for display elements (brand logos, headings, titles).
--font-bodyUsed for body, paragraph copy, list texts, buttons, and form inputs.
Step 1 · Declare in Stylesheet
In your consumer application's root stylesheet (e.g., global.css), you can load local fonts or fallback declarations:
/* global.css */
:root {
--font-display: 'Cinzel', serif;
--font-body: 'Mulish', sans-serif;
}Step 2 · Declare in ThemeProvider
If you are using the theme configuration manager, you can feed custom font names directly to the ThemeProvider element. The provider will automatically inject Google Font dependencies and resolve them on the document:
import { ThemeProvider } from "@shavin/ui";
export default function App({ children }) {
return (
<ThemeProvider
accentColor="grass"
radius="medium"
displayFont="Fraunces"
bodyFont="Outfit"
>
{children}
</ThemeProvider>
);
}Local next/font Mapping (Next.js App Router)
For Next.js projects, use the standard next/font utility to optimize layout shift, mapping the output CSS variable names directly:
// app/layout.tsx
import { Inter, Fraunces } from 'next/font/google';
const displayFont = Fraunces({
subsets: ['latin'],
variable: '--font-display',
});
const bodyFont = Inter({
subsets: ['latin'],
variable: '--font-body',
});
export default function RootLayout({ children }) {
return (
<html lang="en" className={`${displayFont.variable} ${bodyFont.variable}`}>
<body>{children}</body>
</html>
);
}