import type { Metadata, Viewport } from "next"; import { headers } from "next/headers"; import { Cormorant_Garamond, Inter } from "next/font/google"; import { Analytics } from "@/components/Analytics"; import { LOCALES, DEFAULT_LOCALE, type Locale } from "@/lib/i18n/config"; import { localePath } from "@/lib/i18n/navigation"; import { stripLocalePrefix } from "@/lib/i18n/navigation"; import "@fortawesome/fontawesome-free/css/all.min.css"; import "./globals.css"; // Editorial fonts: drive tailwind `font-serif`/`font-sans` via // --font-serif / --font-sans across every page (home, /play, /new, CustomForm). const cormorant = Cormorant_Garamond({ subsets: ["latin"], weight: ["300", "400", "500", "600"], style: ["normal", "italic"], variable: "--font-serif", display: "swap", }); const inter = Inter({ subsets: ["latin"], weight: ["300", "400", "500"], variable: "--font-sans", display: "swap", }); export const metadata: Metadata = { title: "InfiPlot — AI 实时交互剧情游戏", description: "InfiPlot 是一款用 AI 实时生成图片、语音与剧情分支的交互式剧情游戏 Demo。", }; // viewportFit:cover lets the immersive /play portrait layout extend under the // iOS notch / home-indicator and exposes env(safe-area-inset-*) to the // floating controls. device-width + initialScale keep mobile rendering 1:1. export const viewport: Viewport = { width: "device-width", initialScale: 1, viewportFit: "cover", }; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const headersList = await headers(); const locale = headersList.get("x-locale") || "zh-CN"; const origin = process.env.NEXT_PUBLIC_BASE_URL || (process.env.VERCEL_PROJECT_PRODUCTION_URL ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` : "https://infiplot.com"); const pathname = headersList.get("x-pathname") || "/"; const barePath = stripLocalePrefix(pathname); return ( {LOCALES.map((l) => ( ))} {children} ); }