SPB Git forge

spb/websensor

Public
33commits 1branches 0releases
3.4 MBsize
maindefault branch
10 days agolast push
TypeScript 55.4% Python 43.2% SQL 1.2%
2.8 KB · 51 lines tsx
Raw Blame History
1import type { Metadata, Viewport } from "next";2import { Inter, JetBrains_Mono } from "next/font/google";3import type { ReactNode } from "react";4import { CommandPalette } from "@/components/command-palette";5import { EventDrawerProvider } from "@/components/event-drawer";6import { Footer } from "@/components/footer";7import { MobileNav, TopNav } from "@/components/nav";8import { PrefsProvider } from "@/components/prefs";9import { Providers } from "@/components/theme";10import { SITE_URL } from "@/lib/api";11import "./globals.css";1213const inter = Inter({ subsets: ["latin"], variable: "--font-inter", display: "swap" });14const mono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains", display: "swap" });1516export const metadata: Metadata = {17  metadataBase: new URL(SITE_URL),18  title: { default: "WebSensor — The Web is changing. We are watching.", template: "%s · WebSensor" },19  description: "WebSensor continuously watches the public web for meaningful changes, preserving evidence and connecting signals into real-world events.",20  applicationName: "WebSensor",21  authors: [{ name: "Simon-Pierre Boucher", url: "https://www.maclustr.io" }],22  creator: "Simon-Pierre Boucher",23  openGraph: { type: "website", siteName: "WebSensor", url: SITE_URL, title: "WebSensor — The Web is changing. We are watching.", description: "Real-time Internet change intelligence: what changed, where, when, whether it was silent, how important it is — with immutable evidence." },24  twitter: { card: "summary_large_image", title: "WebSensor — The Web is changing. We are watching.", description: "Detect what changed. Know why it matters." },25  alternates: { canonical: "/", types: { "application/rss+xml": `${SITE_URL}/api/v1/feed.rss` } },26  robots: { index: true, follow: true },27};2829export const viewport: Viewport = { themeColor: [{ media: "(prefers-color-scheme: dark)", color: "#0a0e15" }, { media: "(prefers-color-scheme: light)", color: "#f6f7fa" }], width: "device-width", initialScale: 1, viewportFit: "cover" };3031export default function RootLayout({ children }: { children: ReactNode }) {32  return (33    <html lang="en" className={`${inter.variable} ${mono.variable} dark`} suppressHydrationWarning>34      <body className="min-h-dvh">35        <Providers>36          <PrefsProvider>37            <EventDrawerProvider>38              <a href="#main" className="sr-only focus:not-sr-only focus:fixed focus:left-2 focus:top-2 focus:z-[70] focus:rounded-md focus:bg-panel focus:px-3 focus:py-2">Skip to content</a>39              <TopNav />40              <main id="main" className="mx-auto w-full max-w-[1600px] px-3 py-4 pb-24 sm:px-4 lg:pb-6">{children}</main>41              <Footer />42              <MobileNav />43              <CommandPalette />44            </EventDrawerProvider>45          </PrefsProvider>46        </Providers>47      </body>48    </html>49  );50}51