- Auf /colonies/[id]/hive bekommen Sprunglink, Seitenleiste, Kopf, Offline-Band, untere Navigation und „+ Neu“ das Attribut inert; der erste Tab landet auf „Zurück“ im Editor (vorher Stopp 34). - metadata.icons verlinkt /icon.svg neben favicon.ico und apple-icon. - Tests: alle THEME_COLORS gleich dem jeweiligen --background, ausdrücklich gewähltes Dunkel färbt die theme-color. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
82 lines
2.8 KiB
TypeScript
82 lines
2.8 KiB
TypeScript
import type { Metadata, Viewport } from "next";
|
||
import localFont from "next/font/local";
|
||
import "./globals.css";
|
||
import { Providers } from "./providers";
|
||
import { Toaster } from "@/components/ui/sonner";
|
||
import { ServiceWorkerRegistration } from "@/components/service-worker-registration";
|
||
import { AppearanceScript } from "@/components/appearance-script";
|
||
import { AppearanceSync } from "@/components/appearance-sync";
|
||
import { THEME_COLORS } from "@/lib/appearance/appearance-core";
|
||
|
||
// Self-hosted (OFL-1.1, see ./fonts/OFL.txt): no Google request at build or runtime.
|
||
const spaceGrotesk = localFont({
|
||
variable: "--font-heading",
|
||
src: "./fonts/space-grotesk-latin-wght-normal.woff2",
|
||
weight: "300 700",
|
||
display: "swap",
|
||
});
|
||
|
||
const inter = localFont({
|
||
variable: "--font-body",
|
||
src: "./fonts/inter-latin-wght-normal.woff2",
|
||
weight: "100 900",
|
||
display: "swap",
|
||
});
|
||
|
||
const plexMono = localFont({
|
||
variable: "--font-data",
|
||
src: [
|
||
{ path: "./fonts/ibm-plex-mono-latin-400-normal.woff2", weight: "400", style: "normal" },
|
||
{ path: "./fonts/ibm-plex-mono-latin-500-normal.woff2", weight: "500", style: "normal" },
|
||
],
|
||
display: "swap",
|
||
});
|
||
|
||
export const metadata: Metadata = {
|
||
title: "ApiCore – Imkereiverwaltung",
|
||
description: "Digitale Imkereiverwaltung für Wabenhain",
|
||
// favicon.ico (src/app) stays first by file convention. The SVG lives in
|
||
// public/ for the manifest and the service worker. Setting icons here drops
|
||
// the file-based apple-icon from the head, so it is listed again.
|
||
icons: {
|
||
icon: [{ url: "/icon.svg", type: "image/svg+xml" }],
|
||
apple: [{ url: "/apple-icon.png", sizes: "180x180", type: "image/png" }],
|
||
},
|
||
};
|
||
|
||
export const viewport: Viewport = {
|
||
width: "device-width",
|
||
initialScale: 1,
|
||
// Without "cover" iOS reports env(safe-area-inset-*) as 0, and the bottom
|
||
// nav and save bar would sit under the home indicator.
|
||
viewportFit: "cover",
|
||
// The inline appearance script overwrites these when a manual choice differs
|
||
// from the device setting.
|
||
themeColor: [
|
||
{ media: "(prefers-color-scheme: light)", color: THEME_COLORS.light },
|
||
{ media: "(prefers-color-scheme: dark)", color: THEME_COLORS.dark },
|
||
],
|
||
};
|
||
|
||
export default function RootLayout({ children }: LayoutProps<"/">) {
|
||
return (
|
||
<html
|
||
lang="de"
|
||
// The inline script sets class="dark", data-contrast and data-motion
|
||
// before hydration; React must keep the document's values.
|
||
suppressHydrationWarning
|
||
className={`${spaceGrotesk.variable} ${inter.variable} ${plexMono.variable} h-full antialiased`}
|
||
>
|
||
<head>
|
||
<AppearanceScript />
|
||
</head>
|
||
<body className="min-h-full flex flex-col">
|
||
<Providers>{children}</Providers>
|
||
<Toaster richColors />
|
||
<ServiceWorkerRegistration />
|
||
<AppearanceSync />
|
||
</body>
|
||
</html>
|
||
);
|
||
}
|