Files
zeekay 7218bcd39c fix(type): every app and every template a customer generates starts on Zen
Thirteen shipped apps and every scaffold in packages/create-app pulled their
face from Google at request time — Inter through next/font/google in the
examples and the four Next templates, Geist and Geist_Mono in the apps, and in
the seven react-router roots a bare <link> to fonts.googleapis.com. That last
one never even applied what it fetched: nothing in those trees set a family, so
the browser downloaded Inter, spent two preconnects on it, and rendered
system-ui. So `create-app` handed a customer a new docs site whose first act was
a third-party font request for a face that is not ours.

The apps read the family back through --font-sans and --font-mono, which are
next/font's handles rather than names of anything, so those follow the binding
over to --font-zen-sans and --font-zen-mono. Eight of them had only ever bound
the mono and were leaning on Tailwind's default for the text face; they now name
both, or swapping the binding would have dropped the body copy to system-ui
without a word.

Zen and ZenMono are built faces, not constructors — subsetting, display: swap
and fallback metrics are already in them — so the call and its options go away.
2026-08-28 11:30:07 -07:00

48 lines
1.3 KiB
TypeScript

import './global.css';
import '@hanzo/docs/ui/style.css';
import { RootProvider } from '@hanzo/docs/ui/provider/next';
import { Zen } from '@hanzo/font';
import type { ReactNode } from 'react';
import { SearchDialog } from '../components/search-dialog';
import { brand } from '../lib/config';
export const metadata = {
title: {
default: brand.name,
template: `%s | ${brand.name}`,
},
description: brand.description,
keywords: [brand.shortName, 'proposals', 'governance', 'standards'],
metadataBase: new URL(brand.baseUrl),
openGraph: {
title: brand.name,
description: brand.description,
type: 'website',
siteName: brand.name,
},
};
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" className={Zen.variable} suppressHydrationWarning>
<body className="min-h-svh bg-fd-background font-sans antialiased">
<RootProvider
search={{
enabled: false,
}}
theme={{
enabled: true,
defaultTheme: 'dark',
storageKey: `${brand.shortName.toLowerCase()}-theme`,
}}
>
<SearchDialog brand={brand} />
<div className="relative flex min-h-svh flex-col bg-fd-background">
{children}
</div>
</RootProvider>
</body>
</html>
);
}