"use client"; import { motion, useReducedMotion, type Variants } from "motion/react"; import { Container, LinkButton } from "@/components/ui"; import { ContentImage } from "@/components/content-image"; import { HoneycombPattern } from "@/components/honeycomb"; import { useI18n } from "@/i18n/i18n-provider"; const itemContainerVariants: Variants = { hidden: {}, visible: { transition: { delayChildren: 0.3, staggerChildren: 0.12 } }, }; const itemVariants: Variants = { hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0, transition: { duration: 0.7, ease: "easeOut" } }, }; /** * Startseiten-Hero mit grossflaechigem Bild und gestaffelter * Einblend-Animation (Eyebrow, Headline, Text, Buttons) beim Laden. */ export function Hero({ intro, footnote, location, image, video, }: { intro: string; footnote: string; location: string; image: string | null; video: string | null; }) { const { t } = useI18n(); const shouldReduceMotion = useReducedMotion(); return ( // Bewusst KEINE Einblend-Animation auf der aeussersten Ebene: eine // Section, die bei opacity 0 startet, wird erst sichtbar, wenn das // JS-Bundle geladen und die Animation gelaufen ist. Das Hero-Bild ist // aber das groesste Element im ersten Viewport (LCP) — es so lange // zurueckzuhalten verschiebt den gemessenen Ladezeitpunkt der Seite um // die gesamte Hydrationsdauer. Der gestaffelte Aufbau der Textspalte // weiter unten bleibt unveraendert, der laeuft unabhaengig davon.
{video ? (
{/* Standbild als eigene Ebene UNTER dem Video statt im poster-Attribut. poster nimmt nur eine fertige URL und laedt die hochgeladene Datei damit in voller gespeicherter Groesse (bis MAX_IMAGE_DIMENSION, siehe lib/uploads.ts) — am Bildoptimierer vorbei und ohne Ruecksicht auf das Geraet. Als ContentImage laeuft dasselbe Bild durch next/image: passende Breite je Bildschirm, WebP statt JPEG, und mit "priority" als erstes angefordert. Das Video liegt darueber und ist transparent, bis es eigene Bilddaten hat — der Uebergang ist deshalb nicht sichtbar. */}
) : (
)} {/* Gleichmaessige Abdunklung ueber die gesamte Flaeche — noetig, weil redaktionell gepflegtes Bild-/Videomaterial (z.B. helle Etiketten, Himmel) sonst je nach Motiv beliebig hell ausfallen und den Text unlesbar machen kann. Der gerichtete Verlauf darunter verstaerkt das gezielt dort, wo die Textspalte tatsaechlich sitzt (unten links). */}
{/* Wabenraster ueber der rechten Bildhaelfte — die Marke im ersten Blick. */} {/* Senkrecht auf schmalen Schirmen, waagerecht ab md. Der frueher hier stehende to-tr-Verlauf liess die Textspalte auf rund 44 % Abdunklung liegen. Ueber hellem Motiv (Holz, Himmel) ergab das 1,34:1 fuer die Ortszeile und 2,73:1 fuer die Ueberschrift — beides weit unter WCAG AA. Lighthouse meldet das nicht, weil es Text ueber Bildern nicht bewerten kann. Waagerecht funktioniert nur ab md: dort endet die Textspalte bei etwa 45 % Breite und liegt damit ganz im dunklen Teil, waehrend die rechte Bildhaelfte unangetastet bleibt. Auf dem Handy laeuft der Text ueber die volle Breite und geriete rechts in den durchsichtigen Teil — deshalb dort senkrecht, was horizontal gleichmaessig abdunkelt und den oberen Bildrand frei laesst. */}
{location} {t.footer.tagline} {intro} {t.home.hero.ctaPrimary} {t.home.hero.ctaSecondary} {footnote}
{/* Scroll-Hinweis: ein Tropfen loest sich aus einer Wabe. Rein dekorativ; bei reduzierter Bewegung steht er still. */}
); }