feat: manage skyline background media via payload

This commit is contained in:
syntaxbullet
2026-06-22 13:02:47 +02:00
parent 9cf23552cc
commit 34ef0e1f22
6 changed files with 32 additions and 11 deletions

View File

@@ -1,13 +1,23 @@
import React, { useEffect, useRef } from 'react';
import { mediaUrl } from '@/spa/cmsMediaField';
import { useCmsRoute } from '@/spa/cmsRoute';
import { defaultSiteSettings } from '@/spa/siteSettings';
/**
* MunichSkylineBg
* Drop inside any light section (position: relative required on parent).
* Uses backgroundPositionY for parallax – no transform, no GPU compositing layer.
* No mixBlendMode to avoid Safari compositing bleed into sibling elements.
*/
const MunichSkylineBg: React.FC = () => {
const MunichSkylineBg: React.FC<{ height?: string | number; inset?: boolean; opacity?: number }> = ({
height = '52%',
inset = false,
opacity = 0.08,
}) => {
const ref = useRef<HTMLDivElement>(null);
const siteSettings = useCmsRoute()?.siteSettings || defaultSiteSettings;
const skylineImage = mediaUrl(siteSettings.skylineImage, siteSettings.skylineImageUrl);
useEffect(() => {
const el = ref.current;
@@ -32,17 +42,14 @@ const MunichSkylineBg: React.FC = () => {
aria-hidden="true"
style={{
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: '52%',
...(inset ? { inset: 0 } : { bottom: 0, left: 0, right: 0, height }),
pointerEvents: 'none',
zIndex: 0,
backgroundImage: 'url(/munich-skyline.jpg)',
backgroundImage: `url(${skylineImage})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'bottom center',
backgroundSize: 'cover',
opacity: 0.08,
opacity,
}}
/>
);

View File

@@ -537,9 +537,7 @@ const Netzwerk: React.FC = () => {
{/* ── 3. JURY-INTRO (editorial 2-col split) ────────────────────────────── */}
<section style={{ display: isMobile ? 'block' : 'grid', gridTemplateColumns: isMobile ? undefined : '40% 60%', minHeight: isMobile ? 'auto' : 400, position: 'relative', overflow: 'hidden', isolation: 'isolate', background: isMobile ? NAVY : undefined }}>
{!isMobile && <MunichSkylineBg />}
{isMobile && (
<div aria-hidden style={{ position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 0, backgroundImage: 'url(/munich-skyline.jpg)', backgroundRepeat: 'no-repeat', backgroundPosition: 'bottom center', backgroundSize: 'cover', opacity: 0.07 }} />
)}
{isMobile && <MunichSkylineBg inset opacity={0.07} />}
{isMobile ? (
/* Mobile: one cohesive navy module – copy + compact stat strip */
<div style={{ padding: '48px 24px', position: 'relative', zIndex: 1 }}>

View File

@@ -2,12 +2,15 @@ export type SpaSiteSettingsData = {
genericPageKicker: string
genericPageTitle: string
genericPageDescription: string
skylineImage?: unknown
skylineImageUrl: string
}
export const defaultSiteSettings: SpaSiteSettingsData = {
genericPageKicker: 'CMS',
genericPageTitle: 'Seite',
genericPageDescription: 'Diese Route wird aus Payload CMS geladen. Ergänze Inhalte im entsprechenden Collection-Dokument.',
skylineImageUrl: '/munich-skyline.jpg',
}
export function normalizeSiteSettings(settings?: Partial<SpaSiteSettingsData> | null): SpaSiteSettingsData {