import type { Metadata } from "next"; import { THEME_INIT_SCRIPT } from "@/components/theme-toggle"; import { accentCss } from "@/lib/branding-colors"; import { getBranding } from "@/lib/branding"; import "./globals.css"; // Name, Farbe und Favicon kommen aus der Datenbank — nichts davon darf // vorgerendert werden. export const dynamic = "force-dynamic"; export async function generateMetadata(): Promise { const branding = await getBranding(); return { title: { default: branding.appName, template: `%s · ${branding.appName}`, }, description: "QR-Codes erstellen: statisch oder dynamisch, mit eigenen Farben, frei wählbarer Größe und Download als PNG oder SVG.", // Ohne eigenes Favicon bleibt es bei src/app/favicon.ico. ...(branding.faviconUploadId ? { icons: { icon: { url: `/api/uploads/${branding.faviconUploadId}`, type: branding.faviconMimeType ?? undefined, }, }, } : {}), }; } /** * Wurzel-Layout — bewusst nur `html`, `body` und die Akzentfarbe. * * Kopfzeile, Navigation und Fußzeile der Anwendung stehen eine Ebene tiefer in * `(app)/layout.tsx`. Denn die öffentlichen Landingpages unter `/s/[slug]` * bekommen ein Feld voller Fremder zu sehen: dort haben „Verwaltung“ und * „Meine Codes“ nichts zu suchen. * * Die Farbe gehört dagegen hierher, damit auch die Landingpages sie tragen. */ export default async function RootLayout({ children }: LayoutProps<"/">) { const branding = await getBranding(); return ( {/* Setzt eine ausdrücklich gewählte Fassung, bevor der Browser zeichnet. Wer der Systemeinstellung folgt, braucht das nicht — das erledigt `light-dark()` im CSS von allein. */}