- Farb-Tokens laut Brandbook §11.4 (Lotsenblau, Signalorange, Graphit, Hafengrau, Stahlgrau, Zink, Funktionsfarben) in globals.css + src/lib/brand.ts; helles Theme - Inline-SVG-Logo src/components/brand/craftvia-logo.tsx (horizontal/signet, color/mono/reversed, App-Icon-Kachel, optionale Tagline); Certvia-/GEFIM-Logos entfernt - Favicon/PWA-Icons aus dem Signet erzeugt (scripts/generate-brand-icons.ts), site.webmanifest (Craftvia, theme_color #082E5B) - Inter selbst gehostet (next/font/local, lokale OFL-Datei), Open Sans/Poppins entfernt - Metadaten, WebAuthn-RP-Name, Mail-/Dokument-CD auf Craftvia umgestellt - docs/craftvia/BRANDING.md ersetzt docs/BRANDING-CERTVIA.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
||
import localFont from "next/font/local";
|
||
import { NextIntlClientProvider } from "next-intl";
|
||
import { getLocale } from "next-intl/server";
|
||
import { BRAND, BRAND_ASSETS, BRAND_COLORS } from "@/lib/brand";
|
||
import "./globals.css";
|
||
|
||
// Inter (Brandbook §11.5), selbst gehostet über next/font/local — kein Google-Fonts-Fetch
|
||
// zur Build- oder Laufzeit (DSGVO, reproduzierbarer Offline-Build). Variable Font
|
||
// (Gewichte 100–900 in einer Datei). TODO(brand): auf woff2-Subsets umstellen (kleiner).
|
||
const inter = localFont({
|
||
variable: "--font-inter",
|
||
display: "swap",
|
||
src: [{ path: "./fonts/inter-variable.ttf", weight: "100 900", style: "normal" }],
|
||
});
|
||
|
||
export const metadata: Metadata = {
|
||
// Untertitel-Muster: Unterseiten setzen nur ihren eigenen Titel, die Marke hängt an.
|
||
title: { default: `${BRAND.name} — ${BRAND.tagline}`, template: `%s · ${BRAND.name}` },
|
||
description: BRAND.description,
|
||
applicationName: BRAND.name,
|
||
manifest: "/site.webmanifest",
|
||
// Icons aus dem Craftvia-Signet erzeugt (scripts/generate-brand-icons.ts).
|
||
icons: {
|
||
icon: [
|
||
{ url: "/favicon.ico", sizes: "any" },
|
||
{ url: BRAND_ASSETS.favicon, type: "image/svg+xml" },
|
||
{ url: "/favicon/icon-32.png", type: "image/png", sizes: "32x32" },
|
||
],
|
||
apple: [{ url: BRAND_ASSETS.appleTouchIcon, sizes: "180x180" }],
|
||
},
|
||
appleWebApp: { capable: true, title: BRAND.name, statusBarStyle: "default" },
|
||
openGraph: {
|
||
type: "website",
|
||
siteName: BRAND.name,
|
||
title: `${BRAND.name} — ${BRAND.tagline}`,
|
||
description: BRAND.description,
|
||
images: [{ url: BRAND_ASSETS.ogImage, width: 512, height: 512 }],
|
||
},
|
||
};
|
||
|
||
export const viewport: Viewport = {
|
||
themeColor: BRAND_COLORS.lotsenblau,
|
||
};
|
||
|
||
export default async function RootLayout({
|
||
children,
|
||
}: Readonly<{
|
||
children: React.ReactNode;
|
||
}>) {
|
||
const locale = await getLocale();
|
||
|
||
return (
|
||
<html lang={locale} className={`${inter.variable} h-full antialiased`}>
|
||
<body className="min-h-full flex flex-col bg-background text-foreground">
|
||
<NextIntlClientProvider>{children}</NextIntlClientProvider>
|
||
</body>
|
||
</html>
|
||
);
|
||
}
|