diff --git a/src/app/globals.css b/src/app/globals.css index 3dc2f39..e3c366f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -41,7 +41,15 @@ --fl-accent: var(--fl-amber); /* als Textfarbe nutzbar: 11,3:1 */ --fl-accent-alt: var(--fl-magenta); /* als Textfarbe nutzbar: 6,0:1 */ --fl-on-accent: #1a1024; /* Text auf dem Gradient: min. 5,5:1 */ + /* Markenstops fuer SVG-Verlaeufe (Logo). Als Variablen, damit das Logo im + Light Mode dunkler wird und lesbar bleibt, ohne die Identitaet zu aendern. */ + --fl-brand-1: #ffc46b; + --fl-brand-2: #ffb454; + --fl-brand-3: #ff4d9d; + --fl-gradient: linear-gradient(115deg, var(--fl-amber-soft) 0%, var(--fl-amber) 38%, var(--fl-magenta) 100%); + /* Fuer Text: im Dunkeln identisch, im Hellen deutlich abgedunkelt (AA). */ + --fl-gradient-ink: var(--fl-gradient); --fl-gradient-soft: linear-gradient(115deg, #ffb45426 0%, #ff4d9d26 100%); --fl-glow: 0 0 0 1px #ffb4541f, 0 8px 34px -10px #ff4d9d59, 0 2px 12px -4px #ffb45440; --fl-glow-strong: 0 0 0 1px #ffb4543d, 0 14px 48px -12px #ff4d9d80, 0 4px 18px -6px #ffb4546b; @@ -80,7 +88,15 @@ --fl-accent: #8a4b00; /* als Textfarbe: 6,4:1 */ --fl-accent-alt: #b01262; /* als Textfarbe: 6,4:1 */ --fl-on-accent: #23122c; /* Text auf dem Gradient: min. 6,1:1 */ + /* Logo im Hellen: dieselbe Bernstein-zu-Magenta-Bewegung, nur tiefer + angesetzt — sonst verschwindet die Wortmarke auf dem warmen Weiss. */ + --fl-brand-1: #c26a00; + --fl-brand-2: #b35d00; + --fl-brand-3: #c9186f; + --fl-gradient: linear-gradient(115deg, var(--fl-amber-soft) 0%, var(--fl-amber) 38%, var(--fl-magenta) 100%); + /* Verlaufstext im Hellen: beide Enden erfuellen AA auf --fl-bg. */ + --fl-gradient-ink: linear-gradient(115deg, #8a4b00 0%, #a33a2a 45%, #b01262 100%); --fl-gradient-soft: linear-gradient(115deg, #ffb4542e 0%, #ff4d9d2e 100%); --fl-glow: 0 0 0 1px #d8a15c33, 0 8px 26px -12px #ff4d9d4d, 0 2px 10px -4px #ffb4544d; --fl-glow-strong: 0 0 0 1px #d8a15c59, 0 14px 40px -14px #ff4d9d66, 0 4px 16px -6px #ffb45473; @@ -181,7 +197,7 @@ -------------------------------------------------------------------------- */ @utility fl-gradient-text { - background-image: var(--fl-gradient); + background-image: var(--fl-gradient-ink); background-clip: text; -webkit-background-clip: text; color: transparent; diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..1fe4283 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,80 @@ +import type { Metadata, Viewport } from "next"; +import { Outfit } from "next/font/google"; +import { BrandDefs } from "@/components/brand/FlimmerLogo"; +import { env } from "@/lib/env"; +import "./globals.css"; + +/** + * Outfit wird beim Bauen heruntergeladen und mit ausgeliefert — die laufende + * Instanz fragt also niemals bei Google an. + */ +const outfit = Outfit({ + subsets: ["latin"], + display: "swap", + variable: "--font-outfit", +}); + +export const metadata: Metadata = { + metadataBase: new URL(env.appUrl), + title: { + default: "Flimmer", + template: "%s · Flimmer", + }, + description: "Serien und Filme tracken — selbst gehostet, ohne fremde Konten.", + applicationName: "Flimmer", + manifest: "/manifest.webmanifest", + icons: { + icon: [ + { url: "/favicon.svg", type: "image/svg+xml" }, + { url: "/favicon.ico", sizes: "48x48" }, + ], + apple: "/icons/apple-touch-icon.png", + }, + openGraph: { + title: "Flimmer", + description: "Serien und Filme tracken — selbst gehostet, ohne fremde Konten.", + images: ["/og-image.png"], + type: "website", + }, +}; + +export const viewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: dark)", color: "#0c0a14" }, + { media: "(prefers-color-scheme: light)", color: "#faf7f5" }, + ], + width: "device-width", + initialScale: 1, + viewportFit: "cover", +}; + +/** + * Setzt data-theme, bevor der erste Pixel gemalt wird — sonst blitzt beim + * Laden kurz das falsche Farbschema auf. + */ +const THEME_BOOTSTRAP = `(function(){try{ +var stored=localStorage.getItem("flimmer-theme"); +var mode=stored==="light"||stored==="dark"?stored: + (stored==="system"||!stored)&&window.matchMedia("(prefers-color-scheme: light)").matches?"light":"dark"; +document.documentElement.setAttribute("data-theme",mode); +}catch(e){document.documentElement.setAttribute("data-theme","dark");}})();`; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + +