mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-28 07:09:50 +00:00
The docs estate declared its typeface in 30 root layouts and one linked stylesheet, each pulling a third-party family off a hosted font CDN on the critical path of every route. Two of those surfaces also self-hosted the faces, so the same bytes were vendored by hand in the repo. @hanzo/font 1.8.8 is where Zen is authored. It is now mounted the way this repo already mounts every other package stylesheet — `@import '@hanzo/font/css'` at the top of the app's own sheet — which declares the @font-face rules and publishes --font-zen-sans / --font-zen-mono. A single :root block per app binds those to --font-sans / --font-mono, the pair every rule and every font-* utility already read, so the variable contract is untouched and the next face swap is two lines rather than a sweep. Genuine system fallbacks stay. Mounting through the sheet rather than a JS side-effect import also drops the untyped bare subpath TypeScript could not resolve, so no per-app declaration shim is needed. public/reference/ is static HTML with no bundler, so it keeps its own @font-face; scripts/sync-reference-fonts.ts copies the two variable faces out of the installed package on each build and the directory is ignored, the same rule public/openapi/ already follows. The hand-vendored faces are deleted. Also corrects the brand typography table, which still named a face Hanzo does not ship, and the three sample configs and two skill pages that repeated it.
47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import './global.css';
|
|
import '@hanzo/docs/ui/style.css';
|
|
import { RootProvider } from '@hanzo/docs/ui/provider/next';
|
|
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" 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>
|
|
);
|
|
}
|