spb/qwhpi Public
QHPI — Quebec Housing Price Index: quality-adjusted, hierarchically pooled housing price indexes.
Python 63.9%
TypeScript 25.4%
CSS 5.5%
TeX 3.5%
SQL 0.8%
Makefile 0.5%
Dockerfile 0.5%
1/**2 * =============================================================================3 * QWHPI — Quebec Weekly Housing Price Index4 * Author : Simon-Pierre Boucher5 * Contact : contact@spboucher.ai6 * File : web/app/layout.tsx7 * Purpose : Root layout — fonts, navigation, theme toggle, author footer.8 * =============================================================================9 */10import type { Metadata } from "next";11import Link from "next/link";12import { Fraunces, Inter } from "next/font/google";13import "../styles/globals.css";14import ThemeToggle from "../components/ThemeToggle";15import CommandPalette from "../components/CommandPalette";16import SearchButton from "../components/SearchButton";1718const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });19const fraunces = Fraunces({20 subsets: ["latin"],21 variable: "--font-display",22 weight: ["600", "700"],23});2425export const metadata: Metadata = {26 metadataBase: new URL("https://www.indexqc.house"),27 title: {28 default: "QHPI — Quebec Housing Price Index (monthly)",29 template: "%s · QHPI",30 },31 description:32 "Quality-adjusted monthly housing price indexes for Quebec — province, " +33 "17 regions and 10 cities, with confidence intervals on every point. " +34 "Author: Simon-Pierre Boucher — contact@spboucher.ai",35 authors: [{ name: "Simon-Pierre Boucher" }],36 alternates: { canonical: "/" },37 openGraph: {38 title: "QHPI — Quebec Housing Price Index",39 description:40 "Quebec housing prices, measured monthly, robustly. " +41 "Uncertainty always displayed, never hidden.",42 url: "https://www.indexqc.house",43 siteName: "QHPI",44 type: "website",45 locale: "en_CA",46 },47 twitter: {48 card: "summary_large_image",49 title: "QHPI — Quebec Housing Price Index",50 description: "Quebec housing prices, measured monthly, robustly.",51 },52};5354export default function RootLayout({55 children,56}: {57 children: React.ReactNode;58}) {59 return (60 <html lang="en" suppressHydrationWarning61 className={`${inter.variable} ${fraunces.variable}`}>62 <body>63 <header className="site-header">64 <Link href="/" className="brand">65 <svg className="brand-mark" width="22" height="22" viewBox="0 0 22 22"66 aria-hidden focusable="false">67 <rect x="1" y="1" width="20" height="20" rx="5"68 fill="var(--series-1)" />69 <path d="M5 14.5 L9 10.5 L12 12.5 L17 6.5" fill="none"70 stroke="#fff" strokeWidth="2" strokeLinecap="round"71 strokeLinejoin="round" />72 </svg>73 QHPI<small>Quebec Housing Price Index · monthly</small>74 </Link>75 <nav aria-label="Main">76 <Link href="/">Overview</Link>77 <Link href="/explore">Explore</Link>78 <Link href="/compare">Compare</Link>79 <Link href="/map">Map</Link>80 <Link href="/methodology">Methodology</Link>81 <Link href="/api-docs">API</Link>82 </nav>83 <div style={{ display: "flex", gap: 8 }}>84 <SearchButton />85 <ThemeToggle />86 </div>87 </header>88 <CommandPalette />89 <main className="container">{children}</main>90 <footer className="site-footer">91 Simon-Pierre Boucher — contact@spboucher.ai · Monthly hedonic index,92 base 2021 average = 100 · Uncertainty is always displayed, never93 hidden.94 </footer>95 </body>96 </html>97 );98}99