diff --git a/src/app/fonts/dm-sans-var.woff2 b/src/app/fonts/dm-sans-var.woff2 new file mode 100644 index 0000000..8f8cb55 Binary files /dev/null and b/src/app/fonts/dm-sans-var.woff2 differ diff --git a/src/app/fonts/geist-mono-var.woff2 b/src/app/fonts/geist-mono-var.woff2 new file mode 100644 index 0000000..cf24126 Binary files /dev/null and b/src/app/fonts/geist-mono-var.woff2 differ diff --git a/src/app/fonts/geist-var.woff2 b/src/app/fonts/geist-var.woff2 new file mode 100644 index 0000000..8f01e76 Binary files /dev/null and b/src/app/fonts/geist-var.woff2 differ diff --git a/src/app/fonts/inter-var.woff2 b/src/app/fonts/inter-var.woff2 new file mode 100644 index 0000000..91dc3e8 Binary files /dev/null and b/src/app/fonts/inter-var.woff2 differ diff --git a/src/app/fonts/jetbrains-mono-var.woff2 b/src/app/fonts/jetbrains-mono-var.woff2 new file mode 100644 index 0000000..2ca6ac6 Binary files /dev/null and b/src/app/fonts/jetbrains-mono-var.woff2 differ diff --git a/src/app/fonts/lato-400.woff2 b/src/app/fonts/lato-400.woff2 new file mode 100644 index 0000000..56e968d Binary files /dev/null and b/src/app/fonts/lato-400.woff2 differ diff --git a/src/app/fonts/lato-700.woff2 b/src/app/fonts/lato-700.woff2 new file mode 100644 index 0000000..95c63e0 Binary files /dev/null and b/src/app/fonts/lato-700.woff2 differ diff --git a/src/app/fonts/nunito-var.woff2 b/src/app/fonts/nunito-var.woff2 new file mode 100644 index 0000000..e118818 Binary files /dev/null and b/src/app/fonts/nunito-var.woff2 differ diff --git a/src/app/fonts/outfit-var.woff2 b/src/app/fonts/outfit-var.woff2 new file mode 100644 index 0000000..48aae95 Binary files /dev/null and b/src/app/fonts/outfit-var.woff2 differ diff --git a/src/app/fonts/playfair-display-var.woff2 b/src/app/fonts/playfair-display-var.woff2 new file mode 100644 index 0000000..1636e50 Binary files /dev/null and b/src/app/fonts/playfair-display-var.woff2 differ diff --git a/src/app/fonts/space-grotesk-var.woff2 b/src/app/fonts/space-grotesk-var.woff2 new file mode 100644 index 0000000..7b0e76a Binary files /dev/null and b/src/app/fonts/space-grotesk-var.woff2 differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fe59c85..919075b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,16 +1,5 @@ import type { Metadata, Viewport } from "next"; -import { - Geist, - Geist_Mono, - Inter, - Space_Grotesk, - DM_Sans, - Playfair_Display, - Lato, - Nunito, - Outfit, - JetBrains_Mono, -} from "next/font/google"; +import localFont from "next/font/local"; import "leaflet/dist/leaflet.css"; import "./globals.css"; import { ThemeProvider } from "@/components/theme-provider"; @@ -20,68 +9,75 @@ import { TooltipProvider } from "@/components/ui/tooltip"; import { ServiceWorkerRegistration } from "@/components/service-worker-registration"; import { ThemeBootstrapScript } from "@/components/theme-bootstrap"; -// Geist (default app fonts) -const geistSans = Geist({ +// Fonts are self-hosted from ./fonts (Latin subsets of the Google Fonts +// files, downloaded 2026-10-20). With next/font/google every build fetched +// them from fonts.googleapis.com, and the Coolify build kept failing on +// that download (Nunito/Outfit 17 Oct, Lato and JetBrains Mono 20 Oct). +// Same CSS variable names and weights as before. + +// Geist (default app fonts) — variable fonts. +const geistSans = localFont({ + src: "./fonts/geist-var.woff2", variable: "--font-geist-sans", - subsets: ["latin"], + weight: "100 900", }); -const geistMono = Geist_Mono({ +const geistMono = localFont({ + src: "./fonts/geist-mono-var.woff2", variable: "--font-geist-mono", - subsets: ["latin"], + weight: "100 900", }); -// Theme-bound fonts (registered as CSS vars for the theme picker to swap). -// Each font is restricted to the two weights actually used in the app -// (400 regular + 700 bold). Without these, next/font/google preloads -// every available weight and the browser logs warnings about unused -// preload tags (and the page wastes bandwidth fetching woff2 files -// that will never render). -const inter = Inter({ +// Theme-bound fonts (registered as CSS vars for the theme picker to swap), +// 400 regular + 700 bold — the two weights the app uses. Most are variable +// files covering 400–700; Lato ships one file per weight. +const inter = localFont({ + src: "./fonts/inter-var.woff2", variable: "--font-inter", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const spaceGrotesk = Space_Grotesk({ +const spaceGrotesk = localFont({ + src: "./fonts/space-grotesk-var.woff2", variable: "--font-space-grotesk", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const dmSans = DM_Sans({ +const dmSans = localFont({ + src: "./fonts/dm-sans-var.woff2", variable: "--font-dm-sans", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const playfair = Playfair_Display({ +const playfair = localFont({ + src: "./fonts/playfair-display-var.woff2", variable: "--font-playfair", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const lato = Lato({ +const lato = localFont({ + src: [ + { path: "./fonts/lato-400.woff2", weight: "400", style: "normal" }, + { path: "./fonts/lato-700.woff2", weight: "700", style: "normal" }, + ], variable: "--font-lato", - subsets: ["latin"], - weight: ["400", "700"], display: "swap", }); -const nunito = Nunito({ +const nunito = localFont({ + src: "./fonts/nunito-var.woff2", variable: "--font-nunito", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const outfit = Outfit({ +const outfit = localFont({ + src: "./fonts/outfit-var.woff2", variable: "--font-outfit", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", }); -const jetbrainsMono = JetBrains_Mono({ +const jetbrainsMono = localFont({ + src: "./fonts/jetbrains-mono-var.woff2", variable: "--font-jetbrains-mono", - subsets: ["latin"], - weight: ["400", "700"], + weight: "400 700", display: "swap", });