2026-03-06 08:41:19 +08:00
import type { Metadata } from "next" ;
2026-05-14 21:31:05 +08:00
import { Inter , JetBrains_Mono } from "next/font/google" ;
import { RegisterSW } from "@/components/dashboard/RegisterSW" ;
2026-03-06 08:41:19 +08:00
import "./globals.css" ;
2026-05-14 21:31:05 +08:00
const inter = Inter ({
subsets : [ "latin" ],
display : "swap" ,
variable : "--font-inter" ,
weight : [ "300" , "400" , "500" , "600" , "700" , "800" ],
});
const jetbrainsMono = JetBrains_Mono ({
subsets : [ "latin" ],
display : "swap" ,
variable : "--font-jetbrains-mono" ,
weight : [ "400" , "500" , "600" , "700" ],
});
2026-03-06 08:41:19 +08:00
export const metadata : Metadata = {
2026-05-26 08:43:55 +08:00
title : {
default : "PolyWeather | Institutional Weather Signal Intelligence" ,
template : "%s | PolyWeather" ,
},
2026-03-06 08:41:19 +08:00
description :
2026-05-31 01:56:08 +08:00
"PolyWeather is a paid professional weather-signal intelligence terminal with METAR evidence, DEB forecast blending, and structured decision context. Real-time observations for 51 global cities." ,
2026-03-12 03:05:11 +08:00
manifest : "/site.webmanifest" ,
2026-05-26 08:43:55 +08:00
metadataBase : new URL ( "https://polyweather.top" ),
alternates : {
canonical : "/" ,
},
openGraph : {
type : "website" ,
siteName : "PolyWeather" ,
title : "PolyWeather | Institutional Weather Signal Intelligence" ,
description :
2026-05-31 01:56:08 +08:00
"Paid professional weather-signal intelligence terminal. METAR evidence, DEB forecast blending, structured decision context. 51 cities, real-time." ,
2026-05-26 08:43:55 +08:00
url : "https://polyweather.top" ,
images : [
{
url : "/apple-touch-icon.png" ,
width : 180 ,
height : 180 ,
alt : "PolyWeather" ,
},
],
},
twitter : {
card : "summary" ,
title : "PolyWeather | Weather Signal Intelligence" ,
description :
"Paid professional weather-signal intelligence terminal. 51 cities, real-time observations." ,
images : [ "/apple-touch-icon.png" ],
},
robots : {
index : true ,
follow : true ,
"max-video-preview" : - 1 ,
"max-image-preview" : "large" ,
"max-snippet" : - 1 ,
},
2026-03-12 03:05:11 +08:00
icons : {
icon : [
{ url : "/favicon.ico" , type : "image/x-icon" },
{ url : "/favicon-32x32.png" , sizes : "32x32" , type : "image/png" },
{ url : "/favicon-16x16.png" , sizes : "16x16" , type : "image/png" },
],
2026-04-15 23:08:56 +08:00
apple : [
{ url : "/apple-touch-icon.png" , sizes : "180x180" , type : "image/png" },
],
2026-03-12 03:05:11 +08:00
shortcut : [ "/favicon.ico" ],
},
2026-03-06 08:41:19 +08:00
};
export default function RootLayout ({
children ,
} : Readonly < { children : React.ReactNode } > ) {
return (
2026-05-14 21:31:05 +08:00
< html
lang = "zh-CN"
2026-05-24 22:38:43 +08:00
className = { ` ${ inter . variable } ${ jetbrainsMono . variable } light` }
2026-05-14 21:31:05 +08:00
>
2026-03-09 10:36:03 +08:00
< head >
2026-05-12 10:06:12 +08:00
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" />
2026-03-09 10:36:03 +08:00
</ head >
2026-05-10 14:21:10 +08:00
< body className = "min-h-screen font-sans antialiased" >
< a href = "#main-content" className = "skip-to-content" >
Skip to content
</ a >
< main id = "main-content" >{ children }</ main >
2026-05-14 21:31:05 +08:00
< RegisterSW />
2026-05-10 14:21:10 +08:00
</ body >
2026-03-06 08:41:19 +08:00
</ html >
);
}