import type { Metadata, Viewport } from "next"; import { Geist, Geist_Mono, Inter, Space_Grotesk, DM_Sans, Playfair_Display, Lato, Nunito, Outfit, JetBrains_Mono, } from "next/font/google"; import "leaflet/dist/leaflet.css"; import "./globals.css"; import { ThemeProvider } from "@/components/theme-provider"; import { AuthProvider } from "@/components/auth-provider"; import { Toaster } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; import { ServiceWorkerRegistration } from "@/components/service-worker-registration"; import { ThemeBootstrapScript } from "@/components/theme-bootstrap"; // Geist (default app fonts) const geistSans = Geist({ variable: "--font-geist-sans", subsets: ["latin"], }); const geistMono = Geist_Mono({ variable: "--font-geist-mono", subsets: ["latin"], }); // Theme-bound fonts (registered as CSS vars for the theme picker to swap). // Each font is restricted to the two weights actually used in the app // (400 regular + 700 bold). Without these, next/font/google preloads // every available weight and the browser logs warnings about unused // preload tags (and the page wastes bandwidth fetching woff2 files // that will never render). const inter = Inter({ variable: "--font-inter", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const spaceGrotesk = Space_Grotesk({ variable: "--font-space-grotesk", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const dmSans = DM_Sans({ variable: "--font-dm-sans", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const playfair = Playfair_Display({ variable: "--font-playfair", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const lato = Lato({ variable: "--font-lato", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const nunito = Nunito({ variable: "--font-nunito", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const outfit = Outfit({ variable: "--font-outfit", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); const jetbrainsMono = JetBrains_Mono({ variable: "--font-jetbrains-mono", subsets: ["latin"], weight: ["400", "700"], display: "swap", }); export const viewport: Viewport = { width: "device-width", initialScale: 1, viewportFit: "cover", themeColor: "#4C96D7", }; export const metadata: Metadata = { title: "WFDASH - Business CRM", description: "Business CRM for managing customers, companies, suppliers, quotes, and orders", manifest: "/manifest.json", applicationName: "WFDASH", authors: [{ name: "WFDASH" }], keywords: ["CRM", "Business", "Quotes", "Orders", "Customers", "Suppliers"], appleWebApp: { capable: true, statusBarStyle: "default", title: "WFDASH", }, icons: { icon: [ { url: "/favicon.ico", sizes: "any" }, { url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" }, { url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" }, { url: "/favicon-96x96.png", sizes: "96x96", type: "image/png" }, { url: "/android-chrome-192x192.png", sizes: "192x192", type: "image/png" }, { url: "/android-chrome-512x512.png", sizes: "512x512", type: "image/png" }, ], apple: "/apple-touch-icon.png", }, openGraph: { type: "website", title: "WFDASH - Business CRM", description: "Business CRM for managing customers, companies, suppliers, quotes, and orders", siteName: "WFDASH", images: [ { url: "/og-image.png", width: 1200, height: 630, alt: "WFDASH - Business CRM", }, ], }, twitter: { card: "summary_large_image", title: "WFDASH - Business CRM", description: "Business CRM for managing customers, companies, suppliers, quotes, and orders", images: ["/twitter-image.png"], }, }; // All theme-bound CSS vars must be present on so themes can swap them const FONT_VARS = [ geistSans.variable, geistMono.variable, inter.variable, spaceGrotesk.variable, dmSans.variable, playfair.variable, lato.variable, nunito.variable, outfit.variable, jetbrainsMono.variable, ].join(" "); export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {/* Apply persisted theme before hydration to prevent flash of wrong theme */} {children} ); }