← back to Nineoh Guide
apps/web/app/layout.tsx
94 lines
import type { Metadata } from "next";
import { Playfair_Display, Inter } from "next/font/google";
import { APP, SITE_URL } from "@nineoh/core";
import "./globals.css";
const display = Playfair_Display({
subsets: ["latin"],
weight: ["600", "700"],
variable: "--font-display",
display: "swap",
});
const body = Inter({
subsets: ["latin"],
variable: "--font-body",
display: "swap",
});
export const metadata: Metadata = {
metadataBase: new URL(SITE_URL),
title: {
default: `${APP.displayName} — Unofficial Episode & Cast Guide`,
template: `%s · ${APP.displayName}`,
},
description:
"An unofficial, fan-made guide to the 90210 series: original episode recaps, cast bios, and news. Not affiliated with the show's producers, network, or cast.",
robots: { index: true, follow: true },
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${display.variable} ${body.variable}`}>
<body>
<header className="site-header">
<div className="bar">
<a className="brand" href="/" aria-label={APP.displayName}>
<Mark />
<strong style={{ fontFamily: "var(--font-display)", fontSize: 19 }}>
90210 Guide
</strong>
<span className="badge">Unofficial</span>
</a>
<input type="checkbox" id="navtoggle" className="nav-toggle" aria-hidden="true" />
<label htmlFor="navtoggle" className="hamburger" aria-label="Open menu">
☰
</label>
<nav className="nav">
<a href="/show">Series</a>
<a href="/episodes">Episodes</a>
<a href="/cast">Cast</a>
<a href="/characters">Characters</a>
<a href="/news">News</a>
<a href="/games">Games</a>
<a href="/community">Community</a>
<a href="/search">Search</a>
</nav>
</div>
</header>
<main className="wrap">{children}</main>
<footer className="site-footer">
{APP.disclaimerShort}{" "}
<a href="/legal/disclaimer">Disclaimer</a> ·{" "}
<a href="/legal/dmca">Copyright/DMCA</a> ·{" "}
<a href="/legal/privacy">Privacy</a>
</footer>
</body>
</html>
);
}
/* Original art-deco sun mark — our brand glyph, not the show's. */
function Mark() {
return (
<svg width="26" height="26" viewBox="0 0 40 40" aria-hidden="true">
<circle cx="20" cy="24" r="10" fill="#c19a3e" />
<g stroke="#c19a3e" strokeWidth="2" strokeLinecap="round">
{Array.from({ length: 7 }).map((_, i) => {
const a = Math.PI - (Math.PI / 6) * i;
return (
<line
key={i}
x1={20 + Math.cos(a) * 13}
y1={24 - Math.sin(a) * 13}
x2={20 + Math.cos(a) * 18}
y2={24 - Math.sin(a) * 18}
/>
);
})}
</g>
</svg>
);
}