spb/spboucher.ai Public
spboucher.ai — personal website of Simon-Pierre Boucher.
TypeScript 93.4%
HTML 5.5%
CSS 1%
1/*2 layout.tsx3 spboucher.ai Web4 Author: Simon-Pierre Boucher5 Mail: contact@spboucher.ai6*/78import type { Metadata } from "next";9import { Fraunces, IBM_Plex_Mono, Inter } from "next/font/google";1011import { AgentChat } from "@/components/agent-chat";12import { SiteHeader } from "@/components/site-header";13import { SiteFooter } from "@/components/site-footer";1415import "./globals.css";1617const inter = Inter({18 subsets: ["latin"],19 variable: "--font-inter",20});2122const fraunces = Fraunces({23 subsets: ["latin"],24 style: ["normal", "italic"],25 axes: ["opsz"],26 variable: "--font-fraunces",27});2829const plexMono = IBM_Plex_Mono({30 subsets: ["latin"],31 weight: ["400", "500", "600"],32 variable: "--font-plex-mono",33});3435export const metadata: Metadata = {36 metadataBase: new URL("https://www.spboucher.ai"),37 title: {38 default: "Simon-Pierre Boucher — Professor & macOS/AI Developer",39 template: "%s — Simon-Pierre Boucher",40 },41 description:42 "Simon-Pierre Boucher is a Professor in the Department of Administrative Sciences at Université du Québec en Outaouais (UQO). Financial econometrics researcher and macOS/AI developer.",43 openGraph: {44 title: "Simon-Pierre Boucher",45 description:46 "Financial econometrics researcher and macOS/AI developer. Professor at Université du Québec en Outaouais (UQO).",47 url: "https://www.spboucher.ai",48 siteName: "Simon-Pierre Boucher",49 locale: "en_US",50 type: "website",51 },52};5354// Applies the saved (or system) theme before first paint to avoid a flash55// of the wrong color scheme.56const themeInitScript = `57try {58 var t = localStorage.getItem("theme");59 if (t === "dark" || (!t && window.matchMedia("(prefers-color-scheme: dark)").matches)) {60 document.documentElement.classList.add("dark");61 }62} catch (e) {}63`;6465export default function RootLayout({66 children,67}: Readonly<{68 children: React.ReactNode;69}>) {70 return (71 <html lang="en" suppressHydrationWarning>72 <head>73 <script dangerouslySetInnerHTML={{ __html: themeInitScript }} />74 <noscript>75 <style>{`[data-reveal]{opacity:1!important;transform:none!important}`}</style>76 </noscript>77 </head>78 <body79 className={`${inter.variable} ${fraunces.variable} ${plexMono.variable} flex min-h-screen flex-col antialiased`}80 >81 <SiteHeader />82 <main className="flex-1">{children}</main>83 <SiteFooter />84 <AgentChat />85 </body>86 </html>87 );88}89