Files
ApiCore/ApiCore-Frontend/src/app/layout.tsx
T
Nick.RosenloecherandClaude Opus 5.5 6ac9eef93b fix: Beute-Editor fängt den Fokus, SVG-Icon im Kopf
- 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]>
2026-10-16 18:20:28 +02:00

82 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
);
}