import type { Metadata, Viewport } from "next"; import { headers } from "next/headers"; import Script from "next/script"; // Inter's faces, self-hosted; see the module. Before globals.css, where the // font-sans stack that names them lives, as the next/font/google import was. import "./fonts/inter"; import "./globals.css"; import { Providers } from "@/components/providers"; import { AuthShell } from "@/components/layout/auth-shell"; import { MonitoringBootstrap } from "@/components/monitoring/bootstrap"; import { WebVitalsReporter } from "@/components/monitoring/web-vitals-reporter"; import { resolveInitialLocale } from "@/lib/i18n/resolve-initial-locale"; import { isKeyMismatch } from "@/lib/boot/key-mismatch-state"; import { THEME_BOOT_SCRIPT, THEME_COLOR } from "@/lib/pwa/theme-color"; import { KeyMismatchPage } from "./key-mismatch-page"; export const metadata: Metadata = { title: "HealthLog", description: "Self-hosted health tracker: weight, blood pressure, glucose, mood, medications. Withings + Apple Health sync, transparent derived wellness metrics, AI Insights you own.", manifest: "/manifest.json", icons: { icon: "/favicon.svg", // Pre-flattened 180×180 on the app background — Safari ignores PNG // alpha in favourites/home-screen tiles and would render the // transparent logo on a white slab otherwise. apple: "/apple-touch-icon.png", }, appleWebApp: { capable: true, statusBarStyle: "black-translucent", title: "HealthLog", }, openGraph: { title: "HealthLog", description: "Self-hosted health tracker. Weight, blood pressure, glucose, mood, medications. Withings + Apple Health sync. AI Insights you own.", type: "website", locale: "en_US", alternateLocale: ["de_DE", "fr_FR", "es_ES", "it_IT", "pl_PL"], siteName: "HealthLog", // Drop-in OG asset. Replace with a 1200×630 dashboard-screenshot // capture when an official one ships; the logo render keeps the // unfurl from rendering a blank tile in the meantime. images: [ { url: "/logo-readme.png", width: 1000, height: 1000, alt: "HealthLog: your health data, your server", }, ], }, twitter: { card: "summary_large_image", title: "HealthLog", description: "Self-hosted health tracker. Weight, blood pressure, glucose, mood, medications. Withings + Apple Health sync. AI Insights you own.", images: ["/logo-readme.png"], }, }; export const viewport: Viewport = { width: "device-width", initialScale: 1, viewportFit: "cover", // Match the browser chrome (Android URL bar, iOS PWA status bar) to // the active palette. The hex values are the resolved background of // `--background` from `app/globals.css` for each theme so the bar // edge never seams against the page on cold paint. // The client rewrites both to the app's own theme once it is known // (`applyThemeColor`), since that need not be the operating system's. themeColor: [ { media: "(prefers-color-scheme: light)", color: THEME_COLOR.light }, { media: "(prefers-color-scheme: dark)", color: THEME_COLOR.dark }, ], }; export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { const nonce = process.env.NODE_ENV === "production" ? ((await headers()).get("x-nonce") ?? undefined) : undefined; const initialLocale = await resolveInitialLocale(); return (