chore: migrate to payload / nextjs
This commit is contained in:
485
src/spa/pages/About.tsx
Normal file
485
src/spa/pages/About.tsx
Normal file
@@ -0,0 +1,485 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { Star, ChevronRight } from 'lucide-react';
|
||||
import TestimonialsSection from '@/spa/components/TestimonialsSection';
|
||||
import { Button } from '@/spa/components/ui/button';
|
||||
import { WINNERS } from '@/spa/data/winners';
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#E4E2E3';
|
||||
|
||||
// 8 highlight winners from 2025
|
||||
const HIGHLIGHTS = WINNERS.filter(w => w.year === 2025).slice(0, 8);
|
||||
|
||||
const About: React.FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<div className="animate-fade-in">
|
||||
|
||||
{/* ── 1. HERO ─────────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', minHeight: '72vh', display: 'flex', alignItems: 'flex-end', overflow: 'hidden', background: '#060C14' }}>
|
||||
<img
|
||||
src="/images/saal-leer-atmosphaere.jpg"
|
||||
alt="BMP Gala"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
{/* Left-to-right dark overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile ? 'linear-gradient(to top, rgba(2,9,48,0.95) 0%, rgba(2,9,48,0.72) 38%, rgba(2,9,48,0.22) 72%, transparent 100%)' : 'linear-gradient(to right, #020930 0%, rgba(2,9,48,0.90) 38%, rgba(2,9,48,0.18) 65%, transparent 100%)' }} />
|
||||
{/* Gold accent line */}
|
||||
<div style={{ position: 'absolute', top: 0, left: 80, width: 2, height: '100%', background: `linear-gradient(to bottom, transparent, ${GOLD}, transparent)`, opacity: 0.4 }} />
|
||||
{/* Gold bottom line */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.3), transparent)', zIndex: 2 }} />
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '0 24px 48px' : '0 80px 80px', maxWidth: 860 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 28 }}>
|
||||
<div style={{ width: 40, height: 2, background: GOLD }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: '#EFBF04' }}>
|
||||
Bayerischer Mittelstandspreis
|
||||
</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.6rem, 6vw, 5rem)' : 'clamp(2.8rem, 6vw, 5rem)', fontWeight: 900, color: '#fff', lineHeight: 0.95, letterSpacing: '-0.03em', textTransform: 'uppercase', margin: '0 0 28px' }}>
|
||||
WERTE, DIE<br />
|
||||
<span style={{ color: GOLD }}>BAYERN BEWEGEN</span>
|
||||
</h1>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.65)', lineHeight: 1.7, maxWidth: 560, margin: '0 0 40px', fontWeight: 300 }}>
|
||||
Seit 2005 ehrt der BMP herausragende Leistungen im bayerischen Mittelstand. Entdecken Sie die Geschichte, die Vision und die Menschen dahinter.
|
||||
</p>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 16 }}>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#fff', background: '#111D55', padding: '14px 28px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'background 0.15s, color 0.15s', border: '2px solid rgba(255,255,255,0.15)' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = GOLD; (e.currentTarget as HTMLElement).style.color = '#101828'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#111D55'; (e.currentTarget as HTMLElement).style.color = '#fff'; }}
|
||||
>
|
||||
Jetzt bewerben <ChevronRight size={16} />
|
||||
</Link>
|
||||
<Link
|
||||
to="/preistraeger"
|
||||
style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 28px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'background 0.15s, box-shadow 0.2s' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = GOLD; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Alle Preisträger <ChevronRight size={16} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats strip */}
|
||||
<div style={{ position: 'absolute', bottom: 0, right: 0, display: isMobile ? 'none' : 'flex', borderTop: '1px solid rgba(255,255,255,0.08)', borderLeft: '1px solid rgba(255,255,255,0.08)' }}>
|
||||
{[['20+', 'Jahre'], ['0 €', 'Teilnahme'], ['100%', 'Unabhängig']].map(([val, lbl], i) => (
|
||||
<div key={i} style={{ padding: '20px 36px', textAlign: 'center', borderRight: '1px solid rgba(255,255,255,0.08)' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 22, fontWeight: 900, color: GOLD }}>{val}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.15em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.4)', marginTop: 2 }}>{lbl}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 2a. WAS IST DER PREIS? (cream, text left / image right) ─────────── */}
|
||||
<section id="was-ist" style={{ position: 'relative', overflow: 'hidden', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 45%', minHeight: isMobile ? 'auto' : 580 }}>
|
||||
|
||||
{/* Left – text on cream */}
|
||||
<div style={{ background: CREAM, padding: isMobile ? '32px 24px 44px' : '88px 80px', display: 'flex', flexDirection: 'column', justifyContent: 'center', order: isMobile ? 2 : 0 }}>
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 20 }}>Was ist der Preis?</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2.1rem, 3.4vw, 3.1rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 20px' }}>
|
||||
DER BAYERISCHE<br />MITTELSTANDS<wbr />PREIS
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
<div style={{ width: 36, height: 2, background: GOLD, marginBottom: 28 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 19, color: 'rgba(16,24,40,0.8)', lineHeight: 1.8, maxWidth: 440, marginBottom: 16 }}>
|
||||
Seit 2005 ist der BMP eine der bedeutendsten Auszeichnungen für den bayerischen Mittelstand. Vergeben von einer vollständig unabhängigen Expertenjury, ehrt er Unternehmen, die durch Innovation, Nachhaltigkeit und regionale Verwurzelung herausragen.
|
||||
</p>
|
||||
<p style={{ fontFamily: FB, fontSize: 19, color: 'rgba(16,24,40,0.8)', lineHeight: 1.8, maxWidth: 440, marginBottom: isMobile ? 0 : 44 }}>
|
||||
Entstanden aus einer Initiative bayerischer Wirtschaftsvertreter, ehrt der Preis heute jährlich die Leuchttürme unserer Wirtschaft.
|
||||
</p>
|
||||
{/* Key facts – moved above the copy on mobile */}
|
||||
<div style={{ display: 'flex', order: isMobile ? -1 : 0, borderTop: isMobile ? 'none' : '1px solid #D0D5DD', borderBottom: isMobile ? '1px solid #D0D5DD' : 'none', marginBottom: isMobile ? 26 : 0 }}>
|
||||
{[
|
||||
{ val: '2005', label: 'Gegründet' },
|
||||
{ val: '0 €', label: 'Teilnahmegebühr' },
|
||||
{ val: '5', label: 'Jury-Schritte' },
|
||||
].map((f, i) => (
|
||||
<div key={i} style={{ flex: 1, padding: '20px 0', borderRight: i < 2 ? '1px solid #D0D5DD' : 'none', paddingLeft: 0, paddingRight: i < 2 ? 20 : 0 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(1.4rem, 2vw, 1.8rem)', fontWeight: 900, color: '#101828', letterSpacing: '-0.03em', lineHeight: 1 }}>{f.val}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.18em', marginTop: 6 }}>{f.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right – full-bleed image (+ heading on mobile) */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : undefined, order: isMobile ? 1 : 0 }}>
|
||||
<img
|
||||
src="/images/preistraeger-gruppe.jpg"
|
||||
alt="BMP Gala Preisverleihung"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile
|
||||
? 'linear-gradient(to top, rgba(3,9,58,0.94) 0%, rgba(3,9,58,0.55) 38%, rgba(3,9,58,0.12) 72%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.5) 0%, transparent 55%)'
|
||||
: `linear-gradient(to right, ${CREAM} 0%, transparent 25%), linear-gradient(to top, rgba(3,9,58,0.75) 0%, transparent 60%)` }} />
|
||||
{/* Heading overlay – mobile only */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 24px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#8FBEEC', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Was ist der Preis?</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.9rem, 8vw, 2.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.6)' }}>
|
||||
DER BAYERISCHE<br />MITTELSTANDS<wbr />PREIS
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
{/* Decorative label – desktop only */}
|
||||
{!isMobile && (
|
||||
<div style={{ position: 'absolute', bottom: 36, left: 36 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.22em', textTransform: 'uppercase', color: GOLD, marginBottom: 6 }}>BMP Preisverleihung · München</div>
|
||||
<div style={{ width: 28, height: 2, background: GOLD }} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── 2b. BEDEUTUNG FÜR DEN MITTELSTAND (navy, image left / text right) ── */}
|
||||
<section id="mittelstand" style={{ overflow: 'hidden' }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '45% 55%', minHeight: isMobile ? 'auto' : 580 }}>
|
||||
|
||||
{/* Left – full-bleed image (+ heading on mobile) */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : undefined }}>
|
||||
<img
|
||||
src="/images/networking-innenhof.jpg"
|
||||
alt="Bayerischer Mittelstand"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile
|
||||
? 'linear-gradient(to top, rgba(3,9,58,0.94) 0%, rgba(3,9,58,0.55) 38%, rgba(3,9,58,0.12) 72%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.5) 0%, transparent 55%)'
|
||||
: `linear-gradient(to left, ${NAVY} 0%, transparent 30%)` }} />
|
||||
{!isMobile && (
|
||||
<div style={{ position: 'absolute', top: 36, left: 36 }}>
|
||||
<div style={{ width: 2, height: 40, background: GOLD }} />
|
||||
</div>
|
||||
)}
|
||||
{/* Heading overlay – mobile only */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 24px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Relevanz & Zielsetzung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.9rem, 8vw, 2.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.6)' }}>
|
||||
BEDEUTUNG FÜR<br />DEN MITTELSTAND
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right – text on navy */}
|
||||
<div style={{ background: NAVY, padding: isMobile ? '32px 24px 40px' : '88px 80px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 20 }}>Relevanz & Zielsetzung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.2vw, 2.9rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 20px' }}>
|
||||
BEDEUTUNG FÜR<br />DEN MITTELSTAND
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
<div style={{ width: 36, height: 2, background: GOLD, marginBottom: 28 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.5)', lineHeight: 1.8, maxWidth: 440, marginBottom: 16 }}>
|
||||
Der Bayerische Mittelstandspreis ist weit mehr als eine Trophäe. Seit seiner Gründung im Jahr 2005 verfolgt er das Ziel, die Vielfalt und Leistungsstärke bayerischer Familienunternehmen und KMU sichtbar zu machen.
|
||||
</p>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.5)', lineHeight: 1.8, maxWidth: 440, marginBottom: 40 }}>
|
||||
In einer globalisierten Welt sind es diese Unternehmen, die für Stabilität, Innovation und soziale Verantwortung stehen. Der BMP macht sie sichtbar.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 3. PREISTRÄGER-HIGHLIGHTS ─────────────────────────────────────────── */}
|
||||
<section style={{ background: '#111D55' }}>
|
||||
{/* Section header */}
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '72px 80px 48px', display: 'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'flex-start' : 'flex-end', gap: isMobile ? 16 : 0, justifyContent: 'space-between', maxWidth: 1600, margin: '0 auto' }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: '#EFBF04', display: 'block', marginBottom: 12 }}>Preisträger-Highlights</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 4vw, 3rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', margin: 0, lineHeight: 1 }}>
|
||||
AUSGEZEICHNETE 2025
|
||||
</h2>
|
||||
</div>
|
||||
<Link
|
||||
to="/preistraeger"
|
||||
style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: GOLD, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6, paddingBottom: 4, borderBottom: `1px solid ${GOLD}`, whiteSpace: 'nowrap' }}
|
||||
>
|
||||
Alle Preisträger <ChevronRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* 4-col photo grid */}
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? undefined : 'repeat(4, 1fr)',
|
||||
gridAutoFlow: isMobile ? 'column' : undefined,
|
||||
gridTemplateRows: isMobile ? 'repeat(2, 1fr)' : undefined,
|
||||
gridAutoColumns: isMobile ? '66vw' : undefined,
|
||||
overflowX: isMobile ? 'auto' : undefined,
|
||||
scrollSnapType: isMobile ? 'x mandatory' : undefined,
|
||||
gap: isMobile ? 8 : 0,
|
||||
padding: isMobile ? '0 16px 8px' : 0,
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
scrollbarWidth: 'none',
|
||||
}}>
|
||||
{HIGHLIGHTS.map(w => <HighlightCard key={w.id} winner={w} />)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 4. TESTIMONIALS ──────────────────────────────────────────────────── */}
|
||||
<TestimonialsSection />
|
||||
|
||||
|
||||
{/* ── 5. GESCHICHTE & ZIELSETZUNG ──────────────────────────────────────── */}
|
||||
<section id="geschichte" style={{ overflow: 'hidden' }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', minHeight: isMobile ? 'auto' : 700 }}>
|
||||
|
||||
{/* LEFT – navy, timeline */}
|
||||
<div style={{ background: NAVY, padding: isMobile ? '56px 24px' : '88px 80px', position: 'relative', overflow: 'hidden' }}>
|
||||
{/* Ghost "20" watermark – desktop only */}
|
||||
{!isMobile && <div style={{ position: 'absolute', right: -24, bottom: -40, fontFamily: FF, fontSize: 'clamp(160px, 20vw, 240px)', fontWeight: 900, color: 'rgba(239,191,4,0.04)', lineHeight: 1, userSelect: 'none', pointerEvents: 'none', letterSpacing: '-0.04em' }}>20</div>}
|
||||
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Geschichte & Meilensteine</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3vw, 2.8rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 1.0, margin: '0 0 52px' }}>
|
||||
20 JAHRE<br /><span style={{ color: GOLD }}>MITTELSTANDS</span><wbr />EXZELLENZ
|
||||
</h2>
|
||||
|
||||
{/* Timeline */}
|
||||
<div style={{ position: 'relative', paddingLeft: 28 }}>
|
||||
{/* Vertical gold line */}
|
||||
<div style={{ position: 'absolute', left: 0, top: 6, bottom: 6, width: 2, background: `linear-gradient(to bottom, ${GOLD}, rgba(239,191,4,0.15))` }} />
|
||||
|
||||
{[
|
||||
{ year: '2005', title: 'Gründung', desc: 'Initiative bayerischer Wirtschaftsvertreter zur Stärkung des Mittelstands.' },
|
||||
{ year: '2010', title: 'Erste mediale Partnerschaft', desc: 'Kooperation mit bayernweiten TV- und Printmedien.' },
|
||||
{ year: '2015', title: '100 Preisträger', desc: 'Jubiläum: 100 ausgezeichnete Unternehmen seit der ersten Verleihung.' },
|
||||
{ year: '2020', title: 'Digital-Transformation', desc: 'Erweiterung um digitale Bewerbungsprozesse und Online-Formate.' },
|
||||
{ year: '2025', title: 'Jubiläumsjahr', desc: '20 Jahre BMP: stärker, sichtbarer und vernetzter denn je.' },
|
||||
{ year: '2026', title: 'Bavarian Future Award', desc: 'Ergänzung des Portfolios um den Bavarian Future Award mit Fokus auf zukunftsweisende Unternehmen.' },
|
||||
].map((item, i, arr) => (
|
||||
<div key={i} style={{ position: 'relative', marginBottom: i < arr.length - 1 ? 32 : 0 }}>
|
||||
{/* Gold dot */}
|
||||
<div style={{ position: 'absolute', left: -34, top: 7, width: 10, height: 10, background: GOLD, outline: `3px solid ${NAVY}`, outlineOffset: 1, transform: 'rotate(45deg)' }} />
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(1.05rem, 1.6vw, 1.35rem)', fontWeight: 900, color: GOLD, letterSpacing: '-0.02em', lineHeight: 1, marginBottom: 4 }}>{item.year}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 5 }}>{item.title}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.38)', lineHeight: 1.65 }}>{item.desc}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* RIGHT – cream, Zielsetzung */}
|
||||
<div style={{ background: '#EFE5E3', padding: isMobile ? '56px 24px' : '88px 80px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Zielsetzung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3vw, 2.8rem)', fontWeight: 900, color: NAVY, textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 1.0, margin: '0 0 40px' }}>
|
||||
WOFÜR WIR<br />STEHEN
|
||||
</h2>
|
||||
|
||||
<div>
|
||||
{[
|
||||
{ n: '01', title: 'Sichtbarkeit', desc: 'Die Vielfalt und Leistungsstärke des bayerischen Mittelstands in der Öffentlichkeit sichtbar machen.' },
|
||||
{ n: '02', title: 'Netzwerk', desc: 'Branchenübergreifende Verbindungen zwischen herausragenden Unternehmen und Entscheidern schaffen.' },
|
||||
{ n: '03', title: 'Werte', desc: 'Wertebasierte Führung, nachhaltige Unternehmenskultur und gesellschaftliche Verantwortung fördern.' },
|
||||
{ n: '04', title: 'Arbeitgebermarke', desc: 'Den Mittelstand als attraktiven Arbeitgeber stärken und Talente für Bayern gewinnen.' },
|
||||
{ n: '05', title: 'Resilienz', desc: 'Die Widerstandsfähigkeit bayerischer Unternehmen würdigen, die auch in unsicheren Zeiten Stabilität und Verantwortung beweisen.' },
|
||||
].map((item, i, arr) => (
|
||||
<div
|
||||
key={i}
|
||||
style={{ display: 'flex', gap: 24, alignItems: 'flex-start', padding: '24px 0', borderTop: '1px solid rgba(17,29,85,0.1)', borderBottom: i === arr.length - 1 ? '1px solid rgba(17,29,85,0.1)' : 'none', cursor: 'default' }}
|
||||
>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.12em', paddingTop: 3, flexShrink: 0, minWidth: 24 }}>{item.n}</span>
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 800, color: NAVY, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 7 }}>{item.title}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 16, color: 'rgba(17,29,85,0.5)', lineHeight: 1.75 }}>{item.desc}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── 5. VORTEILE & WERTE ──────────────────────────────────────────────── */}
|
||||
<section id="vorteile" style={{ background: CREAM, position: 'relative', overflow: 'hidden', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
{/* Header */}
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '88px 80px 56px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 16 : 40, alignItems: 'flex-end', borderBottom: '1px solid #D0D5DD' }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Vorteile & Werte</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.2vw, 2.9rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: 0 }}>
|
||||
WARUM DER<br />BMP ZÄHLT
|
||||
</h2>
|
||||
</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.8, margin: 0, maxWidth: 440 }}>
|
||||
Drei Dimensionen, die den Unterschied machen: für Ihr Unternehmen, Ihre Mitarbeitenden und Ihren Marktauftritt.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Editorial rows – no cards, pure typography */}
|
||||
{[
|
||||
{
|
||||
num: '01',
|
||||
title: 'Exzellenz-Siegel',
|
||||
},
|
||||
{
|
||||
num: '02',
|
||||
title: 'Partner-Netzwerk',
|
||||
},
|
||||
{
|
||||
num: '03',
|
||||
title: 'Reichweite',
|
||||
},
|
||||
].map((item, i, arr) => (
|
||||
<ValueRow key={i} item={item} last={i === arr.length - 1} />
|
||||
))}
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 5. CTA ───────────────────────────────────────────────────────────── */}
|
||||
<section style={{ background: NAVY, padding: isMobile ? '48px 24px' : '100px 80px', position: 'relative', overflow: 'hidden' }}>
|
||||
{/* Gold decorative lines */}
|
||||
<div style={{ position: 'absolute', top: 0, left: '50%', transform: 'translateX(-50%)', width: '60%', height: 1, background: `linear-gradient(to right, transparent, ${GOLD}, transparent)`, opacity: 0.3 }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: '50%', transform: 'translateX(-50%)', width: '40%', height: 1, background: `linear-gradient(to right, transparent, ${GOLD}, transparent)`, opacity: 0.15 }} />
|
||||
|
||||
<div style={{ textAlign: 'center', position: 'relative', zIndex: 1, maxWidth: 700, margin: '0 auto' }}>
|
||||
<div style={{ display: 'inline-flex', alignItems: 'center', gap: 10, marginBottom: 28 }}>
|
||||
<div style={{ width: 28, height: 1, background: GOLD, opacity: 0.6 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: '#EFBF04' }}>Starten Sie Ihre Reise</span>
|
||||
<div style={{ width: 28, height: 1, background: GOLD, opacity: 0.6 }} />
|
||||
</div>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2.2rem, 5vw, 3.5rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1, margin: '0 0 24px' }}>
|
||||
SCHREIBEN AUCH SIE GESCHICHTE
|
||||
</h2>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.55)', lineHeight: 1.8, marginBottom: 48, fontWeight: 300 }}>
|
||||
Werden Sie Teil der Wall of Fame des bayerischen Mittelstands. Die Teilnahmegebühr beträgt 0 EUR und die Teilnahme lohnt sich in jeder Phase.
|
||||
</p>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '16px 40px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 10, transition: 'background 0.15s, box-shadow 0.2s' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = GOLD; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Jetzt kostenlos bewerben <ChevronRight size={16} />
|
||||
</Link>
|
||||
<div style={{ marginTop: 16, display: 'flex', justifyContent: 'center' }}>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 11, color: 'rgba(255,255,255,0.3)', marginRight: 8 }}>Oder:</span>
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
style={{
|
||||
fontFamily: '"IBM Plex Sans", sans-serif',
|
||||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
color: 'rgba(239,191,4,0.7)',
|
||||
textDecoration: 'none',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
borderBottom: '1px solid rgba(239,191,4,0.3)',
|
||||
paddingBottom: 1,
|
||||
transition: 'color 0.15s, borderColor 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = '#EFBF04';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = '#EFBF04';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = 'rgba(239,191,4,0.7)';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = 'rgba(239,191,4,0.3)';
|
||||
}}
|
||||
>
|
||||
Vereinsmitglied werden <ChevronRight size={10} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── HighlightCard ─────────────────────────────────────────────────────────────
|
||||
|
||||
function HighlightCard({ winner }: { winner: import('@/spa/data/winners').Winner }) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<Link
|
||||
to={`/preistraeger/${winner.slug}`}
|
||||
style={{ textDecoration: 'none', display: 'block', position: 'relative', height: isMobile ? 220 : 280, overflow: 'hidden', scrollSnapAlign: isMobile ? 'start' : undefined }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<img
|
||||
src={winner.img}
|
||||
alt={winner.name}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transition: 'transform 0.6s ease', transform: hovered ? 'scale(1.07)' : 'scale(1)', filter: 'grayscale(15%)' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.1) 55%, transparent 100%)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.2)', opacity: hovered ? 1 : 0, transition: 'opacity 0.25s' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.06)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, padding: '18px 20px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 5 }}>
|
||||
<Star size={10} style={{ color: GOLD, flexShrink: 0 }} fill={GOLD} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.12em', textTransform: 'uppercase' }}>
|
||||
{winner.year} · {winner.type}
|
||||
</span>
|
||||
</div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', margin: '0 0 3px', lineHeight: 1.3, textShadow: '0 1px 4px rgba(0,0,0,0.5)' }}>
|
||||
{winner.name}
|
||||
</h3>
|
||||
<p style={{ fontFamily: FF, fontSize: 14, color: 'rgba(255,255,255,0.75)', margin: 0, letterSpacing: '0.03em' }}>
|
||||
{winner.category}
|
||||
</p>
|
||||
</div>
|
||||
{/* hover pill */}
|
||||
<div style={{ position: 'absolute', bottom: 16, right: 16, background: GOLD, color: '#101828', padding: '6px 14px', borderRadius: 999, fontSize: 10, fontFamily: FF, fontWeight: 800, letterSpacing: '0.1em', textTransform: 'uppercase', opacity: hovered ? 1 : 0, transform: hovered ? 'translateY(0)' : 'translateY(6px)', transition: 'all 0.25s' }}>
|
||||
Detail →
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// ── ValueRow ──────────────────────────────────────────────────────────────────
|
||||
|
||||
function ValueRow({ item, last }: { item: { num: string; title: string }; last: boolean }) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileRow = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid', gridTemplateColumns: isMobileRow ? '1fr' : '120px 1fr', gap: isMobileRow ? '16px 0' : '0 48px',
|
||||
padding: isMobileRow ? '32px 24px' : '48px 80px',
|
||||
borderBottom: last ? 'none' : '1px solid #D0D5DD',
|
||||
background: hovered ? '#EAE7E6' : 'transparent',
|
||||
transition: 'background 0.2s', cursor: 'default',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
{/* Left: number */}
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3vw, 2.8rem)', fontWeight: 900, color: hovered ? GOLD : 'rgba(16,24,40,0.1)', lineHeight: 1, letterSpacing: '-0.04em', transition: 'color 0.2s' }}>{item.num}</div>
|
||||
</div>
|
||||
{/* Right: title (short label only) */}
|
||||
<div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.3rem, 2vw, 1.8rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, margin: 0 }}>{item.title}</h3>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default About;
|
||||
300
src/spa/pages/BlogDetail.tsx
Normal file
300
src/spa/pages/BlogDetail.tsx
Normal file
@@ -0,0 +1,300 @@
|
||||
import React from 'react';
|
||||
import { useParams, Link } from '@/spa/router';
|
||||
import { ArrowLeft, Clock, User, Tag, ArrowRight } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { getArticleBySlug, articles } from '@/spa/data/blog';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#EFE5E3';
|
||||
const INK = '#3A3A3A';
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
|
||||
const CAT_COLORS: Record<string, string> = {
|
||||
Innovation: '#2563EB',
|
||||
Engagement: '#16A34A',
|
||||
Wirtschaft: '#9333EA',
|
||||
};
|
||||
|
||||
export default function BlogDetail() {
|
||||
const isMobile = useIsMobile();
|
||||
const { slug } = useParams<{ slug: string }>();
|
||||
const article = slug ? getArticleBySlug(slug) : undefined;
|
||||
|
||||
if (!article) {
|
||||
return (
|
||||
<div style={{ minHeight: '60vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 24, padding: '80px 24px', background: CREAM }}>
|
||||
<h2 style={{ fontFamily: FF, fontSize: '2rem', fontWeight: 900, color: NAVY }}>Artikel nicht gefunden</h2>
|
||||
<Link to="/presse" style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: NAVY, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
<ArrowLeft size={14} /> Zurück zur Presse
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const related = article.relatedSlugs
|
||||
.map(s => articles.find(a => a.slug === s))
|
||||
.filter(Boolean) as typeof articles;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
{/* ── HERO ──────────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', height: isMobile ? 'auto' : '70vh', minHeight: 520, overflow: 'hidden', display: 'flex', alignItems: 'flex-end' }}>
|
||||
<img
|
||||
src={article.img}
|
||||
alt={article.title}
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%' }}
|
||||
/>
|
||||
{/* Gradient overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, #111D55 0%, rgba(3,9,58,0.75) 45%, rgba(3,9,58,0.1) 100%)' }} />
|
||||
{/* Gold bottom line */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 3, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.3), transparent)` }} />
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 2, padding: isMobile ? '0 24px 48px' : '0 80px 72px', maxWidth: 860 }}>
|
||||
{/* Back link */}
|
||||
<Link
|
||||
to="/presse"
|
||||
style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8,
|
||||
fontFamily: FF, fontSize: 11, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.14em',
|
||||
color: 'rgba(255,255,255,0.5)', textDecoration: 'none',
|
||||
marginBottom: 32, transition: 'color 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = '#fff')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.5)')}
|
||||
>
|
||||
<ArrowLeft size={13} /> Newsroom
|
||||
</Link>
|
||||
|
||||
{/* Category badge */}
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<span style={{
|
||||
display: 'inline-block',
|
||||
padding: '4px 12px',
|
||||
fontFamily: FF, fontSize: 9, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.22em',
|
||||
background: CAT_COLORS[article.cat] ?? GOLD,
|
||||
color: '#fff',
|
||||
}}>
|
||||
{article.cat}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: isMobile ? 'clamp(1.6rem, 6vw, 2.4rem)' : 'clamp(2rem, 5vw, 3.8rem)',
|
||||
fontWeight: 900,
|
||||
color: '#fff',
|
||||
lineHeight: 1.05,
|
||||
letterSpacing: '-0.03em',
|
||||
textTransform: 'uppercase',
|
||||
margin: '0 0 28px',
|
||||
maxWidth: 760,
|
||||
}}
|
||||
>
|
||||
{article.title}
|
||||
</motion.h1>
|
||||
|
||||
{/* Meta row */}
|
||||
<div style={{ display: 'flex', gap: 28, flexWrap: 'wrap' }}>
|
||||
{[
|
||||
{ icon: User, label: `${article.author} · ${article.authorRole}` },
|
||||
{ icon: Clock, label: `${article.date} · ${article.readTime} Lesezeit` },
|
||||
].map(({ icon: Icon, label }, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.5)' }}>
|
||||
<Icon size={13} color={GOLD} /> {label}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── ARTICLE BODY ─────────────────────────────────────────────────── */}
|
||||
<section style={{ background: CREAM, padding: isMobile ? '48px 0 0' : '80px 0 0' }}>
|
||||
<div style={{ maxWidth: 1100, margin: '0 auto', padding: isMobile ? '0 24px' : '0 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 320px', gap: isMobile ? 40 : 80 }}>
|
||||
|
||||
{/* LEFT – article text */}
|
||||
<article>
|
||||
{/* Lead */}
|
||||
<p style={{
|
||||
fontFamily: FB, fontSize: 19, fontWeight: 300,
|
||||
color: INK, lineHeight: 1.75,
|
||||
borderLeft: `4px solid ${GOLD}`, paddingLeft: 28,
|
||||
marginBottom: 56,
|
||||
}}>
|
||||
{article.excerpt}
|
||||
</p>
|
||||
|
||||
{/* Sections */}
|
||||
{article.sections.map((section, idx) => (
|
||||
<motion.div
|
||||
key={idx}
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.4, delay: idx * 0.04 }}
|
||||
style={{ marginBottom: 48 }}
|
||||
>
|
||||
{section.heading && (
|
||||
<h2 style={{
|
||||
fontFamily: FF, fontSize: 'clamp(1.1rem, 1.8vw, 1.35rem)',
|
||||
fontWeight: 900, color: NAVY,
|
||||
textTransform: 'uppercase', letterSpacing: '-0.01em',
|
||||
marginBottom: 16,
|
||||
}}>
|
||||
{section.heading}
|
||||
</h2>
|
||||
)}
|
||||
<p style={{
|
||||
fontFamily: FB, fontSize: 18,
|
||||
color: 'rgba(58,58,58,0.8)', lineHeight: 1.8, margin: 0,
|
||||
}}>
|
||||
{section.body}
|
||||
</p>
|
||||
</motion.div>
|
||||
))}
|
||||
|
||||
{/* Tags */}
|
||||
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', padding: '40px 0', borderTop: '1px solid rgba(3,9,58,0.1)', marginTop: 24 }}>
|
||||
<Tag size={13} color='rgba(3,9,58,0.35)' style={{ marginTop: 2 }} />
|
||||
{article.tags.map(tag => (
|
||||
<span key={tag} style={{
|
||||
padding: '4px 12px',
|
||||
fontFamily: FF, fontSize: 10, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.12em',
|
||||
color: NAVY, background: 'rgba(3,9,58,0.07)',
|
||||
}}>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{/* RIGHT – sticky sidebar */}
|
||||
<aside>
|
||||
<div style={{ position: isMobile ? 'static' : 'sticky', top: isMobile ? undefined : 100 }}>
|
||||
|
||||
{/* Author card */}
|
||||
<div style={{ background: NAVY, padding: '28px 28px 32px', marginBottom: 24 }}>
|
||||
<div style={{ width: 48, height: 48, background: GOLD, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16 }}>
|
||||
<User size={22} color={NAVY} />
|
||||
</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', marginBottom: 4 }}>
|
||||
{article.author}
|
||||
</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 15, color: 'rgba(255,255,255,0.45)', lineHeight: 1.6 }}>
|
||||
{article.authorRole}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div style={{ background: '#fff', border: '1px solid rgba(3,9,58,0.1)', padding: '28px' }}>
|
||||
<div style={{ width: 32, height: 2, background: GOLD, marginBottom: 16 }} />
|
||||
<h4 style={{ fontFamily: FF, fontSize: 15, fontWeight: 900, color: NAVY, textTransform: 'uppercase', letterSpacing: '-0.01em', marginBottom: 12 }}>
|
||||
Jetzt bewerben
|
||||
</h4>
|
||||
<p style={{ fontFamily: FB, fontSize: 16, color: 'rgba(58,58,58,0.55)', lineHeight: 1.7, marginBottom: 20 }}>
|
||||
Ist Ihr Unternehmen bereit für den Bayerischen Mittelstandspreis 2026?
|
||||
</p>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
|
||||
padding: '13px 20px',
|
||||
background: NAVY, color: '#fff',
|
||||
fontFamily: FF, fontSize: 14, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.1em',
|
||||
textDecoration: 'none',
|
||||
transition: 'background 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = GOLD)}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = NAVY)}
|
||||
>
|
||||
Zur Bewerbung <ArrowRight size={12} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── RELATED ARTICLES ─────────────────────────────────────────────── */}
|
||||
{related.length > 0 && (
|
||||
<section style={{ background: NAVY, padding: isMobile ? '48px 0' : '80px 0' }}>
|
||||
<div style={{ maxWidth: 1100, margin: '0 auto', padding: isMobile ? '0 24px' : '0 80px' }}>
|
||||
|
||||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 20, marginBottom: 56 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.28em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.35)' }}>
|
||||
Weitere Artikel
|
||||
</span>
|
||||
<div style={{ flex: 1, height: 1, background: 'rgba(255,255,255,0.1)' }} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : `repeat(${related.length}, 1fr)`, gap: 0 }}>
|
||||
{related.map((rel, idx) => (
|
||||
<RelatedCard key={rel.slug} article={rel} bordered={isMobile ? false : idx > 0} isMobile={isMobile} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RelatedCard({ article, bordered, isMobile }: { article: ReturnType<typeof getArticleBySlug> & object; bordered: boolean; isMobile: boolean }) {
|
||||
const [hovered, setHovered] = React.useState(false);
|
||||
if (!article) return null;
|
||||
return (
|
||||
<Link
|
||||
to={`/presse/blog/${article.slug}`}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{
|
||||
display: 'flex', flexDirection: 'column',
|
||||
borderLeft: bordered && !isMobile ? '1px solid rgba(255,255,255,0.07)' : 'none',
|
||||
borderBottom: 'none',
|
||||
textDecoration: 'none',
|
||||
paddingLeft: bordered && !isMobile ? 40 : 0,
|
||||
paddingRight: isMobile ? 0 : 40,
|
||||
paddingBottom: isMobile ? 40 : 0,
|
||||
}}
|
||||
>
|
||||
{/* Thumbnail */}
|
||||
<div style={{ height: 180, overflow: 'hidden', marginBottom: 24 }}>
|
||||
<img
|
||||
src={article.img}
|
||||
alt={article.title}
|
||||
style={{
|
||||
width: '100%', height: '100%', objectFit: 'cover',
|
||||
filter: hovered ? 'none' : 'grayscale(80%)',
|
||||
transform: hovered ? 'scale(1.04)' : 'scale(1)',
|
||||
transition: 'filter 0.4s, transform 0.4s',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.22em', fontWeight: 700, marginBottom: 10 }}>
|
||||
{article.cat}
|
||||
</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1rem, 1.4vw, 1.15rem)', fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.01em', lineHeight: 1.25, marginBottom: 12 }}>
|
||||
{article.title}
|
||||
</h3>
|
||||
<div style={{ width: hovered ? 64 : 24, height: 1, background: 'rgba(239,191,4,0.5)', transition: 'width 0.35s', marginBottom: 14 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.38)', lineHeight: 1.7, flex: 1, marginBottom: 16 }}>
|
||||
{article.excerpt}
|
||||
</p>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: GOLD, display: 'inline-flex', alignItems: 'center', gap: 5 }}>
|
||||
Weiterlesen <ArrowRight size={12} />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
279
src/spa/pages/Contact.tsx
Normal file
279
src/spa/pages/Contact.tsx
Normal file
@@ -0,0 +1,279 @@
|
||||
import React, { useState } from 'react';
|
||||
import { MapPin, Mail, Phone, Clock, ChevronDown } from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import KontaktForm from '@/spa/components/forms/KontaktForm';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#EFE5E3';
|
||||
const INK = '#3A3A3A';
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
q: 'Was kostet die Teilnahme am BMP?',
|
||||
a: 'Die Teilnahme am Bayerischen Mittelstandspreis ist für alle Unternehmen vollständig kostenfrei. Wir finanzieren uns durch Partner und Sponsoren, um exzellenten Mittelstand ohne finanzielle Hürden zu fördern.',
|
||||
},
|
||||
{
|
||||
q: 'Nach welchen Kriterien wird bewertet?',
|
||||
a: 'Die Bewertung basiert auf vier Säulen: Zukunftsfähigkeit & Innovation, Nachhaltigkeit & Verantwortung, Unternehmenskultur sowie Regionale Verwurzelung. Jede Säule fließt mit 25 % in das Gesamtergebnis ein.',
|
||||
},
|
||||
{
|
||||
q: 'Wie läuft der Bewerbungsprozess ab?',
|
||||
a: 'Der Prozess ist mehrstufig: 1. Online-Bewerbung oder Vorschlag, 2. Formale Prüfung & erste Jury-Sichtung, 3. Fach-Audits bei den Finalisten vor Ort, 4. Finale Jury-Sitzung und abschließende Preisverleihung.',
|
||||
},
|
||||
{
|
||||
q: 'Wie lange dauert die Bewerbung?',
|
||||
a: 'Dank unseres optimierten Bewerbungsformulars benötigen Sie für die erste Einreichung ca. 30–45 Minuten. Tiefergehende Unterlagen werden erst in der Audit-Phase angefordert.',
|
||||
},
|
||||
];
|
||||
|
||||
const deadlines = [
|
||||
{ step: '01', label: 'Bewerbungsschluss', date: '30. Juni 2026', desc: 'Letzte Möglichkeit zur Einreichung Ihrer Unterlagen.' },
|
||||
{ step: '02', label: 'Nominierung', date: '15. August 2026', desc: 'Bekanntgabe der Nominierten nach Jury-Sichtung.' },
|
||||
{ step: '03', label: 'Preisverleihung', date: '22. Oktober 2026', desc: 'Festliche Gala in München.' },
|
||||
];
|
||||
|
||||
const Contact: React.FC = () => {
|
||||
const [openFaq, setOpenFaq] = useState<number | null>(0);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div style={{ background: CREAM }}>
|
||||
|
||||
{/* ── Hero ───────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', height: '68vh', minHeight: 520, overflow: 'hidden', display: 'flex', alignItems: 'flex-end' }}>
|
||||
<img
|
||||
src="/images/gala-dinner.jpg"
|
||||
alt="BMP Gala"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 40%' }}
|
||||
/>
|
||||
{/* Diagonal overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: `linear-gradient(105deg, ${NAVY} 0%, rgba(3,9,58,0.82) 35%, rgba(3,9,58,0.2) 70%, transparent 100%)` }} />
|
||||
{/* Bottom fade to navy contact section */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 160, background: `linear-gradient(to top, ${NAVY}, transparent)` }} />
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 2, width: '100%', paddingBottom: isMobile ? '3rem' : '5rem', paddingLeft: isMobile ? 24 : 80, paddingRight: isMobile ? 24 : 80 }}>
|
||||
<p style={{ fontSize: 11, fontWeight: 800, letterSpacing: '0.28em', textTransform: 'uppercase', color: GOLD, marginBottom: 16 }}>
|
||||
Dialog & Service
|
||||
</p>
|
||||
<h1 style={{ fontSize: isMobile ? 'clamp(2rem, 10vw, 3rem)' : 'clamp(3rem, 7vw, 6rem)', fontWeight: 900, lineHeight: 1.0, color: '#fff', letterSpacing: '-0.03em', marginBottom: 24, maxWidth: 640 }}>
|
||||
Wir sind<br />für Sie da.
|
||||
</h1>
|
||||
<p style={{ fontSize: 18, color: 'rgba(255,255,255,0.72)', maxWidth: 480, lineHeight: 1.65, fontWeight: 400 }}>
|
||||
Fragen zur Bewerbung, zur Gala oder zu Partnermöglichkeiten – unser Team begleitet Sie persönlich.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Contact + Form ─────────────────────────────────────────────── */}
|
||||
<section style={{ background: NAVY, position: 'relative', overflow: 'hidden' }}>
|
||||
{/* Decorative circles */}
|
||||
<div style={{ position: 'absolute', left: -120, bottom: -120, width: 480, height: 480, borderRadius: '50%', background: 'rgba(5,26,135,0.12)', pointerEvents: 'none' }} />
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr' }}>
|
||||
|
||||
{/* Left – info panel */}
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '88px 56px 88px 64px', display: 'flex', flexDirection: 'column', justifyContent: 'center', position: 'relative' }}>
|
||||
<p style={{ fontSize: 10, fontWeight: 800, letterSpacing: '0.28em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.4)', marginBottom: 20 }}>
|
||||
Direktkontakt
|
||||
</p>
|
||||
<div style={{ width: 36, height: 2, background: GOLD, marginBottom: 20 }} />
|
||||
<h2 style={{ fontSize: 'clamp(1.6rem, 3vw, 2.4rem)', fontWeight: 900, color: '#fff', lineHeight: 1.15, letterSpacing: '-0.03em', marginBottom: 52 }}>
|
||||
Kontakt­möglichkeiten
|
||||
</h2>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
|
||||
{[
|
||||
{ icon: MapPin, title: 'Geschäftsstelle', lines: ['Maximilianstraße 42', '80538 München'] },
|
||||
{ icon: Mail, title: 'E-Mail', lines: ['info@bmp-bayern.de'] },
|
||||
{ icon: Phone, title: 'Telefon', lines: ['+49 89 123 456 78'] },
|
||||
{ icon: Clock, title: 'Bürozeiten', lines: ['Mo – Fr: 09:00 – 17:00 Uhr'] },
|
||||
].map(({ icon: Icon, title, lines }, i) => (
|
||||
<div key={i} style={{ display: 'flex', gap: 18, alignItems: 'flex-start' }}>
|
||||
<div style={{ width: 40, height: 40, borderRadius: 8, background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.08)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||||
<Icon size={17} color="rgba(255,255,255,0.80)" />
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, color: 'rgba(255,255,255,0.40)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 4 }}>{title}</div>
|
||||
{lines.map((l, j) => <div key={j} style={{ fontSize: 17, color: '#fff', fontWeight: 500, lineHeight: 1.5 }}>{l}</div>)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 52, paddingTop: 28, borderTop: '1px solid rgba(255,255,255,0.10)' }}>
|
||||
<p style={{ fontSize: 15, color: 'rgba(255,255,255,0.40)', lineHeight: 1.65 }}>
|
||||
Nächste Preisverleihung: <strong style={{ color: '#fff' }}>22. Oktober 2026</strong>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
{!isMobile && <div style={{ background: 'rgba(255,255,255,0.07)' }} />}
|
||||
|
||||
{/* Right – gold form panel */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: isMobile ? 'visible' : 'hidden', height: isMobile ? 'auto' : undefined, minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 0 }} aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="kontaktCross" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
<path d="M0,0 L18,18 M18,0 L0,18" stroke="rgba(17,29,85,0.055)" strokeWidth="0.65" />
|
||||
</pattern>
|
||||
<pattern id="kontaktDiamond" width="36" height="36" patternUnits="userSpaceOnUse">
|
||||
<polygon points="18,2 34,18 18,34 2,18" fill="none" stroke="rgba(17,29,85,0.045)" strokeWidth="0.6" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#kontaktCross)" />
|
||||
<rect width="100%" height="100%" fill="url(#kontaktDiamond)" />
|
||||
</svg>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at center, transparent 55%, rgba(100,70,0,0.25) 100%)', pointerEvents: 'none', zIndex: 0 }} />
|
||||
|
||||
{!isMobile && (
|
||||
<div style={{ height: 200, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
||||
<img src="/images/preistraeger-gruppe.jpg" alt="BMP Gala 2025" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%', filter: 'sepia(0.18) brightness(0.92)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 14, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ width: 5, height: 5, borderRadius: '50%', background: 'rgba(17,29,85,0.7)' }} />
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, fontWeight: 700, color: 'rgba(17,29,85,0.75)', textTransform: 'uppercase', letterSpacing: '0.2em' }}>Gala 2025 München</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ padding: isMobile ? '36px 20px' : '32px 48px 32px 40px', flex: isMobile ? 'none' : 1, display: 'flex', flexDirection: 'column', minHeight: isMobile ? 480 : 0, position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, color: 'rgba(17,29,85,0.5)', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 8 }}>Kontaktformular</span>
|
||||
<h3 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(1.2rem, 1.8vw, 1.6rem)', fontWeight: 900, color: '#111D55', letterSpacing: '-0.025em', textTransform: 'uppercase', lineHeight: 1.1, marginBottom: 24 }}>
|
||||
Schreiben Sie uns
|
||||
</h3>
|
||||
<KontaktForm theme="gold" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Deadlines ──────────────────────────────────────────────────── */}
|
||||
<section style={{ background: '#0D1640', padding: isMobile ? '56px 0' : '88px 0', position: 'relative', overflow: 'hidden' }}>
|
||||
<div style={{ position: 'absolute', right: -20, top: '50%', transform: 'translateY(-50%)', fontSize: 'clamp(160px, 22vw, 280px)', fontWeight: 900, color: '#fff', opacity: 0.025, lineHeight: 1, pointerEvents: 'none', userSelect: 'none', letterSpacing: '-0.05em' }}>
|
||||
2026
|
||||
</div>
|
||||
<div className="container mx-auto px-6" style={{ position: 'relative' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 20, marginBottom: isMobile ? 48 : 72 }}>
|
||||
<span style={{ fontSize: 10, fontWeight: 800, letterSpacing: '0.28em', textTransform: 'uppercase', color: '#EFBF04', whiteSpace: 'nowrap' }}>
|
||||
Fahrplan 2026
|
||||
</span>
|
||||
<div style={{ flex: 1, height: 1, background: 'rgba(255,255,255,0.10)' }} />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, 1fr)', gap: 0 }}>
|
||||
{deadlines.map((item, i) => (
|
||||
<div key={i} style={isMobile ? {
|
||||
paddingTop: i > 0 ? 36 : 0,
|
||||
paddingBottom: i < deadlines.length - 1 ? 36 : 0,
|
||||
borderBottom: i < deadlines.length - 1 ? '1px solid rgba(255,255,255,0.10)' : 'none',
|
||||
} : {
|
||||
paddingRight: i < deadlines.length - 1 ? 48 : 0,
|
||||
paddingLeft: i > 0 ? 48 : 0,
|
||||
borderRight: i < deadlines.length - 1 ? '1px solid rgba(255,255,255,0.10)' : 'none',
|
||||
}}>
|
||||
<div style={{ fontSize: 10, fontWeight: 800, letterSpacing: '0.2em', color: `rgba(239,191,4,0.5)`, marginBottom: 18, fontVariantNumeric: 'tabular-nums' }}>
|
||||
{item.step}
|
||||
</div>
|
||||
<div style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'rgba(255,255,255,0.45)', marginBottom: 12 }}>
|
||||
{item.label}
|
||||
</div>
|
||||
<div style={{ fontSize: 'clamp(1.4rem, 2.5vw, 2rem)', fontWeight: 900, color: '#fff', letterSpacing: '-0.03em', lineHeight: 1.1, marginBottom: 16 }}>
|
||||
{item.date}
|
||||
</div>
|
||||
<div style={{ fontSize: 16, color: 'rgba(255,255,255,0.45)', lineHeight: 1.7 }}>
|
||||
{item.desc}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── FAQ ────────────────────────────────────────────────────────── */}
|
||||
<section id="faq" style={{ background: CREAM, padding: isMobile ? '56px 0 72px' : '96px 0 112px' }}>
|
||||
<div className="container mx-auto px-6">
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 2fr', gap: isMobile ? 40 : 80 }}>
|
||||
|
||||
{/* Left – sticky label */}
|
||||
<div style={isMobile ? undefined : { position: 'sticky', top: 96, alignSelf: 'start' }}>
|
||||
<p style={{ fontSize: 10, fontWeight: 800, letterSpacing: '0.28em', textTransform: 'uppercase', color: '#4A8FC9', marginBottom: 20 }}>
|
||||
Antworten
|
||||
</p>
|
||||
<div style={{ width: 28, height: 2, background: GOLD, marginBottom: 20 }} />
|
||||
<h2 style={{ fontSize: isMobile ? 'clamp(1.8rem, 8vw, 2.4rem)' : 'clamp(2rem, 3.5vw, 2.8rem)', fontWeight: 900, color: NAVY, letterSpacing: '-0.03em', lineHeight: 1.1 }}>
|
||||
Häufige<br />Fragen
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{/* Right – accordion */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
{faqs.map((faq, idx) => {
|
||||
const isOpen = openFaq === idx;
|
||||
return (
|
||||
<div
|
||||
key={idx}
|
||||
style={{
|
||||
background: isOpen ? '#fff' : 'transparent',
|
||||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
transition: 'background 0.2s',
|
||||
border: isOpen ? `1.5px solid rgba(17,29,85,0.12)` : '1.5px solid rgba(17,29,85,0.08)',
|
||||
}}
|
||||
>
|
||||
<button
|
||||
onClick={() => setOpenFaq(isOpen ? null : idx)}
|
||||
style={{
|
||||
width: '100%', padding: '22px 24px',
|
||||
display: 'flex', justifyContent: 'space-between', alignItems: 'center',
|
||||
background: 'none', border: 'none', cursor: 'pointer', textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 17, fontWeight: 700, color: isOpen ? NAVY : INK, flex: 1, paddingRight: 20, lineHeight: 1.4 }}>
|
||||
{faq.q}
|
||||
</span>
|
||||
<div style={{
|
||||
width: 30, height: 30, borderRadius: '50%', flexShrink: 0,
|
||||
background: isOpen ? NAVY : 'rgba(17,29,85,0.08)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
transition: 'all 0.2s',
|
||||
}}>
|
||||
<ChevronDown
|
||||
size={15}
|
||||
color={isOpen ? '#fff' : NAVY}
|
||||
style={{ transform: isOpen ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s' }}
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<AnimatePresence initial={false}>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
key="content"
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
exit={{ height: 0, opacity: 0 }}
|
||||
transition={{ duration: 0.22, ease: 'easeInOut' }}
|
||||
style={{ overflow: 'hidden' }}
|
||||
>
|
||||
<div style={{ padding: '0 24px 24px', fontSize: 17, color: 'rgba(58,58,58,0.72)', lineHeight: 1.75 }}>
|
||||
{faq.a}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Contact;
|
||||
270
src/spa/pages/Datenschutz.tsx
Normal file
270
src/spa/pages/Datenschutz.tsx
Normal file
@@ -0,0 +1,270 @@
|
||||
import React from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const ANTHRA = '#1A2030';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#EFE5E3';
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
|
||||
const TOC = [
|
||||
{ id: 'verantwortlicher', label: 'Verantwortlicher' },
|
||||
{ id: 'datenschutz-allgemein', label: 'Datenschutz & Datenverarbeitung' },
|
||||
{ id: 'kontaktformular', label: 'Kontaktformular & E-Mail' },
|
||||
{ id: 'betroffenenrechte', label: 'Betroffenenrechte' },
|
||||
{ id: 'aufsichtsbehoerde', label: 'Beschwerderecht' },
|
||||
{ id: 'privacy-policy', label: 'Privacy Policy' },
|
||||
{ id: 'recaptcha', label: 'Google reCAPTCHA' },
|
||||
{ id: 'webanalyse', label: 'Webseitenanalyse' },
|
||||
];
|
||||
|
||||
const ADDR = (
|
||||
<>
|
||||
VM Verbands-Management GmbH<br />
|
||||
Edelsbergstr. 8<br />
|
||||
80686 München<br />
|
||||
Tel. +49 (0) 89 – 57007-0<br />
|
||||
Fax +49 (0) 89 – 57007 260<br />
|
||||
info@vm-verbands-management.de<br />
|
||||
HRB 110222 AG München, gesetzl. vertreten durch Friedrich Marx
|
||||
</>
|
||||
);
|
||||
|
||||
export default function Datenschutz() {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div style={{ background: CREAM, minHeight: '100vh' }}>
|
||||
|
||||
{/* ── HERO ──────────────────────────────────────────────────────────── */}
|
||||
<section style={{ background: ANTHRA, padding: isMobile ? '48px 24px 40px' : '64px 80px 52px', position: 'relative', overflow: 'hidden' }}>
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.2), transparent)` }} />
|
||||
<Link
|
||||
to="/"
|
||||
style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.18em', color: 'rgba(255,255,255,0.4)', textDecoration: 'none', marginBottom: 32, transition: 'color 0.15s' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = '#fff')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.4)')}
|
||||
>
|
||||
<ArrowLeft size={12} /> Zurück zur Website
|
||||
</Link>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
|
||||
<div style={{ width: 32, height: 2, background: GOLD }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.35em', textTransform: 'uppercase', color: GOLD }}>Legal</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontWeight: 900, fontSize: isMobile ? 'clamp(1.8rem, 7vw, 2.6rem)' : 'clamp(2.4rem, 4vw, 3.2rem)', color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.02, margin: '0 0 12px' }}>
|
||||
Datenschutz­erklärung
|
||||
</h1>
|
||||
<p style={{ fontFamily: FB, fontSize: 15, color: 'rgba(255,255,255,0.45)', margin: 0 }}>
|
||||
Zuletzt aktualisiert: April 2026 · <Link to="/impressum" style={{ color: 'rgba(239,191,4,0.7)', textDecoration: 'none' }}>Zum Impressum →</Link>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* ── BODY ──────────────────────────────────────────────────────────── */}
|
||||
<div style={{ maxWidth: 1100, margin: '0 auto', padding: isMobile ? '40px 24px' : '64px 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '200px 1fr', gap: isMobile ? 40 : 80, alignItems: 'start' }}>
|
||||
|
||||
{/* LEFT – sticky TOC */}
|
||||
{!isMobile && (
|
||||
<nav style={{ position: 'sticky', top: 80 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.28em', textTransform: 'uppercase', color: GOLD, marginBottom: 16 }}>Inhalt</div>
|
||||
<ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
{TOC.map(item => (
|
||||
<li key={item.id}>
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
style={{ display: 'block', fontFamily: FB, fontSize: 12, color: 'rgba(17,29,85,0.5)', textDecoration: 'none', padding: '5px 0 5px 12px', borderLeft: '2px solid transparent', transition: 'color 0.15s, border-color 0.15s', lineHeight: 1.4 }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = NAVY; (e.currentTarget as HTMLElement).style.borderLeftColor = GOLD; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = 'rgba(17,29,85,0.5)'; (e.currentTarget as HTMLElement).style.borderLeftColor = 'transparent'; }}
|
||||
>{item.label}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div style={{ marginTop: 32, paddingTop: 20, borderTop: '1px solid rgba(17,29,85,0.1)' }}>
|
||||
<Link to="/impressum" style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.14em', color: NAVY, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
Zum Impressum →
|
||||
</Link>
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
{/* RIGHT – content */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 56 }}>
|
||||
|
||||
<Section id="verantwortlicher" title="Verantwortlicher">
|
||||
<p style={body}>Name und Anschrift des für die Verarbeitung Verantwortlichen im Sinne der Datenschutz-Grundverordnung:</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
</Section>
|
||||
|
||||
<Section id="datenschutz-allgemein" title="Datenschutz & Datenverarbeitung">
|
||||
<p style={body}>Alle personenbezogenen Informationen werden vertraulich und gemäß den gesetzlichen Vorschriften behandelt. Den Schutz der persönlichen Daten nehmen wir als Webseitenbetreiber sehr ernst.</p>
|
||||
<p style={body}>Ein Besuch unserer Webseiten ist möglich, ohne Angaben zu Ihrer Person zu machen. Es werden bei jedem Zugriff auf unsere Website Nutzungsdaten durch Ihren Internetbrowser übermittelt und in Protokolldaten (Server-Logfiles) gespeichert. Zu diesen gespeicherten Daten gehören z. B. Name der aufgerufenen Seite, Datum und Uhrzeit des Abrufs, übertragene Datenmenge und der anfragende Provider (IP-Adresse). Diese Daten dienen ausschließlich der Gewährleistung eines störungsfreien Betriebs unserer Website und zur Verbesserung unseres Angebotes. Eine Zuordnung dieser Daten zu einer bestimmten Person ist nicht möglich.</p>
|
||||
<p style={body}>Es erfolgt keine Zusammenführung dieser Daten mit anderen Datenquellen.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="kontaktformular" title="Kontaktformular & E-Mail">
|
||||
<p style={body}>Sofern Sie uns über unsere Kontaktdaten eine E-Mail übersenden bzw. uns über das Kontaktformular informieren, erheben wir Ihre personenbezogenen Daten (Name, E-Mail-Adresse, Telefonnummer, Betreff, Nachrichtentext) nur in dem von Ihnen zur Verfügung gestellten Umfang. Die Datenverarbeitung dient dem Zweck der Kontaktaufnahme.</p>
|
||||
<p style={body}>Mit Absenden Ihrer Nachricht willigen Sie in die Verarbeitung der übermittelten Daten ein.</p>
|
||||
<Legal>Eine Verarbeitung erfolgt auf Grundlage des Art. 6 (1) lit. a DSGVO mit Ihrer Einwilligung.</Legal>
|
||||
<p style={body}>Sie können diese Einwilligung jederzeit durch Mitteilung an uns widerrufen, ohne dass die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Verarbeitung berührt wird. Ihre E-Mail-Adresse wird nur zur Bearbeitung Ihrer Anfrage genutzt. Ihre Daten werden anschließend gelöscht, sofern Sie der weitergehenden Verarbeitung und Nutzung nicht zugestimmt haben.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="betroffenenrechte" title="Betroffenenrechte">
|
||||
<p style={body}>Bei Vorliegen der gesetzlichen Voraussetzungen stehen Ihnen folgende Rechte nach Art. 15 bis 20 DSGVO zu:</p>
|
||||
<ul style={{ ...body, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<li>Recht auf Auskunft</li>
|
||||
<li>Recht auf Berichtigung</li>
|
||||
<li>Recht auf Löschung</li>
|
||||
<li>Recht auf Einschränkung der Verarbeitung</li>
|
||||
<li>Recht auf Datenübertragbarkeit</li>
|
||||
</ul>
|
||||
<Legal>Außerdem steht Ihnen nach Art. 21 (1) DSGVO ein Widerspruchsrecht gegen die Verarbeitungen zu, die auf Art. 6 (1) f DSGVO beruhen, sowie gegen die Verarbeitung zum Zwecke von Direktwerbung.</Legal>
|
||||
<p style={body}>Auf Wunsch können Sie uns kontaktieren. Die Kontaktdaten finden Sie in unserem <Link to="/impressum" style={{ color: NAVY, fontWeight: 600 }}>Impressum</Link> bzw. unter <Link to="/kontakt" style={{ color: NAVY, fontWeight: 600 }}>Kontakt</Link>.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="aufsichtsbehoerde" title="Beschwerderecht bei der Aufsichtsbehörde">
|
||||
<p style={body}>Sie haben gemäß Art. 77 DSGVO das Recht, sich bei der Aufsichtsbehörde zu beschweren, wenn Sie der Ansicht sind, dass die Verarbeitung Ihrer personenbezogenen Daten nicht rechtmäßig erfolgt.</p>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY }}>Die zuständige Aufsichtsbehörde:</p>
|
||||
<AddressBlock>
|
||||
Bayerisches Landesamt für Datenschutzaufsicht<br />
|
||||
Postfach 606<br />
|
||||
91511 Ansbach<br />
|
||||
Deutschland<br />
|
||||
Tel. 09853-1300<br />
|
||||
Fax 09853-981300<br />
|
||||
E-Mail: poststelle@lda.bayern.de
|
||||
</AddressBlock>
|
||||
</Section>
|
||||
|
||||
<Section id="privacy-policy" title="Privacy Policy (Erklärung zum Datenschutz)">
|
||||
<p style={{ ...body, fontStyle: 'italic', borderLeft: `3px solid ${GOLD}`, paddingLeft: 16, marginBottom: 32 }}>
|
||||
Die Betreiber des Portals nehmen den Schutz der privaten Daten ernst. Persönliche Daten werden gemäß den Bestimmungen des Bundesdatenschutzgesetzes BDSG verwendet; die Betreiber verpflichten sich zur Verschwiegenheit. Diese Webseiten können Links zu Webseiten anderer Anbieter enthalten, auf die sich diese Datenschutzerklärung nicht erstreckt.
|
||||
</p>
|
||||
|
||||
<SubSection num="1" title="Personenbezogene Daten">
|
||||
<p style={body}>Personenbezogene Daten sind Informationen, die dazu genutzt werden können, die Identität zu erfahren. Darunter fallen Informationen wie richtiger Name, Adresse, Postanschrift, Telefonnummer. Informationen, die nicht direkt mit der wirklichen Identität in Verbindung gebracht werden, fallen nicht darunter.</p>
|
||||
<p style={body}>Wir nutzen die persönlichen Daten zu Zwecken der technischen Administration der Webseiten und zur Kundenverwaltung nur im jeweils dafür erforderlichen Umfang. Darüber hinaus werden persönliche Daten nur dann gespeichert, wenn diese freiwillig angegeben werden.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="2" title="Weitergabe personenbezogener Daten">
|
||||
<p style={body}>Wir verwenden personenbezogene Informationen nur für diese Webseite. Wir geben die Informationen nicht ohne ausdrückliches Einverständnis an Dritte weiter. Sollten im Rahmen der Auftragsdatenverarbeitung Daten an Dienstleister weitergegeben werden, so sind diese an das BDSG und diese Privacy Policy gebunden.</p>
|
||||
<p style={body}>Erhebungen bzw. Übermittlungen persönlicher Daten an staatliche Einrichtungen und Behörden erfolgen nur im Rahmen zwingender Rechtsvorschriften.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="3" title="Kinder">
|
||||
<p style={body}>Personen unter 18 Jahren sollten ohne Zustimmung der Eltern oder Erziehungsberechtigten keine personenbezogenen Daten an uns übermitteln. Wir fordern keine personenbezogenen Daten von Kindern an, sammeln diese nicht und geben sie nicht an Dritte weiter.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="4" title="Recht auf Widerruf">
|
||||
<p style={body}>Wenn Sie uns personenbezogene Daten überlassen haben, können Sie diese jederzeit wieder ändern und löschen lassen. Für eine vollständige Löschung wenden Sie sich bitte an den Webmaster.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="5" title="Links zu anderen Websites">
|
||||
<p style={body}>Unser Online-Angebot enthält Links zu anderen Websites. Wir haben keinen Einfluss darauf, dass deren Betreiber die Datenschutzbestimmungen einhalten.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="6" title="Beiträge">
|
||||
<p style={body}>Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. Für den Inhalt der verlinkten Seiten sind ausschließlich deren Betreiber verantwortlich. Alle hier verwendeten Namen, Begriffe, Zeichen und Grafiken können Marken- oder Warenzeichen im Besitze ihrer rechtlichen Eigentümer sein.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="7" title="Fragen und Kommentare">
|
||||
<p style={body}>Bei Fragen und für Anregungen zum Thema Datenschutz bitte per Mail an den Webmaster wenden.</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
</SubSection>
|
||||
</Section>
|
||||
|
||||
<Section id="recaptcha" title="Spamschutz mit Google reCAPTCHA">
|
||||
<p style={body}>Wir haben Google reCAPTCHA in Formularen auf unserer Webseite implementiert, um zu überprüfen, ob die in den Formularen eingegebenen Daten von menschlichen Besuchern stammen oder von Maschinen bzw. automatisierten Programmen („Bots").</p>
|
||||
<p style={body}>Dieses Tool analysiert automatisch das Verhalten der Webseitenbesucher, sobald sie mit der Webseite interagieren, unter Verwendung verschiedener Informationen wie IP-Adresse, Aufenthaltsdauer und Mausbewegungen.</p>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY, marginBottom: 8 }}>Verarbeitete Daten</p>
|
||||
<ul style={{ ...body, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 16 }}>
|
||||
<li>Nutzungsdaten: aufgerufene Webseite, Datum und Uhrzeit des Zugriffs, Mausbewegungen</li>
|
||||
<li>Kommunikationsdaten: IP-Adresse, Browsertyp, Betriebssystem</li>
|
||||
</ul>
|
||||
<p style={body}>Der Hauptzweck dieser Verarbeitung besteht darin, den Missbrauch unseres Kontaktformulars zu verhindern und dadurch die Sicherheit zu erhöhen.</p>
|
||||
<Legal>Rechtsgrundlage: berechtigtes Interesse gemäß Art. 6 Abs. 1 S. 1 lit. f. DSGVO</Legal>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY, marginBottom: 8 }}>Datenempfänger</p>
|
||||
<AddressBlock>
|
||||
Google Ireland Ltd<br />
|
||||
Google Building Gordon House, Barrow St<br />
|
||||
Dublin 4, Irland<br />
|
||||
Datenschutzerklärung: https://policies.google.com/privacy
|
||||
</AddressBlock>
|
||||
<p style={body}>Während Ihre persönlichen Daten innerhalb der EU verarbeitet werden, wird die Aufbewahrungsfrist für die verarbeiteten Daten von Google Ireland Limited bestimmt. Weitere Informationen finden Sie in der Datenschutzerklärung von Google reCAPTCHA unter <a href="https://policies.google.com/privacy" target="_blank" rel="noopener noreferrer" style={{ color: NAVY }}>policies.google.com/privacy</a>.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="webanalyse" title="Webseitenanalyse (Jimdo Statistiken)">
|
||||
<p style={body}>Wenn Sie unsere Website besuchen, sammeln wir Informationen über Ihre Nutzung durch ein Webanalyse-Tool, das von unserem Hosting-Service bereitgestellt wird. Dieses Tool sammelt und kombiniert Ihre IP-Adresse und Ihren User Agent, verkürzt sie und speichert diese Daten mit einer Hash-Funktion.</p>
|
||||
<p style={body}>Durch diesen Vorgang wird eine Besucherkennung erstellt, die mit einem zufällig generierten Wert (SALT) verschlüsselt ist, der sich alle 24 Stunden ändert. Diese Methode stellt sicher, dass Ihre IP-Adresse nicht aus dem gespeicherten Besucheridentifikator rekonstruiert werden kann, sodass Ihre Anonymität gewahrt bleibt. Außerdem führen wir diese Informationen nicht mit anderen Daten zusammen und sie werden nur auf dem Server des Hosting-Anbieters gespeichert.</p>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY, marginBottom: 8 }}>Verarbeitete Daten</p>
|
||||
<ul style={{ ...body, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 16 }}>
|
||||
<li>Webanalysedaten: Seitenaufrufe, Besuchshäufigkeit, Verweildauer auf jeder Seite, User Agent</li>
|
||||
<li>HTTP-Daten & Nutzungsdaten: besuchte Webseiten, Zugriffszeiten</li>
|
||||
<li>Kommunikationsdaten: Browsertyp, Betriebssystem, IP-Adressen</li>
|
||||
</ul>
|
||||
<p style={body}>Mit der Verarbeitung dieser Daten wollen wir das Nutzerverhalten in zusammengefasster Form analysieren, um die Darstellung und den Inhalt unserer Website zu verbessern.</p>
|
||||
<Legal>Rechtsgrundlage: berechtigtes Interesse gemäß Art. 6 Abs. 1 lit. f. DSGVO – insbesondere an der Durchführung von Webmessungen zur Verbesserung unserer Website.</Legal>
|
||||
<p style={body}>Die erhobenen Daten werden mit unserem Website-Hosting-Anbieter geteilt und innerhalb der EU verarbeitet.</p>
|
||||
</Section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── shared styles ── */
|
||||
const body: React.CSSProperties = {
|
||||
fontFamily: '"Inter", sans-serif',
|
||||
fontSize: 15,
|
||||
color: 'rgba(58,58,58,0.82)',
|
||||
lineHeight: 1.85,
|
||||
margin: '0 0 16px',
|
||||
overflowWrap: 'anywhere',
|
||||
};
|
||||
|
||||
function Section({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {
|
||||
return (
|
||||
<div id={id} style={{ scrollMarginTop: 80 }}>
|
||||
<div style={{ borderLeft: `3px solid ${GOLD}`, paddingLeft: 16, marginBottom: 28 }}>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.2em', color: NAVY, margin: 0 }}>
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
<div style={{ background: '#fff', padding: 'clamp(20px, 5vw, 28px) clamp(20px, 5vw, 32px)', boxShadow: '0 1px 3px rgba(0,0,0,0.06)' }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SubSection({ num, title, children }: { num: string; title: string; children: React.ReactNode }) {
|
||||
return (
|
||||
<div style={{ marginBottom: 28 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 10 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.12em' }}>{num}.</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: NAVY, margin: 0 }}>{title}</h3>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AddressBlock({ children }: { children: React.ReactNode }) {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<address style={{ fontFamily: '"Inter", sans-serif', fontSize: isMobile ? 15 : 14, color: 'rgba(58,58,58,0.75)', lineHeight: 1.9, fontStyle: 'normal', background: 'rgba(17,29,85,0.04)', padding: '16px 20px', borderLeft: '2px solid rgba(239,191,4,0.4)', marginBottom: 16, overflowWrap: 'anywhere' }}>
|
||||
{children}
|
||||
</address>
|
||||
);
|
||||
}
|
||||
|
||||
function Legal({ children }: { children: React.ReactNode }) {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<p style={{ fontFamily: '"Inter", sans-serif', fontSize: isMobile ? 15 : 14, color: NAVY, lineHeight: 1.75, background: 'rgba(17,29,85,0.04)', padding: '12px 16px', borderLeft: `3px solid ${NAVY}`, margin: '0 0 16px', fontWeight: 500, overflowWrap: 'anywhere' }}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
304
src/spa/pages/EventDetail.tsx
Normal file
304
src/spa/pages/EventDetail.tsx
Normal file
@@ -0,0 +1,304 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useParams, Link } from '@/spa/router'
|
||||
import { motion } from 'framer-motion'
|
||||
import { Calendar, MapPin, Clock, Bell, BellOff, ArrowLeft, ChevronRight, Users, Tag } from 'lucide-react'
|
||||
import { getEventBySlug, EventUpdate, UpdateType } from '@/spa/data/events'
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile'
|
||||
|
||||
const NAVY = '#111D55'
|
||||
const GOLD = '#EFBF04'
|
||||
const CREAM = '#EFE5E3'
|
||||
const INK = '#3A3A3A'
|
||||
|
||||
// ── Timestamp formatter ──────────────────────────────────────────────────────
|
||||
const MONATE = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']
|
||||
function formatTs(iso: string): string {
|
||||
const d = new Date(iso)
|
||||
return `${d.getDate()}. ${MONATE[d.getMonth()]} ${d.getFullYear()}, ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')} Uhr`
|
||||
}
|
||||
|
||||
// ── Update type styling ──────────────────────────────────────────────────────
|
||||
const UPDATE_STYLE: Record<UpdateType, { bg: string; color: string; label: string }> = {
|
||||
ankündigung: { bg: '#EBF4FF', color: '#1D4ED8', label: 'Ankündigung' },
|
||||
erinnerung: { bg: '#FFFBEB', color: '#B45309', label: 'Erinnerung' },
|
||||
update: { bg: '#F3F4F6', color: '#374151', label: 'Update' },
|
||||
highlight: { bg: `${NAVY}12`, color: NAVY, label: 'Highlight' },
|
||||
ergebnis: { bg: '#ECFDF5', color: '#065F46', label: 'Ergebnis' },
|
||||
wichtig: { bg: '#FEF2F2', color: '#991B1B', label: 'Wichtig' },
|
||||
}
|
||||
|
||||
// ── Status badge ─────────────────────────────────────────────────────────────
|
||||
const STATUS_LABEL: Record<string, { label: string; bg: string; color: string }> = {
|
||||
'geplant': { label: 'In Planung', bg: `${NAVY}18`, color: NAVY },
|
||||
'anmeldung-offen': { label: 'Anmeldung offen', bg: '#ECFDF5', color: '#065F46' },
|
||||
'intern': { label: 'Intern', bg: '#FEF9C3', color: '#713F12' },
|
||||
'abgeschlossen': { label: 'Abgeschlossen', bg: '#F3F4F6', color: '#6B7280' },
|
||||
}
|
||||
|
||||
// ── Update Card ───────────────────────────────────────────────────────────────
|
||||
function UpdateCard({ update, index }: { update: EventUpdate; index: number }) {
|
||||
const style = UPDATE_STYLE[update.type] ?? UPDATE_STYLE.update
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 24 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.35, delay: index * 0.07, ease: 'easeOut' }}
|
||||
style={{ display: 'flex', gap: 16, position: 'relative' }}
|
||||
>
|
||||
{/* Timeline dot */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
|
||||
<div style={{ width: 10, height: 10, borderRadius: '50%', background: GOLD, border: `2px solid ${GOLD}`, marginTop: 6, flexShrink: 0 }} />
|
||||
<div style={{ flex: 1, width: 1, background: `rgba(3,9,58,0.1)`, marginTop: 6 }} />
|
||||
</div>
|
||||
|
||||
{/* Card */}
|
||||
<div style={{
|
||||
flex: 1, background: '#fff', borderRadius: 12, padding: '16px 20px',
|
||||
marginBottom: 12, border: '1px solid rgba(3,9,58,0.08)',
|
||||
boxShadow: '0 1px 8px rgba(3,9,58,0.04)',
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8, flexWrap: 'wrap' }}>
|
||||
<span style={{
|
||||
fontSize: 10, fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.1em',
|
||||
padding: '3px 8px', borderRadius: 20,
|
||||
background: style.bg, color: style.color,
|
||||
}}>{style.label}</span>
|
||||
<span style={{ fontSize: 11, color: 'rgba(58,58,58,0.45)' }}>{formatTs(update.timestamp)}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 15, fontWeight: 700, color: NAVY, marginBottom: 4, lineHeight: 1.35 }}>{update.title}</div>
|
||||
<div style={{ fontSize: 14, color: 'rgba(58,58,58,0.65)', lineHeight: 1.65 }}>{update.body}</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
|
||||
// ── Main Component ────────────────────────────────────────────────────────────
|
||||
export default function EventDetail() {
|
||||
const { slug } = useParams<{ slug: string }>()
|
||||
const event = getEventBySlug(slug ?? '')
|
||||
const [subscribed, setSubscribed] = useState(false)
|
||||
const isMobile = useIsMobile()
|
||||
|
||||
if (!event) {
|
||||
return (
|
||||
<div style={{ paddingTop: 60, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: CREAM, flexDirection: 'column', gap: 24 }}>
|
||||
<div style={{ fontSize: 64, fontWeight: 900, color: `${NAVY}20`, letterSpacing: '-0.04em' }}>404</div>
|
||||
<div style={{ fontSize: 20, fontWeight: 700, color: NAVY }}>Event nicht gefunden</div>
|
||||
<Link to="/presse" style={{ fontSize: 15, color: NAVY, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6, fontWeight: 600, borderBottom: `2px solid ${GOLD}`, paddingBottom: 2 }}>
|
||||
<ArrowLeft size={14} /> Zurück zur Presse-Seite
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const statusStyle = STATUS_LABEL[event.status] ?? STATUS_LABEL['geplant']
|
||||
|
||||
return (
|
||||
<div style={{ paddingTop: 60, background: CREAM, minHeight: '100vh', fontFamily: '"Inter", sans-serif' }}>
|
||||
|
||||
{/* ── Hero ─────────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', height: isMobile ? 'auto' : '65vh', minHeight: isMobile ? 520 : 480, overflow: 'hidden' }}>
|
||||
<img
|
||||
src={event.img}
|
||||
alt={event.title}
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(3,9,58,0.25) 0%, rgba(3,9,58,0.92) 100%)' }} />
|
||||
|
||||
{/* Back link */}
|
||||
<div style={{ position: 'absolute', top: 28, left: 0, right: 0, padding: isMobile ? '0 24px' : '0 80px', zIndex: 10 }}>
|
||||
<Link to="/presse" style={{ display: 'inline-flex', alignItems: 'center', gap: 8, color: 'rgba(255,255,255,0.7)', textDecoration: 'none', fontSize: 14, fontWeight: 600, transition: 'color 0.15s' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = '#fff')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.7)')}
|
||||
>
|
||||
<ArrowLeft size={14} /> Alle Events
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Hero content */}
|
||||
<div style={{ position: isMobile ? 'relative' : 'absolute', bottom: 0, left: 0, right: 0, padding: isMobile ? '88px 24px 48px' : '40px 80px', zIndex: 10, display: 'flex', flexDirection: isMobile ? 'column' : 'row', justifyContent: isMobile ? 'flex-end' : 'space-between', alignItems: isMobile ? 'flex-start' : 'flex-end', gap: isMobile ? 20 : 40, minHeight: isMobile ? 520 : undefined, boxSizing: 'border-box' }}>
|
||||
{/* Left */}
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14, flexWrap: 'wrap' }}>
|
||||
<span style={{ fontSize: 10, fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.2em', background: statusStyle.bg, color: statusStyle.color, padding: '4px 10px', borderRadius: 20 }}>
|
||||
{statusStyle.label}
|
||||
</span>
|
||||
<span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.15em', color: GOLD }}>
|
||||
{event.category}
|
||||
</span>
|
||||
</div>
|
||||
<h1 style={{ fontSize: isMobile ? 'clamp(1.8rem, 8vw, 2.8rem)' : 'clamp(2rem, 5vw, 4rem)', fontWeight: 900, color: '#fff', letterSpacing: '-0.03em', lineHeight: 1.05, marginBottom: 12, fontFamily: '"IBM Plex Sans", sans-serif' }}>
|
||||
{event.title}
|
||||
</h1>
|
||||
<p style={{ fontSize: isMobile ? 14 : 16, color: 'rgba(255,255,255,0.65)', maxWidth: 520, lineHeight: 1.6 }}>
|
||||
{event.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right – key facts */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, flexShrink: 0, background: 'rgba(3,9,58,0.55)', backdropFilter: 'blur(12px)', borderRadius: 16, padding: isMobile ? '16px 20px' : '24px 28px', border: '1px solid rgba(255,255,255,0.1)', width: isMobile ? '100%' : undefined, boxSizing: 'border-box' }}>
|
||||
{[
|
||||
{ icon: Calendar, label: event.date },
|
||||
{ icon: Clock, label: event.time },
|
||||
{ icon: MapPin, label: `${event.venue}, ${event.location}` },
|
||||
].map(({ icon: Icon, label }, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
|
||||
<Icon size={15} color={GOLD} style={{ flexShrink: 0 }} />
|
||||
<span style={{ fontSize: 14, color: '#fff', fontWeight: 500, overflowWrap: 'anywhere' }}>{label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Gold bottom line */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 3, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.3), transparent)` }} />
|
||||
</section>
|
||||
|
||||
{/* ── Main Content ─────────────────────────────────────────────────── */}
|
||||
<section style={{ padding: isMobile ? '48px 24px' : '64px 80px', maxWidth: 1400, margin: '0 auto' }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 400px', gap: isMobile ? 48 : 64, alignItems: 'start' }}>
|
||||
|
||||
{/* Left – Description + Eckdaten */}
|
||||
<div>
|
||||
{/* Description */}
|
||||
<div style={{ marginBottom: 56 }}>
|
||||
<p style={{ fontSize: 11, fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.25em', color: GOLD, marginBottom: 16 }}>
|
||||
Über die Veranstaltung
|
||||
</p>
|
||||
{event.longDescription.split('\n\n').map((para, i) => (
|
||||
<p key={i} style={{ fontSize: 17, color: 'rgba(58,58,58,0.75)', lineHeight: 1.8, marginBottom: 20 }}>{para}</p>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Eckdaten */}
|
||||
<div>
|
||||
<p style={{ fontSize: 11, fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.25em', color: GOLD, marginBottom: 24 }}>
|
||||
Eckdaten
|
||||
</p>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: 2 }}>
|
||||
{event.eckdaten.map((item, i) => (
|
||||
<div key={i} style={{
|
||||
padding: '20px 24px',
|
||||
background: i % 2 === 0 ? '#fff' : 'rgba(255,255,255,0.6)',
|
||||
borderRadius: isMobile
|
||||
? (i === 0
|
||||
? '12px 12px 0 0'
|
||||
: i === event.eckdaten.length - 1
|
||||
? '0 0 12px 12px'
|
||||
: '0')
|
||||
: (i === 0 ? '12px 0 0 0' : i === 1 ? '0 12px 0 0' : i === event.eckdaten.length - 2 ? '0 0 0 12px' : i === event.eckdaten.length - 1 ? '0 0 12px 0' : '0'),
|
||||
border: '1px solid rgba(3,9,58,0.06)',
|
||||
}}>
|
||||
<div style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'rgba(58,58,58,0.4)', marginBottom: 6 }}>
|
||||
{item.label}
|
||||
</div>
|
||||
<div style={{ fontSize: 16, fontWeight: 700, color: NAVY, lineHeight: 1.35 }}>
|
||||
{item.value}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div style={{ marginTop: 40, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
||||
{event.status === 'anmeldung-offen' && (
|
||||
<Link to="/teilnahme" style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8,
|
||||
background: NAVY, color: GOLD, textDecoration: 'none',
|
||||
padding: '14px 28px', borderRadius: 10, fontWeight: 700, fontSize: 15,
|
||||
fontFamily: '"IBM Plex Sans", sans-serif',
|
||||
}}>
|
||||
Jetzt anmelden <ChevronRight size={16} />
|
||||
</Link>
|
||||
)}
|
||||
<Link to="/kontakt" style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8,
|
||||
background: 'transparent', color: NAVY, textDecoration: 'none',
|
||||
padding: '14px 28px', borderRadius: 10, fontWeight: 700, fontSize: 15,
|
||||
border: `2px solid ${NAVY}`,
|
||||
}}>
|
||||
Frage stellen
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right – Live Updates Feed (sticky on desktop, static on mobile) */}
|
||||
<div style={isMobile ? undefined : { position: 'sticky', top: 80 }}>
|
||||
{/* Header */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<Bell size={18} color={NAVY} />
|
||||
<span style={{ fontSize: 17, fontWeight: 800, color: NAVY, fontFamily: '"IBM Plex Sans", sans-serif' }}>
|
||||
Live Updates
|
||||
</span>
|
||||
<span style={{
|
||||
fontSize: 11, fontWeight: 800, background: NAVY, color: GOLD,
|
||||
borderRadius: 20, padding: '2px 8px',
|
||||
}}>{event.updates.length}</span>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => setSubscribed(s => !s)}
|
||||
style={{
|
||||
display: 'flex', alignItems: 'center', gap: 6, cursor: 'pointer',
|
||||
background: subscribed ? NAVY : 'transparent',
|
||||
color: subscribed ? GOLD : NAVY,
|
||||
border: `1.5px solid ${NAVY}`, borderRadius: 8,
|
||||
padding: '8px 14px', fontSize: 12, fontWeight: 700,
|
||||
transition: 'all 0.2s', fontFamily: 'inherit',
|
||||
}}
|
||||
>
|
||||
{subscribed ? <><BellOff size={13} /> Abgemeldet</> : <><Bell size={13} /> Abonnieren</>}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{subscribed && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -8 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
style={{ background: '#ECFDF5', border: '1px solid #A7F3D0', borderRadius: 10, padding: '10px 14px', marginBottom: 16, fontSize: 14, color: '#065F46', fontWeight: 500 }}
|
||||
>
|
||||
✓ Sie erhalten Benachrichtigungen für dieses Event.
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{/* Timeline */}
|
||||
<div style={{ maxHeight: isMobile ? 'none' : 560, overflowY: isMobile ? 'visible' : 'auto', paddingRight: 4 }}>
|
||||
{event.updates.map((update, i) => (
|
||||
<UpdateCard key={update.id} update={update} index={i} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── Bottom CTA ───────────────────────────────────────────────────── */}
|
||||
<section style={{ background: NAVY, padding: isMobile ? '48px 24px' : '64px 80px', marginTop: 40 }}>
|
||||
<div style={{ maxWidth: 1400, margin: '0 auto', display: 'flex', flexDirection: isMobile ? 'column' : 'row', justifyContent: 'space-between', alignItems: isMobile ? 'flex-start' : 'center', gap: isMobile ? 24 : 0 }}>
|
||||
<div>
|
||||
<p style={{ fontSize: 11, fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.25em', color: GOLD, marginBottom: 10 }}>
|
||||
Mehr entdecken
|
||||
</p>
|
||||
<h3 style={{ fontSize: 28, fontWeight: 900, color: '#fff', letterSpacing: '-0.03em', fontFamily: '"IBM Plex Sans", sans-serif' }}>
|
||||
Weitere Veranstaltungen
|
||||
</h3>
|
||||
</div>
|
||||
<Link
|
||||
to="/presse"
|
||||
style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8, textDecoration: 'none',
|
||||
background: GOLD, color: NAVY, padding: '14px 28px', borderRadius: 10,
|
||||
fontWeight: 800, fontSize: 15, fontFamily: '"IBM Plex Sans", sans-serif',
|
||||
transition: 'background 0.15s, box-shadow 0.2s',
|
||||
}}
|
||||
onMouseEnter={e => { const el = e.currentTarget as HTMLElement; el.style.background = '#FFD130'; el.style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.background = GOLD; el.style.boxShadow = 'none'; }}
|
||||
>
|
||||
Alle Events <ChevronRight size={16} />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
265
src/spa/pages/FormularUpload.tsx
Normal file
265
src/spa/pages/FormularUpload.tsx
Normal file
@@ -0,0 +1,265 @@
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { Upload, FileText, CheckCircle, AlertCircle, X, ArrowRight, Clock, Shield, Info } from 'lucide-react';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const GOLD = '#EFBF04';
|
||||
const NAVY = '#111D55';
|
||||
const DARK = '#101828';
|
||||
const GRAU = '#E4E2E3';
|
||||
const BORDER = '#D0D5DD';
|
||||
const HELLBLAU = '#4A8FC9';
|
||||
|
||||
type UploadFile = { name: string; size: number; status: 'ready' | 'uploading' | 'done' | 'error' };
|
||||
|
||||
function formatBytes(b: number) {
|
||||
if (b < 1024) return b + ' B';
|
||||
if (b < 1024 * 1024) return (b / 1024).toFixed(1) + ' KB';
|
||||
return (b / (1024 * 1024)).toFixed(1) + ' MB';
|
||||
}
|
||||
|
||||
export default function FormularUpload() {
|
||||
const [files, setFiles] = useState<UploadFile[]>([]);
|
||||
const [dragging, setDragging] = useState(false);
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const addFiles = (fileList: FileList) => {
|
||||
const newFiles: UploadFile[] = Array.from(fileList).map(f => ({
|
||||
name: f.name, size: f.size, status: 'ready',
|
||||
}));
|
||||
setFiles(prev => [...prev, ...newFiles]);
|
||||
};
|
||||
|
||||
const remove = (i: number) => setFiles(prev => prev.filter((_, idx) => idx !== i));
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!files.length) return;
|
||||
setFiles(prev => prev.map(f => ({ ...f, status: 'uploading' })));
|
||||
setTimeout(() => {
|
||||
setFiles(prev => prev.map(f => ({ ...f, status: 'done' })));
|
||||
setTimeout(() => setSubmitted(true), 600);
|
||||
}, 1800);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ background: '#fff', minHeight: '100vh' }}>
|
||||
|
||||
{/* ── HERO ────────────────────────────────────────── */}
|
||||
<div style={{ background: DARK, position: 'relative', overflow: 'hidden', padding: isMobile ? '64px 24px 48px' : '100px 80px 72px' }}>
|
||||
<div style={{ height: 3, background: `linear-gradient(to right, ${GOLD}, transparent)`, position: 'absolute', top: 0, left: 0, right: 0 }} />
|
||||
|
||||
<div style={{ maxWidth: 720, position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.35em', color: HELLBLAU, display: 'block', marginBottom: 16 }}>
|
||||
BMP 2026 – Bewerbungsportal
|
||||
</span>
|
||||
<h1 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.6rem, 4vw, 3.6rem)' : 'clamp(2.2rem, 4vw, 3.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.0, margin: '0 0 20px' }}>
|
||||
UNTERLAGEN<br />EINREICHEN
|
||||
</h1>
|
||||
<div style={{ width: 48, height: 3, background: GOLD, marginBottom: 24 }} />
|
||||
<p style={{ fontFamily: FF, fontSize: 16, color: 'rgba(255,255,255,0.55)', lineHeight: 1.75, maxWidth: 520, margin: 0 }}>
|
||||
Laden Sie Ihre Bewerbungsunterlagen sicher hoch. Alle Einreichungen werden vertraulich behandelt und direkt an die Jury weitergeleitet.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Stats row */}
|
||||
<div style={{ display: 'flex', flexWrap: isMobile ? 'wrap' : 'nowrap', gap: isMobile ? '24px 0' : 0, marginTop: 56, borderTop: '1px solid rgba(255,255,255,0.07)', paddingTop: 32, position: 'relative', zIndex: 1 }}>
|
||||
{[
|
||||
{ num: '100%', label: 'Vertraulich' },
|
||||
{ num: 'SSL', label: 'Verschlüsselt' },
|
||||
{ num: '30 MB', label: 'Max. Dateigröße' },
|
||||
{ num: 'PDF/DOCX', label: 'Akzeptierte Formate' },
|
||||
].map((s, i) => (
|
||||
<div key={i} style={{ flex: isMobile ? '0 0 50%' : 1, paddingRight: 32 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 22, fontWeight: 900, color: GOLD, lineHeight: 1 }}>{s.num}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, color: 'rgba(255,255,255,0.35)', marginTop: 4, textTransform: 'uppercase', letterSpacing: '0.1em' }}>{s.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb */}
|
||||
<div style={{ background: '#fff', borderBottom: `1px solid ${BORDER}`, padding: isMobile ? '16px 24px' : '16px 80px' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 12, color: HELLBLAU, fontWeight: 700, letterSpacing: '0.04em' }}>Formular hochladen</span>
|
||||
</div>
|
||||
|
||||
{/* ── ERKLÄRUNG ───────────────────────────────────── */}
|
||||
<div style={{ background: GRAU, padding: isMobile ? '48px 24px' : '64px 80px' }}>
|
||||
<p style={{ fontFamily: FF, fontSize: 11, color: '#888', textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 8 }}>Was wird benötigt?</p>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.4rem, 2.2vw, 2rem)', fontWeight: 900, color: DARK, textTransform: 'uppercase', letterSpacing: '-0.02em', marginBottom: 40 }}>
|
||||
ANFORDERUNGEN & FRISTEN
|
||||
</h2>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, 1fr)', gap: 1, background: BORDER }}>
|
||||
{[
|
||||
{
|
||||
icon: FileText,
|
||||
title: 'Pflichtdokumente',
|
||||
items: ['Kurzprofil des Unternehmens (max. 2 Seiten)', 'Begründung der Bewerbung (mind. 500 Wörter)', 'Anschreiben der Geschäftsführung', 'Letzte 2 Jahresabschlüsse (optional, falls vorhanden)'],
|
||||
},
|
||||
{
|
||||
icon: Clock,
|
||||
title: 'Fristen & Einreichung',
|
||||
items: ['Bewerbungsschluss: 30. Juni 2026', 'Nachreichungen bis: 15. Juli 2026', 'Benachrichtigung: August 2026', 'Gala & Verleihung: Oktober 2026'],
|
||||
},
|
||||
{
|
||||
icon: Shield,
|
||||
title: 'Technische Anforderungen',
|
||||
items: ['Formate: PDF, DOCX, XLSX', 'Max. Dateigröße: 30 MB pro Datei', 'Max. Gesamtgröße: 100 MB', 'Sprache: Deutsch'],
|
||||
},
|
||||
].map(({ icon: Icon, title, items }, i) => (
|
||||
<div key={i} style={{ background: '#fff', padding: '36px 32px' }}>
|
||||
<div style={{ width: 40, height: 40, background: DARK, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 20 }}>
|
||||
<Icon size={18} color={GOLD} />
|
||||
</div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, color: DARK, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 16 }}>{title}</h3>
|
||||
<ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
|
||||
{items.map((item, j) => (
|
||||
<li key={j} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, fontFamily: FF, fontSize: 14, color: '#555', lineHeight: 1.5 }}>
|
||||
<span style={{ color: GOLD, marginTop: 2, flexShrink: 0 }}>–</span>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── UPLOAD-BEREICH ──────────────────────────────── */}
|
||||
<div style={{ background: NAVY, padding: isMobile ? '48px 24px' : '72px 80px' }}>
|
||||
<p style={{ fontFamily: FF, fontSize: 11, color: HELLBLAU, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.25em', marginBottom: 8 }}>Einreichung</p>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.4rem, 2.2vw, 2rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', marginBottom: 40 }}>
|
||||
DATEIEN HOCHLADEN
|
||||
</h2>
|
||||
|
||||
{submitted ? (
|
||||
<div style={{ textAlign: 'center', padding: '64px 0' }}>
|
||||
<div style={{ width: 64, height: 64, background: GOLD, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 24px' }}>
|
||||
<CheckCircle size={28} color={DARK} />
|
||||
</div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 22, fontWeight: 900, color: '#fff', textTransform: 'uppercase', marginBottom: 12 }}>Einreichung erfolgreich</h3>
|
||||
<p style={{ fontFamily: FF, fontSize: 15, color: 'rgba(255,255,255,0.45)', maxWidth: 440, margin: '0 auto 32px', lineHeight: 1.7 }}>
|
||||
Ihre Unterlagen wurden übermittelt. Sie erhalten eine Bestätigung per E-Mail. Die Jury meldet sich bis August 2026.
|
||||
</p>
|
||||
<Link to="/teilnahme" style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: DARK, background: GOLD, padding: '14px 32px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8 }}>
|
||||
Zur Teilnahmeseite <ArrowRight size={13} />
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 360px', gap: 32, alignItems: 'start' }}>
|
||||
|
||||
{/* Drop zone */}
|
||||
<div>
|
||||
<div
|
||||
onDragOver={e => { e.preventDefault(); setDragging(true); }}
|
||||
onDragLeave={() => setDragging(false)}
|
||||
onDrop={e => { e.preventDefault(); setDragging(false); if (e.dataTransfer.files.length) addFiles(e.dataTransfer.files); }}
|
||||
onClick={() => inputRef.current?.click()}
|
||||
style={{
|
||||
border: `2px dashed ${dragging ? GOLD : 'rgba(255,255,255,0.2)'}`,
|
||||
padding: '52px 32px',
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer',
|
||||
background: dragging ? 'rgba(239,191,4,0.05)' : 'rgba(255,255,255,0.03)',
|
||||
transition: 'all 0.2s',
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
<Upload size={32} color={dragging ? GOLD : 'rgba(255,255,255,0.3)'} style={{ margin: '0 auto 16px' }} />
|
||||
<p style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: '#fff', marginBottom: 8 }}>
|
||||
Dateien hierher ziehen
|
||||
</p>
|
||||
<p style={{ fontFamily: FF, fontSize: 12, color: 'rgba(255,255,255,0.35)', marginBottom: 20 }}>
|
||||
oder klicken zum Auswählen
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: 8, justifyContent: 'center', flexWrap: 'wrap' }}>
|
||||
{['PDF', 'DOCX', 'XLSX', 'PPT'].map(ext => (
|
||||
<span key={ext} style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', color: GOLD, border: `1px solid rgba(239,191,4,0.4)`, padding: '3px 10px' }}>{ext}</span>
|
||||
))}
|
||||
</div>
|
||||
<input ref={inputRef} type="file" multiple accept=".pdf,.docx,.xlsx,.pptx" style={{ display: 'none' }} onChange={e => { if (e.target.files) addFiles(e.target.files); }} />
|
||||
</div>
|
||||
|
||||
{/* File list */}
|
||||
{files.length > 0 && (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
{files.map((f, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '12px 16px', background: 'rgba(255,255,255,0.05)', borderLeft: `3px solid ${f.status === 'done' ? GOLD : f.status === 'error' ? '#f87171' : 'rgba(255,255,255,0.15)'}` }}>
|
||||
{f.status === 'done' ? <CheckCircle size={14} color={GOLD} /> : f.status === 'error' ? <AlertCircle size={14} color="#f87171" /> : <FileText size={14} color="rgba(255,255,255,0.4)" />}
|
||||
<span style={{ fontFamily: FF, fontSize: 12, color: '#fff', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.name}</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 11, color: 'rgba(255,255,255,0.3)' }}>{formatBytes(f.size)}</span>
|
||||
{f.status === 'uploading' && <div style={{ width: 14, height: 14, border: '2px solid rgba(255,255,255,0.2)', borderTopColor: GOLD, borderRadius: '50%', animation: 'spin 0.8s linear infinite' }} />}
|
||||
{f.status !== 'uploading' && f.status !== 'done' && (
|
||||
<button onClick={() => remove(i)} aria-label="Datei entfernen" style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'rgba(255,255,255,0.3)', padding: isMobile ? 12 : 0, margin: isMobile ? -12 : 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||||
<X size={isMobile ? 18 : 14} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Sidebar info + submit */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
|
||||
<div style={{ padding: '24px', background: 'rgba(255,255,255,0.04)', borderTop: `2px solid ${GOLD}` }}>
|
||||
<div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', marginBottom: 16 }}>
|
||||
<Info size={14} color={GOLD} style={{ marginTop: 2, flexShrink: 0 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Hinweis</span>
|
||||
</div>
|
||||
<p style={{ fontFamily: FF, fontSize: 12, color: 'rgba(255,255,255,0.4)', lineHeight: 1.7, margin: 0 }}>
|
||||
Stellen Sie sicher, dass alle Pflichtdokumente vollständig sind, bevor Sie einreichen. Unvollständige Bewerbungen können nicht berücksichtigt werden.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
disabled={files.length === 0}
|
||||
style={{
|
||||
fontFamily: FF, fontSize: 12, fontWeight: 700, textTransform: 'uppercase',
|
||||
letterSpacing: '0.12em', color: DARK, background: files.length ? GOLD : 'rgba(239,191,4,0.3)',
|
||||
border: 'none', cursor: files.length ? 'pointer' : 'not-allowed',
|
||||
padding: '16px 28px', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
gap: 8, transition: 'background 0.15s, box-shadow 0.2s', width: '100%',
|
||||
}}
|
||||
onMouseEnter={e => { if (files.length) { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; } }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = files.length ? GOLD : 'rgba(239,191,4,0.3)'; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
<Upload size={14} />
|
||||
{files.length ? `${files.length} Datei${files.length > 1 ? 'en' : ''} einreichen` : 'Keine Dateien ausgewählt'}
|
||||
</button>
|
||||
|
||||
<p style={{ fontFamily: FF, fontSize: 11, color: 'rgba(255,255,255,0.2)', lineHeight: 1.6, margin: 0 }}>
|
||||
Mit der Einreichung stimmen Sie der Verarbeitung Ihrer Daten gemäß unserer Datenschutzerklärung zu.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)}
|
||||
<style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
|
||||
</div>
|
||||
|
||||
{/* ── CTA ─────────────────────────────────────────── */}
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '64px 80px', borderTop: `1px solid ${BORDER}`, display: 'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'flex-start' : 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 24 }}>
|
||||
<div>
|
||||
<p style={{ fontFamily: FF, fontSize: 12, color: '#888', marginBottom: 6 }}>Noch Fragen zur Einreichung?</p>
|
||||
<Link to="/kontakt" style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: NAVY, textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
Kontakt aufnehmen <ArrowRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: DARK, background: GOLD, padding: '14px 32px', textDecoration: 'none', display: isMobile ? 'flex' : 'inline-flex', width: isMobile ? '100%' : 'auto', justifyContent: isMobile ? 'center' : undefined, alignItems: 'center', gap: 8, transition: 'background 0.15s, box-shadow 0.2s' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = GOLD; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Zur Teilnahmeseite <ArrowRight size={13} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
830
src/spa/pages/Home.tsx
Normal file
830
src/spa/pages/Home.tsx
Normal file
@@ -0,0 +1,830 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Button } from '@/spa/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/spa/components/ui/card';
|
||||
import { Badge } from '@/spa/components/ui/badge';
|
||||
import { Award, Users, TrendingUp, Play, ChevronRight, Building2, ShieldCheck, Leaf, HeartHandshake, X, Star } from 'lucide-react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { PartnerTicker } from '@/spa/components/ui/partner-ticker';
|
||||
import { WINNERS } from '@/spa/data/winners';
|
||||
import BewerbungsForm from '@/spa/components/forms/BewerbungsForm';
|
||||
import TestimonialsSection from '@/spa/components/TestimonialsSection';
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const PARTNERS = [
|
||||
{ id: 'rsm', label: <><span style={{fontWeight:700,fontSize:11,letterSpacing:2}}>RSM</span><br/><span style={{fontWeight:300,fontSize:8,letterSpacing:1,opacity:.7}}>Ebner Stolz</span></> },
|
||||
{ id: 'wwk', label: <span style={{fontWeight:800,fontSize: 15,letterSpacing:3}}>WWK</span> },
|
||||
{ id: 'db', label: <span style={{fontWeight:700,fontSize:10,letterSpacing:1.5}}>Deutsche Bank</span> },
|
||||
{ id: 'bio', label: <span style={{fontFamily:'Georgia,serif',fontSize: 14,letterSpacing:.5}}>Bionorica</span> },
|
||||
{ id: 'bcl', label: <span style={{fontWeight:700,fontSize:9,letterSpacing:1.5,lineHeight:1.3,textAlign:'center' as const,display:'block'}}>Berchtesgadener<br/>Land</span> },
|
||||
{ id: 'mtz', label: <span style={{fontFamily:'Georgia,serif',fontStyle:'italic',fontSize: 14}}>Metzler</span> },
|
||||
{ id: 'vbw', label: <span style={{fontWeight:800,fontSize: 14,letterSpacing:2}}>vbw</span> },
|
||||
{ id: 'wby', label: <span style={{fontWeight:700,fontSize:9,letterSpacing:1,lineHeight:1.3,textAlign:'center' as const,display:'block'}}>Wirtschafts-<br/>beirat Bayern</span> },
|
||||
{ id: 'rgong', label: <span style={{fontWeight:700,fontSize:9,letterSpacing:1}}>Radio Gong 96.3</span> },
|
||||
{ id: 'mtvr', label: <span style={{fontWeight:700,fontSize:10,letterSpacing:1.5}}>münchen.tv</span> },
|
||||
{ id: 'ews', label: <span style={{fontWeight:800,fontSize: 14,letterSpacing:2}}>EWS</span> },
|
||||
];
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
|
||||
// ─── Status Phase Slider ────────────────────────────────────────────────────
|
||||
/**
|
||||
* 🔧 DEPLOYMENT CONFIG
|
||||
* Setze ACTIVE_PHASE je nach aktuellem Stand des BMP-Zyklus:
|
||||
* 0 = Bewerbungsphase offen
|
||||
* 1 = Auswertungsphase (Jury bewertet)
|
||||
* 2 = Nach der Preisverleihung (Erfolg)
|
||||
*/
|
||||
const ACTIVE_PHASE: 0 | 1 | 2 = 0;
|
||||
|
||||
interface StatusPhase {
|
||||
num: string;
|
||||
tag: string;
|
||||
pulse: boolean;
|
||||
phase: string;
|
||||
headline: string;
|
||||
body: string;
|
||||
cta: { label: string; to: string } | null;
|
||||
accent: string;
|
||||
bg: string;
|
||||
glow: string;
|
||||
meta: string;
|
||||
}
|
||||
|
||||
const STATUS_PHASES: StatusPhase[] = [
|
||||
{
|
||||
num: '01',
|
||||
tag: 'JETZT OFFEN',
|
||||
pulse: true,
|
||||
phase: 'Bewerbungsphase 2026',
|
||||
headline: 'BEWERBEN SIE SICH JETZT.',
|
||||
body: 'Die Bewerbungsphase 2026 ist eröffnet – es ist noch nicht zu spät. Reichen Sie Ihre Unterlagen bis zum 30. Juni kostenlos ein und zeigen Sie, was den bayerischen Mittelstand ausmacht.',
|
||||
cta: { label: 'Jetzt kostenlos bewerben', to: '/teilnahme' },
|
||||
accent: '#EFBF04',
|
||||
bg: '#020A1E',
|
||||
glow: 'rgba(239,191,4,0.14)',
|
||||
meta: 'Deadline: 30. Juni 2026',
|
||||
},
|
||||
{
|
||||
num: '02',
|
||||
tag: 'IN AUSWERTUNG',
|
||||
pulse: true,
|
||||
phase: 'Auswertungsphase 2026',
|
||||
headline: 'DIE JURY BEWERTET GERADE.',
|
||||
body: 'Die Anmeldephase 2026 ist geschlossen. Unsere unabhängige Expertenjury aus Wissenschaft und Praxis sichtet und bewertet derzeit alle Einreichungen.',
|
||||
cta: null,
|
||||
accent: '#4A8FC9',
|
||||
bg: '#060D1C',
|
||||
glow: 'rgba(74,143,201,0.12)',
|
||||
meta: 'Ergebnis: August 2026',
|
||||
},
|
||||
{
|
||||
num: '03',
|
||||
tag: 'ABGESCHLOSSEN',
|
||||
pulse: false,
|
||||
phase: 'Preisverleihung · Oktober 2026',
|
||||
headline: 'DER BMP 2026 WAR EIN ERFOLG.',
|
||||
body: 'Wir danken allen 247 Bewerberinnen und Bewerbern für Mut und Exzellenz. Drei außergewöhnliche Unternehmen wurden in München ausgezeichnet – ein unvergesslicher Abend.',
|
||||
cta: { label: 'Alle Preisträger ansehen', to: '/preistraeger' },
|
||||
accent: '#EFBF04',
|
||||
bg: '#06090F',
|
||||
glow: 'rgba(239,191,4,0.08)',
|
||||
meta: 'Gala · Oktober 2026 · München',
|
||||
},
|
||||
];
|
||||
|
||||
function HomeWinnerCard({ winner }: { winner: import('@/spa/data/winners').Winner }) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<Link
|
||||
to={`/preistraeger/${winner.slug}`}
|
||||
style={{ textDecoration: 'none', display: 'block', position: 'relative', height: isMobile ? 220 : 280, overflow: 'hidden', scrollSnapAlign: isMobile ? 'start' : undefined }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<img src={winner.img} alt={winner.name} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transition: 'transform 0.5s ease', transform: hovered ? 'scale(1.07)' : 'scale(1)', filter: 'grayscale(15%)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.1) 55%, transparent 100%)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.2)', opacity: hovered ? 1 : 0, transition: 'opacity 0.25s' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.06)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, padding: '18px 20px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 5 }}>
|
||||
<Star size={10} style={{ color: '#EFBF04', flexShrink: 0 }} fill="#EFBF04" />
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, fontWeight: 700, color: '#EFBF04', letterSpacing: '0.12em', textTransform: 'uppercase' }}>{winner.year} · {winner.type}</span>
|
||||
</div>
|
||||
<h3 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 16, fontWeight: 700, color: '#fff', margin: '0 0 3px', lineHeight: 1.3 }}>{winner.name}</h3>
|
||||
<p style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 14, color: 'rgba(255,255,255,0.75)', margin: 0 }}>{winner.category}</p>
|
||||
<div style={{ marginTop: 10, display: 'inline-block', background: '#EFBF04', color: '#101828', padding: '5px 14px', borderRadius: 999, fontSize: 10, fontFamily: '"IBM Plex Sans", sans-serif', fontWeight: 800, letterSpacing: '0.1em', textTransform: 'uppercase', opacity: hovered ? 1 : 0, transform: hovered ? 'translateY(0)' : 'translateY(6px)', transition: 'all 0.25s' }}>
|
||||
Detail →
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const [showVideo, setShowVideo] = useState(false);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div className="animate-fade-in">
|
||||
{/* Hero Section */}
|
||||
<section className="relative flex items-center overflow-hidden" style={{ background: '#111D55', height: isMobile ? '88svh' : '100vh' }}>
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img
|
||||
src="/images/gala-saal-overview.jpg"
|
||||
alt="Awards Gala"
|
||||
className="w-full h-full object-cover scale-105"
|
||||
style={{ objectPosition: 'center top' }}
|
||||
/>
|
||||
<div style={{ position:'absolute', inset:0, background: isMobile ? 'linear-gradient(to top, rgba(17,29,85,0.96) 0%, rgba(17,29,85,0.82) 42%, rgba(17,29,85,0.48) 72%, rgba(17,29,85,0.22) 100%)' : 'linear-gradient(to right, #111D55 0%, rgba(17,29,85,0.90) 38%, rgba(17,29,85,0.18) 65%, transparent 100%)' }}></div>
|
||||
</div>
|
||||
|
||||
<div className="container mx-auto relative z-10" style={{ padding: isMobile ? '0 24px' : '0 24px' }}>
|
||||
<div style={{ maxWidth: isMobile ? '100%' : '48rem' }}>
|
||||
<div className="inline-flex items-center gap-3 bg-accent/20 border border-accent/30 rounded-full px-4 py-1.5 mb-8 backdrop-blur-sm animate-fade-in" style={{ marginBottom: isMobile ? 20 : undefined }}>
|
||||
<span className="flex h-2 w-2 rounded-full bg-accent"></span>
|
||||
<span className="text-accent text-[10px] uppercase tracking-[0.2em] font-bold">Bewerbungsphase 2026 geschlossen</span>
|
||||
</div>
|
||||
|
||||
<h1 className="font-display font-bold text-white mb-6 leading-[0.9] tracking-tight" style={{ fontSize: isMobile ? 'clamp(1.8rem, 10vw, 3rem)' : 'clamp(3.5rem, 8vw, 6rem)' }}>
|
||||
BAYERNS BESTE <br />
|
||||
<span className="text-accent">MITTELSTÄNDLER.</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-white/70 mb-12 font-light leading-relaxed" style={{ fontSize: isMobile ? '1.0625rem' : '1.375rem', maxWidth: isMobile ? '100%' : '36rem', marginBottom: isMobile ? 28 : undefined }}>
|
||||
Der Bayerische Mittelstandspreis würdigt herausragende Leistungen – von Innovation über Nachhaltigkeit bis hin zur Exzellenz.
|
||||
</p>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{ fontFamily:'"IBM Plex Sans", sans-serif', fontSize: 16, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.12em', color:'#101828', background:'#EFBF04', padding:'16px 36px', textDecoration:'none', display:'inline-flex', alignItems:'center', justifyContent: isMobile ? 'center' : 'flex-start', gap:10, transition:'background 0.15s, box-shadow 0.2s', width: isMobile ? '100%' : 'auto' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#EFBF04'; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Jetzt kostenlos bewerben <ChevronRight size={16} />
|
||||
</Link>
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: 16, alignItems: isMobile ? 'stretch' : 'center' }}>
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
style={{ fontFamily:'"IBM Plex Sans", sans-serif', fontSize: 16, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.12em', color:'rgba(255,255,255,0.85)', border:'1.5px solid rgba(255,255,255,0.35)', padding:'14px 32px', textDecoration:'none', display:'inline-flex', alignItems:'center', justifyContent: isMobile ? 'center' : 'flex-start', gap:10, transition:'border-color 0.15s, color 0.15s', background:'transparent', width: isMobile ? '100%' : 'auto' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.borderColor = '#EFBF04'; (e.currentTarget as HTMLElement).style.color = '#EFBF04'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.borderColor = 'rgba(255,255,255,0.35)'; (e.currentTarget as HTMLElement).style.color = 'rgba(255,255,255,0.85)'; }}
|
||||
>
|
||||
Mitglied werden
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => setShowVideo(true)}
|
||||
className="flex items-center gap-4 text-white hover:text-accent transition-colors group"
|
||||
style={{ justifyContent: isMobile ? 'center' : 'flex-start' }}
|
||||
>
|
||||
<div className="w-12 h-12 rounded-full border border-white/30 flex items-center justify-center group-hover:border-accent group-hover:bg-accent/10 transition-all">
|
||||
<Play size={20} fill="currentColor" />
|
||||
</div>
|
||||
<span className="uppercase text-xs tracking-widest font-bold">Film abspielen</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Partner Bar */}
|
||||
<div className="absolute bottom-0 left-0 w-full bg-white/5 backdrop-blur-xl border-t border-white/10 hidden lg:block">
|
||||
<div className="px-8 py-5 flex items-center justify-between opacity-60 hover:opacity-100 transition-opacity duration-500">
|
||||
{/* Left: label – stays put */}
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 9, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.5)', whiteSpace: 'nowrap', flexShrink: 0 }}>Unsere Partner</span>
|
||||
{/* Right: ticker – fixed window, exactly 4 logos wide */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16, flexShrink: 0 }}>
|
||||
<div style={{ width: 1, height: 20, background: 'rgba(255,255,255,0.2)' }} />
|
||||
<div style={{ width: 560, overflow: 'hidden', flexShrink: 0 }}>
|
||||
<PartnerTicker logos={PARTNERS} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Schnell-Check Section */}
|
||||
<section style={{ overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 45%', position: 'relative' }}>
|
||||
{/* Left (desktop) / Bottom (mobile) – text block (light bg, dark text) */}
|
||||
<div style={{ background: '#E4E2E3', padding: isMobile ? '32px 24px 44px' : '80px 72px', display: 'flex', flexDirection: 'column', justifyContent: 'center', order: isMobile ? 2 : 0 }}>
|
||||
{/* Eyebrow + heading – desktop only (on mobile these are overlaid on the image) */}
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Schnell-Check</span>
|
||||
<h2 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(1.8rem, 2.8vw, 2.5rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: '0 0 20px' }}>
|
||||
SIND SIE<br />BERECHTIGT?
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
<div style={{ width: 40, height: 2, background: '#EFBF04', marginBottom: 28 }} />
|
||||
<p style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 17, color: 'rgba(16,24,40,0.6)', lineHeight: 1.7, marginBottom: 32 }}>
|
||||
Der Bayerische Mittelstandspreis richtet sich an inhabergeführte KMU im Freistaat. Fünf Kriterien entscheiden, erfüllen Sie alle fünf, steht Ihrer Bewerbung nichts im Weg.
|
||||
</p>
|
||||
{/* Criteria list */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 0, marginBottom: 36, borderTop: '1px solid #D0D5DD' }}>
|
||||
{[
|
||||
{ label: 'Standort Bayern', desc: 'Sitz oder Betriebsstätte im Freistaat' },
|
||||
{ label: '50–1.500 Mitarbeiter', desc: 'Klassischer Mittelstand' },
|
||||
{ label: 'Min. 3 Geschäftsjahre', desc: 'Markterfahrung und Stabilität' },
|
||||
{ label: 'Privatwirtschaft', desc: 'Kein staatlicher Träger' },
|
||||
{ label: 'Familien- bzw. eigentümergeführt', desc: 'Ihr Unternehmen ist inhabergeführt' },
|
||||
].map((item, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '13px 0', borderBottom: '1px solid #D0D5DD' }}>
|
||||
<div style={{ width: 24, height: 24, background: '#111D55', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||||
<svg width="10" height="10" viewBox="0 0 10 10"><polyline points="1,5 3.5,7.5 9,2" stroke="#EFBF04" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 16, fontWeight: 700, color: '#101828' }}>{item.label}</div>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 14, color: 'rgba(16,24,40,0.5)' }}>{item.desc}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 14, color: 'rgba(16,24,40,0.55)', lineHeight: 1.6, marginTop: 16, marginBottom: 28 }}>
|
||||
Auch ein Verbund bzw. eine Gemeinschaft von mittelständischen Unternehmen oder von mittelständischen Unternehmen und Organisationen/Institutionen mit Schwerpunkt in Bayern kann teilnehmen.
|
||||
</p>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 15, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: '#101828', background: '#EFBF04', padding: '15px 32px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, alignSelf: isMobile ? 'stretch' : 'flex-start', transition: 'background 0.15s, box-shadow 0.2s' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#EFBF04'; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Ihr Weg zum Preis <ChevronRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Right (desktop) / Top (mobile) – image; on mobile the heading is overlaid here */}
|
||||
<div style={{ position: 'relative', minHeight: isMobile ? 280 : 560, overflow: 'hidden', order: isMobile ? 1 : 0 }}>
|
||||
<img
|
||||
src="/images/buehne-gewinner.jpg"
|
||||
alt="Preisverleihung Bühne"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: isMobile ? 'center right' : 'center center' }}
|
||||
/>
|
||||
{/* Overlay: mobile = navy shadow bottom-left (for the heading); desktop = leftward fade into text bg */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile
|
||||
? 'linear-gradient(to top, rgba(3,9,58,0.92) 0%, rgba(3,9,58,0.55) 34%, rgba(3,9,58,0.12) 68%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.55) 0%, transparent 55%)'
|
||||
: 'linear-gradient(to left, transparent 40%, #E4E2E3 100%)' }} />
|
||||
{/* Heading overlay – mobile only */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 26px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, color: '#8FBEEC', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Schnell-Check</span>
|
||||
<h2 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(1.9rem, 8vw, 2.5rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.5)' }}>
|
||||
SIND SIE<br />BERECHTIGT?
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
{/* Gold accent line – bottom edge */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'linear-gradient(to right, rgba(239,191,4,0.2), #EFBF04, rgba(239,191,4,0.2))', zIndex: 3 }} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Intro Section – editorial split, no radius, no floating badge */}
|
||||
<section style={{ overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '45% 55%' }}>
|
||||
{/* Left – full-bleed image with stats overlay (+ heading on mobile) */}
|
||||
<div style={{ position: 'relative', minHeight: isMobile ? 300 : 600, overflow: 'hidden' }}>
|
||||
<img
|
||||
src="/images/preistraeger-jubel.jpg"
|
||||
alt="BMP Auszeichnung"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center top' }}
|
||||
/>
|
||||
{/* Dark overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile
|
||||
? 'linear-gradient(to top, rgba(3,9,58,0.92) 0%, rgba(3,9,58,0.5) 36%, rgba(3,9,58,0.1) 70%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.5) 0%, transparent 55%)'
|
||||
: 'linear-gradient(to right, transparent 50%, #fff 100%), linear-gradient(to top, rgba(3,9,58,0.82) 0%, rgba(3,9,58,0.50) 60%, transparent 100%)' }} />
|
||||
{/* Heading overlay – mobile only (bottom-left) */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 26px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, color: '#8FBEEC', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Ein Gewinn für alle</span>
|
||||
<h2 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(1.9rem, 8vw, 2.5rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.5)' }}>
|
||||
AUSZEICHNUNG<br />FÜR DIE BESTEN.
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
{/* Stats bottom-left – desktop only (mobile shows them below the image) */}
|
||||
{!isMobile && (
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '32px 40px', background: 'linear-gradient(to top, rgba(3,9,58,0.88) 0%, transparent 100%)', display: 'flex', gap: 36 }}>
|
||||
{[['20+', 'Jahre Exzellenz'], ['0 €', 'Teilnahmegebühr'], ['100%', 'Unabhängig']].map(([v, l]) => (
|
||||
<div key={l}>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 28, fontWeight: 900, color: '#EFBF04', lineHeight: 1 }}>{v}</div>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 9, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.6)', marginTop: 4 }}>{l}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right – editorial text */}
|
||||
<div style={{ background: '#fff', padding: isMobile ? '32px 24px 40px' : '80px 72px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Ein Gewinn für alle</span>
|
||||
<h2 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(2rem, 3.2vw, 2.8rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: '0 0 20px' }}>
|
||||
AUSZEICHNUNG<br />FÜR DIE BESTEN.
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
{/* Stats row – mobile only, below the image */}
|
||||
{isMobile && (
|
||||
<div style={{ display: 'flex', gap: 16, marginBottom: 28, paddingBottom: 24, borderBottom: '1px solid #D0D5DD' }}>
|
||||
{[['20+', 'Jahre Exzellenz'], ['0 €', 'Teilnahmegebühr'], ['100%', 'Unabhängig']].map(([v, l]) => (
|
||||
<div key={l} style={{ flex: 1 }}>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 26, fontWeight: 900, color: '#101828', lineHeight: 1 }}>{v}</div>
|
||||
<div style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 9, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: '#4A8FC9', marginTop: 6 }}>{l}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ width: 40, height: 2, background: '#EFBF04', marginBottom: 28, display: isMobile ? 'none' : 'block' }} />
|
||||
<blockquote style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 18, fontStyle: 'italic', color: '#101828', lineHeight: 1.7, borderLeft: '3px solid #EFBF04', paddingLeft: 20, margin: '0 0 24px' }}>
|
||||
"Ein Unternehmen zu gründen erfordert nicht allein spezielle Fähigkeiten. Es erfordert Persönlichkeit!"
|
||||
</blockquote>
|
||||
<p style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 17, color: 'rgba(16,24,40,0.6)', lineHeight: 1.7, margin: '0 0 36px' }}>
|
||||
Wir suchen Vorbilder, die sich trotz aller Risiken nicht scheuen, Visionen in Businesspläne und Ideen in Unternehmungen zu verwandeln, und das mit großem persönlichen Einsatz und Verantwortung für Ihre Mitarbeiter. Seit vielen Jahren würdigen wir herausragende unternehmerische Leistungen im Freistaat.
|
||||
</p>
|
||||
<Link
|
||||
to="/der-bmp"
|
||||
style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 15, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: '#101828', background: '#EFBF04', padding: '14px 28px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8, alignSelf: isMobile ? 'stretch' : 'flex-start', transition: 'background 0.15s, box-shadow 0.2s' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#EFBF04'; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Mehr über den Preis <ChevronRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Status Phase Slider */}
|
||||
<StatusSlider />
|
||||
|
||||
{/* Winners Grid – neue Preisträger-Übersicht */}
|
||||
<section style={{ background: '#111D55' }}>
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '72px 80px 48px', display: 'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'flex-start' : 'flex-end', justifyContent: 'space-between', gap: isMobile ? 16 : 0 }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: '#EFBF04', display: 'block', marginBottom: 12 }}>Success Stories</span>
|
||||
<h2 style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 'clamp(2rem, 4vw, 3rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', margin: 0, lineHeight: 1 }}>
|
||||
DIE BESTEN UNTERNEHMEN IN BAYERN
|
||||
</h2>
|
||||
</div>
|
||||
<Link
|
||||
to="/preistraeger"
|
||||
style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 15, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#EFBF04', textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6, paddingBottom: 4, borderBottom: '1px solid #EFBF04', whiteSpace: 'nowrap' }}
|
||||
>
|
||||
Alle Preisträger <ChevronRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? undefined : 'repeat(4, 1fr)',
|
||||
gridAutoFlow: isMobile ? 'column' : undefined,
|
||||
gridTemplateRows: isMobile ? 'repeat(2, 1fr)' : undefined,
|
||||
gridAutoColumns: isMobile ? '66vw' : undefined,
|
||||
overflowX: isMobile ? 'auto' : undefined,
|
||||
scrollSnapType: isMobile ? 'x mandatory' : undefined,
|
||||
gap: isMobile ? 8 : 0,
|
||||
padding: isMobile ? '0 16px 8px' : 0,
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
scrollbarWidth: 'none',
|
||||
}}>
|
||||
{WINNERS.filter(w => w.year === 2025).slice(0, 8).map(w => (
|
||||
<HomeWinnerCard key={w.id} winner={w} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Testimonials Section */}
|
||||
<TestimonialsSection />
|
||||
|
||||
|
||||
{/* Benefits Section – editorial split */}
|
||||
<section style={{ overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 45%', minHeight: isMobile ? 'auto' : 560 }}>
|
||||
|
||||
{/* Left – text on cream */}
|
||||
<div style={{ background: '#E4E2E3', padding: isMobile ? '32px 24px 44px' : '80px 72px', display: 'flex', flexDirection: 'column', justifyContent: 'center', order: isMobile ? 2 : 0 }}>
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Mehr als nur ein Preis</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3vw, 2.6rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: '0 0 48px' }}>
|
||||
WARUM SICH DIE<br />TEILNAHME LOHNT.
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Numbered rows – no cards, no shadows */}
|
||||
<div style={{ borderTop: '1px solid #D0D5DD' }}>
|
||||
{[
|
||||
{ num: '01', title: 'Netzwerk', desc: 'Direkter Zugang zu Entscheidern aus Staatsregierung, Wirtschaft und Wissenschaft.' },
|
||||
{ num: '02', title: 'Sichtbarkeit', desc: 'Breite mediale Begleitung durch TV-, Radio- und Print-Partner bayernweit.' },
|
||||
{ num: '03', title: 'Bestätigung', desc: 'Ein unabhängiger Qualitätsnachweis – das stärkste Siegel für Ihren Marktauftritt.' },
|
||||
].map((item, i) => (
|
||||
<div
|
||||
key={i}
|
||||
style={{ display: 'grid', gridTemplateColumns: '48px 1fr', gap: '0 20px', padding: '24px 0', borderBottom: '1px solid #D0D5DD', cursor: 'default', transition: 'background 0.15s' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.background = '#EAE7E6')}
|
||||
onMouseLeave={e => (e.currentTarget.style.background = 'transparent')}
|
||||
>
|
||||
<span style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, color: '#EFBF04', letterSpacing: '0.1em', paddingTop: 2 }}>{item.num}</span>
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 5 }}>{item.title}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 16, color: 'rgba(16,24,40,0.55)', lineHeight: 1.6 }}>{item.desc}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right – full-bleed photo (+ heading on mobile) */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : 'auto', order: isMobile ? 1 : 0 }}>
|
||||
<img
|
||||
src="/images/networking-innenhof.jpg"
|
||||
alt="BMP Gala Netzwerk"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center center', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile
|
||||
? 'linear-gradient(to top, rgba(3,9,58,0.92) 0%, rgba(3,9,58,0.5) 36%, rgba(3,9,58,0.1) 70%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.5) 0%, transparent 55%)'
|
||||
: 'linear-gradient(to right, #E4E2E3 0%, transparent 30%), linear-gradient(to top, rgba(3,9,58,0.82) 0%, transparent 50%)' }} />
|
||||
{/* Heading overlay – mobile only (bottom-left) */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 26px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#8FBEEC', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Mehr als nur ein Preis</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.9rem, 8vw, 2.4rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.5)' }}>
|
||||
WARUM SICH DIE<br />TEILNAHME LOHNT.
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
{/* Bottom-left label – desktop only */}
|
||||
{!isMobile && (
|
||||
<div style={{ position: 'absolute', bottom: 40, left: 40 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', color: '#EFBF04', marginBottom: 6 }}>BMP Gala-Netzwerk</div>
|
||||
<div style={{ width: 32, height: 2, background: '#EFBF04' }} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA Section – with embedded form */}
|
||||
<section style={{ background: '#111D55', position: 'relative', overflow: 'hidden', height: isMobile ? 'auto' : 'calc(100vh - 60px)', display: 'flex', flexDirection: 'column' }} id="bewerben">
|
||||
{/* Subtle radial glow behind left copy */}
|
||||
<div style={{ position: 'absolute', left: -120, top: '50%', transform: 'translateY(-50%)', width: 600, height: 600, borderRadius: '50%', background: 'radial-gradient(circle, rgba(5,26,135,0.35) 0%, transparent 70%)', pointerEvents: 'none' }} />
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr', position: 'relative', flex: isMobile ? 'none' : 1, minHeight: 0, overflow: 'hidden' }}>
|
||||
|
||||
{/* Left – pitch copy */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 24px' : '36px 36px 32px 52px', display: 'flex', flexDirection: 'column', justifyContent: 'center', overflow: 'hidden' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.36em', fontWeight: 700, display: 'block', marginBottom: 16, opacity: 0.8 }}>Chance ergreifen</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.8rem, 8vw, 2.6rem)' : 'clamp(1.8rem, 2.8vw, 2.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 1.0, marginBottom: 16 }}>
|
||||
SCHREIBEN<br />AUCH SIE<br />GESCHICHTE.
|
||||
</h2>
|
||||
<div style={{ width: 32, height: 2, background: '#EFBF04', marginBottom: 20 }} />
|
||||
<p style={{ fontFamily: FF, fontSize: 15, color: 'rgba(255,255,255,0.6)', lineHeight: 1.7, marginBottom: 32 }}>
|
||||
Werden Sie Teil der Wall of Fame des bayerischen Mittelstands – vollständig kostenfrei.
|
||||
</p>
|
||||
|
||||
{/* Benefit rows */}
|
||||
<div style={{ borderTop: '1px solid rgba(255,255,255,0.08)' }}>
|
||||
{[
|
||||
{ num: '01', label: 'Kostenfrei', desc: 'Ohne Teilnahmegebühr' },
|
||||
{ num: '02', label: 'Jury', desc: 'Aus Wissenschaft und Praxis' },
|
||||
{ num: '03', label: 'Sichtbarkeit', desc: 'Medial bayernweit' },
|
||||
{ num: '04', label: 'Gala', desc: 'Verleihung München' },
|
||||
].map(item => (
|
||||
<div key={item.num} style={{ display: 'grid', gridTemplateColumns: '24px 1fr', gap: '0 14px', padding: '13px 0', borderBottom: '1px solid rgba(255,255,255,0.06)', alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, color: 'rgba(239,191,4,0.55)', letterSpacing: '0.1em' }}>{item.num}</span>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.08em' }}>{item.label}</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 14, color: 'rgba(255,255,255,0.45)', textAlign: 'right' }}>{item.desc}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
{!isMobile && <div style={{ background: 'rgba(255,255,255,0.07)' }} />}
|
||||
|
||||
{/* Right – gold premium panel */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
|
||||
{/* Premium award crosshatch pattern */}
|
||||
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 0 }} aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="bmpCross" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
<path d="M0,0 L18,18 M18,0 L0,18" stroke="rgba(17,29,85,0.055)" strokeWidth="0.65" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#bmpCross)" />
|
||||
</svg>
|
||||
|
||||
{/* Inner vignette – edges slightly deeper gold */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at center, transparent 55%, rgba(100,70,0,0.25) 100%)', pointerEvents: 'none', zIndex: 0 }} />
|
||||
|
||||
{/* Award ceremony photo */}
|
||||
{!isMobile && (
|
||||
<div style={{ height: 220, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
||||
<img
|
||||
src="/images/preisuebergabe.jpg"
|
||||
alt="Preisverleihung Bayerischer Mittelstandspreis"
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 25%', filter: 'sepia(0.18) brightness(0.92)' }}
|
||||
/>
|
||||
{/* Blend photo into gold panel */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 14, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ width: 5, height: 5, borderRadius: '50%', background: 'rgba(17,29,85,0.7)' }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(17,29,85,0.75)', textTransform: 'uppercase', letterSpacing: '0.2em' }}>Preisverleihung 2025</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Form area */}
|
||||
<div style={{ padding: isMobile ? '32px 24px' : '24px 48px 32px 40px', flex: isMobile ? 'none' : 1, height: isMobile ? '82svh' : undefined, display: 'flex', flexDirection: 'column', minHeight: 0, position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(17,29,85,0.5)', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 8 }}>Direktbewerbung 2026</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.2rem, 1.8vw, 1.6rem)', fontWeight: 900, color: '#111D55', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, marginBottom: 24 }}>Kostenlos bewerben</h3>
|
||||
<BewerbungsForm theme="gold" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Footnote row */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '16px 24px 20px' : '14px 56px 18px', display: 'flex', flexWrap: 'wrap', justifyContent: 'center', textAlign: 'center', borderTop: '1px solid rgba(255,255,255,0.06)', flexShrink: 0 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, color: 'rgba(255,255,255,0.45)', marginRight: isMobile ? 6 : 10 }}>Kostenlos und unverbindlich –</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: 'rgba(239,191,4,0.8)' }}>keine Teilnahmegebühr</span>
|
||||
</div>
|
||||
<div style={{ height: 2, background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.25), transparent)', flexShrink: 0 }} />
|
||||
</section>
|
||||
|
||||
{/* Video Modal */}
|
||||
{showVideo && (
|
||||
<div className="fixed inset-0 z-[200] bg-black flex items-center justify-center p-6 bg-opacity-95">
|
||||
<button
|
||||
onClick={() => setShowVideo(false)}
|
||||
className="absolute top-8 right-8 text-white/60 hover:text-white transition-colors"
|
||||
>
|
||||
<X size={40} />
|
||||
</button>
|
||||
<div className="w-full max-w-6xl aspect-video bg-white/5 rounded-3xl overflow-hidden flex items-center justify-center relative">
|
||||
<div className="text-center">
|
||||
<Play size={80} className="text-accent mx-auto mb-6 opacity-40" />
|
||||
<p className="text-white/40 uppercase tracking-widest text-sm">Video-Player Platzhalter</p>
|
||||
<p className="text-white/60 mt-4 text-xs italic font-body">Hier würde das Image-Video des BMP geladen werden.</p>
|
||||
<Button onClick={() => setShowVideo(false)} className="mt-8" variant="outline">Schließen</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ─── StatusSlider ─────────────────────────────────────────────────────────────
|
||||
|
||||
function StatusSlider() {
|
||||
const isMobile = useIsMobile();
|
||||
const [active, setActive] = useState<number>(ACTIVE_PHASE);
|
||||
const [dragOffset, setDragOffset] = useState(0);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const startX = useRef<number | null>(null);
|
||||
const lastDelta = useRef(0);
|
||||
|
||||
// Swipe hint on mount: peek next slide briefly, then bounce back
|
||||
useEffect(() => {
|
||||
const peek = setTimeout(() => setDragOffset(-Math.round(window.innerWidth * 0.11)), 900);
|
||||
const back = setTimeout(() => setDragOffset(0), 1700);
|
||||
return () => { clearTimeout(peek); clearTimeout(back); };
|
||||
}, []);
|
||||
|
||||
const goTo = (i: number) => setActive(Math.max(0, Math.min(STATUS_PHASES.length - 1, i)));
|
||||
|
||||
const onStart = (x: number) => { startX.current = x; lastDelta.current = 0; setIsDragging(true); };
|
||||
const onMove = (x: number) => {
|
||||
if (startX.current === null) return;
|
||||
const d = x - startX.current;
|
||||
lastDelta.current = d;
|
||||
setDragOffset(d);
|
||||
};
|
||||
const onEnd = () => {
|
||||
if (startX.current === null) return;
|
||||
const d = lastDelta.current;
|
||||
startX.current = null;
|
||||
setIsDragging(false);
|
||||
setDragOffset(0);
|
||||
if (d < -60 && active < STATUS_PHASES.length - 1) goTo(active + 1);
|
||||
else if (d > 60 && active > 0) goTo(active - 1);
|
||||
};
|
||||
|
||||
const curPhase = STATUS_PHASES[active];
|
||||
|
||||
return (
|
||||
<section
|
||||
style={{
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
height: isMobile ? 'auto' : 480,
|
||||
minHeight: isMobile ? 360 : 'auto',
|
||||
cursor: isDragging ? 'grabbing' : 'grab',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
onMouseDown={e => onStart(e.clientX)}
|
||||
onMouseMove={e => onMove(e.clientX)}
|
||||
onMouseUp={onEnd}
|
||||
onMouseLeave={onEnd}
|
||||
onTouchStart={e => onStart(e.touches[0].clientX)}
|
||||
onTouchMove={e => onMove(e.touches[0].clientX)}
|
||||
onTouchEnd={onEnd}
|
||||
>
|
||||
{/* Track */}
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
height: '100%',
|
||||
width: `${STATUS_PHASES.length * 100}vw`,
|
||||
transform: `translateX(calc(${-active * 100}vw + ${dragOffset}px))`,
|
||||
transition: isDragging ? 'none' : 'transform 0.62s cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
willChange: 'transform',
|
||||
}}
|
||||
>
|
||||
{STATUS_PHASES.map(phase => (
|
||||
<StatusSlideCard key={phase.num} phase={phase} isMobile={isMobile} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Dots */}
|
||||
<div
|
||||
style={{ position: 'absolute', bottom: 28, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 6, zIndex: 10 }}
|
||||
onMouseDown={e => e.stopPropagation()}
|
||||
>
|
||||
{STATUS_PHASES.map((_, i) => (
|
||||
<button
|
||||
key={i}
|
||||
onClick={() => goTo(i)}
|
||||
style={{
|
||||
width: i === active ? 32 : 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
background: i === active ? curPhase.accent : 'rgba(255,255,255,0.22)',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
padding: 0,
|
||||
transition: 'all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Prev arrow */}
|
||||
{active > 0 && (
|
||||
<button
|
||||
onMouseDown={e => e.stopPropagation()}
|
||||
onClick={() => goTo(active - 1)}
|
||||
style={{ position: 'absolute', left: 28, top: '50%', transform: 'translateY(-50%)', zIndex: 10, background: 'rgba(255,255,255,0.08)', backdropFilter: 'blur(8px)', border: '1px solid rgba(255,255,255,0.15)', borderRadius: '50%', width: 48, height: 48, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: '#fff', fontSize: 22, lineHeight: 1, transition: 'background 0.2s' }}
|
||||
>‹</button>
|
||||
)}
|
||||
|
||||
{/* Next arrow */}
|
||||
{active < STATUS_PHASES.length - 1 && (
|
||||
<button
|
||||
onMouseDown={e => e.stopPropagation()}
|
||||
onClick={() => goTo(active + 1)}
|
||||
style={{ position: 'absolute', right: 28, top: '50%', transform: 'translateY(-50%)', zIndex: 10, background: 'rgba(255,255,255,0.08)', backdropFilter: 'blur(8px)', border: '1px solid rgba(255,255,255,0.15)', borderRadius: '50%', width: 48, height: 48, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: '#fff', fontSize: 22, lineHeight: 1, transition: 'background 0.2s' }}
|
||||
>›</button>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── StatusSlideCard ──────────────────────────────────────────────────────────
|
||||
|
||||
function StatusSlideCard({ phase, isMobile }: { phase: StatusPhase; isMobile: boolean }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100vw',
|
||||
height: '100%',
|
||||
flexShrink: 0,
|
||||
position: 'relative',
|
||||
background: phase.bg,
|
||||
overflow: 'hidden',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? '1fr' : '1fr 360px',
|
||||
}}
|
||||
>
|
||||
|
||||
{/* Left content */}
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '52px 80px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', position: 'relative', zIndex: 1, gap: isMobile ? 24 : 0 }}>
|
||||
|
||||
{/* Status badge + phase label */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, background: `${phase.accent}18`, border: `1px solid ${phase.accent}35`, borderRadius: 999, padding: '5px 14px' }}>
|
||||
{phase.pulse && <span className="animate-pulse" style={{ width: 6, height: 6, borderRadius: '50%', background: phase.accent, display: 'inline-block' }} />}
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.32em', textTransform: 'uppercase', color: phase.accent }}>{phase.tag}</span>
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.50)', letterSpacing: '0.15em', textTransform: 'uppercase' }}>{phase.phase}</span>
|
||||
</div>
|
||||
|
||||
{/* Headline + body + CTA */}
|
||||
<div>
|
||||
<h2 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.8rem, 8vw, 2.6rem)' : 'clamp(2.4rem, 3.8vw, 3.8rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 0.94, margin: '0 0 24px' }}>
|
||||
{phase.headline}
|
||||
</h2>
|
||||
<p style={{ fontFamily: '"Inter", sans-serif', fontSize: 17, color: 'rgba(255,255,255,0.68)', lineHeight: 1.8, marginBottom: 32, maxWidth: 520 }}>
|
||||
{phase.body}
|
||||
</p>
|
||||
{phase.cta ? (
|
||||
<Link
|
||||
to={phase.cta.to}
|
||||
onMouseDown={e => e.stopPropagation()}
|
||||
style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#101828', background: phase.accent, padding: '14px 32px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 10, transition: 'opacity 0.2s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
{phase.cta.label} <ChevronRight size={14} />
|
||||
</Link>
|
||||
) : (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<div style={{ width: 20, height: 1, background: 'rgba(255,255,255,0.2)' }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(255,255,255,0.50)', letterSpacing: '0.2em', textTransform: 'uppercase' }}>Kein Handlungsbedarf</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Meta */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<div style={{ width: 20, height: 1, background: phase.accent, opacity: 0.35 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: `${phase.accent}70`, letterSpacing: '0.18em', textTransform: 'uppercase' }}>{phase.meta}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right visual panel */}
|
||||
{!isMobile && <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 36, padding: '52px 48px', position: 'relative', zIndex: 1, borderLeft: '1px solid rgba(255,255,255,0.05)' }}>
|
||||
{phase.num !== '03' ? (
|
||||
/* Concentric rings for active phases */
|
||||
<div style={{ position: 'relative', width: 180, height: 180, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
{([0, 20, 44] as const).map((inset, i) => (
|
||||
<div key={inset} style={{ position: 'absolute', inset, borderRadius: '50%', border: `1px solid ${phase.accent}${['12', '25', '45'][i]}` }} />
|
||||
))}
|
||||
<div style={{ width: 76, height: 76, borderRadius: '50%', background: `${phase.accent}15`, border: `1px solid ${phase.accent}55`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, fontWeight: 900, color: phase.accent, letterSpacing: '0.05em' }}>{phase.num}</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
/* Success stats */
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 68, fontWeight: 900, color: phase.accent, lineHeight: 1, opacity: 0.9 }}>247</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 8, fontWeight: 700, letterSpacing: '0.35em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.50)', marginTop: 4, marginBottom: 20 }}>Bewerbungen</div>
|
||||
<div style={{ width: 1, height: 28, background: 'rgba(255,255,255,0.08)', margin: '0 auto 20px' }} />
|
||||
<div style={{ fontFamily: FF, fontSize: 44, fontWeight: 900, color: '#fff', lineHeight: 1 }}>3</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 8, fontWeight: 700, letterSpacing: '0.35em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.50)', marginTop: 4 }}>Preisträger</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Membership CTA – for active phases only */}
|
||||
{phase.num !== '03' && (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ width: 1, height: 20, background: 'rgba(255,255,255,0.08)', margin: '0 auto 20px' }} />
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
onMouseDown={e => e.stopPropagation()}
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.14em',
|
||||
textTransform: 'uppercase',
|
||||
color: phase.accent,
|
||||
border: `1.5px solid ${phase.accent}55`,
|
||||
background: 'transparent',
|
||||
textDecoration: 'none',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
padding: '11px 22px',
|
||||
transition: 'border-color 0.2s, color 0.2s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.borderColor = phase.accent;
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(e.currentTarget as HTMLElement).style.borderColor = `${phase.accent}55`;
|
||||
}}
|
||||
>
|
||||
Mitglied werden <ChevronRight size={13} />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Home;
|
||||
265
src/spa/pages/Impressum.tsx
Normal file
265
src/spa/pages/Impressum.tsx
Normal file
@@ -0,0 +1,265 @@
|
||||
import React from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const ANTHRA = '#1A2030';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#EFE5E3';
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
|
||||
const TOC = [
|
||||
{ id: 'betreiber', label: 'Angaben gem. §5 TMG' },
|
||||
{ id: 'datenschutz', label: 'Datenschutz' },
|
||||
{ id: 'kontaktformular', label: 'Kontaktformular' },
|
||||
{ id: 'betroffenenrechte', label: 'Betroffenenrechte' },
|
||||
{ id: 'aufsichtsbehoerde', label: 'Beschwerderecht' },
|
||||
{ id: 'verantwortlicher', label: 'Verantwortlicher' },
|
||||
{ id: 'privacy-policy', label: 'Privacy Policy' },
|
||||
{ id: 'bildnachweise', label: 'Bildnachweise' },
|
||||
{ id: 'haftung', label: 'Haftungsausschluss' },
|
||||
];
|
||||
|
||||
const ADDR = (
|
||||
<>
|
||||
VM Verbands-Management GmbH<br />
|
||||
Edelsbergstr. 8<br />
|
||||
80686 München<br />
|
||||
Tel. +49 (0) 89 – 57007-0<br />
|
||||
Fax +49 (0) 89 – 57007 260<br />
|
||||
info@vm-verbands-management.de<br />
|
||||
HRB 110222 AG München, gesetzl. vertreten durch Friedrich Marx
|
||||
</>
|
||||
);
|
||||
|
||||
export default function Impressum() {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<div style={{ background: CREAM, minHeight: '100vh' }}>
|
||||
|
||||
{/* ── HERO ──────────────────────────────────────────────────────────── */}
|
||||
<section style={{ background: ANTHRA, padding: isMobile ? '48px 24px 40px' : '64px 80px 52px', position: 'relative', overflow: 'hidden' }}>
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.2), transparent)` }} />
|
||||
<Link
|
||||
to="/"
|
||||
style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.18em', color: 'rgba(255,255,255,0.4)', textDecoration: 'none', marginBottom: 32, transition: 'color 0.15s' }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = '#fff')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.4)')}
|
||||
>
|
||||
<ArrowLeft size={12} /> Zurück zur Website
|
||||
</Link>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
|
||||
<div style={{ width: 32, height: 2, background: GOLD }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.35em', textTransform: 'uppercase', color: GOLD }}>Legal</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontWeight: 900, fontSize: isMobile ? 'clamp(1.8rem, 7vw, 2.6rem)' : 'clamp(2.4rem, 4vw, 3.2rem)', color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.02, margin: '0 0 12px' }}>
|
||||
Impressum
|
||||
</h1>
|
||||
<p style={{ fontFamily: FB, fontSize: 15, color: 'rgba(255,255,255,0.45)', margin: 0 }}>
|
||||
Angaben gemäß §5 TMG · <Link to="/datenschutz" style={{ color: 'rgba(239,191,4,0.7)', textDecoration: 'none' }}>Zur Datenschutzerklärung →</Link>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* ── BODY ──────────────────────────────────────────────────────────── */}
|
||||
<div style={{ maxWidth: 1100, margin: '0 auto', padding: isMobile ? '40px 24px' : '64px 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '200px 1fr', gap: isMobile ? 40 : 80, alignItems: 'start' }}>
|
||||
|
||||
{/* LEFT – sticky TOC */}
|
||||
{!isMobile && (
|
||||
<nav style={{ position: 'sticky', top: 80 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.28em', textTransform: 'uppercase', color: GOLD, marginBottom: 16 }}>Inhalt</div>
|
||||
<ul style={{ listStyle: 'none', margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
{TOC.map(item => (
|
||||
<li key={item.id}>
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
style={{ display: 'block', fontFamily: FB, fontSize: 12, color: 'rgba(17,29,85,0.5)', textDecoration: 'none', padding: '5px 0 5px 12px', borderLeft: '2px solid transparent', transition: 'color 0.15s, border-color 0.15s', lineHeight: 1.4 }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = NAVY; (e.currentTarget as HTMLElement).style.borderLeftColor = GOLD; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = 'rgba(17,29,85,0.5)'; (e.currentTarget as HTMLElement).style.borderLeftColor = 'transparent'; }}
|
||||
>{item.label}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div style={{ marginTop: 32, paddingTop: 20, borderTop: '1px solid rgba(17,29,85,0.1)' }}>
|
||||
<Link to="/datenschutz" style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.14em', color: NAVY, textDecoration: 'none' }}>
|
||||
Datenschutzerklärung →
|
||||
</Link>
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
{/* RIGHT – content */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 56 }}>
|
||||
|
||||
<Section id="betreiber" title="Angaben gemäß §5 TMG">
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY, marginBottom: 8 }}>Informationen über den Verantwortlichen</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY, marginBottom: 8 }}>Angaben zum Webseitenbetreiber</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
<p style={body}>Inhaltlich Verantwortlicher gemäß TMG: VM Verbands-Management GmbH, gesetzl. vertreten durch Friedrich Marx</p>
|
||||
</Section>
|
||||
|
||||
<Section id="datenschutz" title="Datenschutz & Datenverarbeitung">
|
||||
<p style={body}>Alle personenbezogenen Informationen werden vertraulich und gemäß den gesetzlichen Vorschriften behandelt, wie in der <Link to="/datenschutz" style={{ color: NAVY, fontWeight: 600 }}>Datenschutzerklärung</Link> erläutert. Den Schutz der persönlichen Daten nehmen wir als Webseitenbetreiber sehr ernst.</p>
|
||||
<p style={body}>Ein Besuch unserer Webseiten ist möglich, ohne Angaben zu Ihrer Person zu machen. Es werden bei jedem Zugriff auf unsere Website Nutzungsdaten durch Ihren Internetbrowser übermittelt und in Protokolldaten (Server-Logfiles) gespeichert. Zu diesen gespeicherten Daten gehören z. B. Name der aufgerufenen Seite, Datum und Uhrzeit des Abrufs, übertragene Datenmenge und der anfragende Provider (IP-Adresse). Diese Daten dienen ausschließlich der Gewährleistung eines störungsfreien Betriebs unserer Website und zur Verbesserung unseres Angebotes. Eine Zuordnung dieser Daten zu einer bestimmten Person ist nicht möglich.</p>
|
||||
<p style={body}>Es erfolgt keine Zusammenführung dieser Daten mit anderen Datenquellen.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="kontaktformular" title="Erhebung und Verarbeitung beim Kontaktformular">
|
||||
<p style={body}>Sofern Sie uns über unsere Kontaktdaten eine E-Mail übersenden bzw. uns über das Kontaktformular informieren, erheben wir Ihre personenbezogenen Daten (Name, E-Mail-Adresse, Telefonnummer, Betreff, Nachrichtentext) nur in dem von Ihnen zur Verfügung gestellten Umfang. Die Datenverarbeitung dient dem Zweck der Kontaktaufnahme.</p>
|
||||
<p style={body}>Mit Absenden Ihrer Nachricht willigen Sie in die Verarbeitung der übermittelten Daten ein.</p>
|
||||
<Legal>Eine Verarbeitung erfolgt auf Grundlage des Art. 6 (1) lit. a DSGVO mit Ihrer Einwilligung.</Legal>
|
||||
<p style={body}>Sie können diese Einwilligung jederzeit durch Mitteilung an uns widerrufen. Ihre E-Mail-Adresse wird nur zur Bearbeitung Ihrer Anfrage genutzt. Ihre Daten werden anschließend gelöscht, sofern Sie der weitergehenden Verarbeitung und Nutzung nicht zugestimmt haben.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="betroffenenrechte" title="Betroffenenrechte">
|
||||
<p style={body}>Bei Vorliegen der gesetzlichen Voraussetzungen stehen Ihnen folgende Rechte nach Art. 15 bis 20 DSGVO zu:</p>
|
||||
<ul style={{ ...body, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<li>Recht auf Auskunft</li>
|
||||
<li>Recht auf Berichtigung</li>
|
||||
<li>Recht auf Löschung</li>
|
||||
<li>Recht auf Einschränkung der Verarbeitung</li>
|
||||
<li>Recht auf Datenübertragbarkeit</li>
|
||||
</ul>
|
||||
<Legal>Außerdem steht Ihnen nach Art. 21 (1) DSGVO ein Widerspruchsrecht gegen die Verarbeitungen zu, die auf Art. 6 (1) f DSGVO beruhen, sowie gegen die Verarbeitung zum Zwecke von Direktwerbung.</Legal>
|
||||
<p style={body}>Auf Wunsch können Sie uns kontaktieren. Die Kontaktdaten finden Sie unter <Link to="/kontakt" style={{ color: NAVY, fontWeight: 600 }}>Kontakt</Link>.</p>
|
||||
</Section>
|
||||
|
||||
<Section id="aufsichtsbehoerde" title="Beschwerderecht bei der Aufsichtsbehörde">
|
||||
<p style={body}>Sie haben gemäß Art. 77 DSGVO das Recht, sich bei der Aufsichtsbehörde zu beschweren, wenn Sie der Ansicht sind, dass die Verarbeitung Ihrer personenbezogenen Daten nicht rechtmäßig erfolgt.</p>
|
||||
<p style={{ ...body, fontWeight: 600, color: NAVY }}>Die zuständige Aufsichtsbehörde:</p>
|
||||
<AddressBlock>
|
||||
Bayerisches Landesamt für Datenschutzaufsicht<br />
|
||||
Postfach 606<br />
|
||||
91511 Ansbach<br />
|
||||
Deutschland<br />
|
||||
Tel. 09853-1300<br />
|
||||
Fax 09853-981300<br />
|
||||
E-Mail: poststelle@lda.bayern.de
|
||||
</AddressBlock>
|
||||
</Section>
|
||||
|
||||
<Section id="verantwortlicher" title="Name und Anschrift des Verantwortlichen">
|
||||
<p style={body}>Verantwortlicher im Sinne der Datenschutz-Grundverordnung und sonstiger datenschutzrechtlicher Bestimmungen ist der Webseitenbetreiber:</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
</Section>
|
||||
|
||||
<Section id="privacy-policy" title="Erklärung zum Datenschutz (Privacy Policy)">
|
||||
<p style={{ ...body, fontStyle: 'italic', borderLeft: `3px solid ${GOLD}`, paddingLeft: 16, marginBottom: 32 }}>
|
||||
Die Betreiber des Portals nehmen den Schutz der privaten Daten ernst. Die besondere Beachtung der Privatsphäre bei der Verarbeitung persönlicher Daten ist ein wichtiges Anliegen. Persönliche Daten werden gemäß den Bestimmungen des Bundesdatenschutzgesetzes BDSG verwendet; die Betreiber dieser Website verpflichten sich zur Verschwiegenheit. Diese Webseiten können Links zu Webseiten anderer Anbieter enthalten, auf die sich diese Datenschutzerklärung nicht erstreckt. Weitere wichtige Informationen finden sich auch in den Allgemeinen Nutzungsbedingungen.
|
||||
</p>
|
||||
|
||||
<SubSection num="1" title="Personenbezogene Daten">
|
||||
<p style={body}>Personenbezogene Daten sind Informationen, die dazu genutzt werden können, die Identität zu erfahren. Darunter fallen Informationen wie richtiger Name, Adresse, Postanschrift, Telefonnummer. Informationen, die nicht direkt mit der wirklichen Identität in Verbindung gebracht werden (wie zum Beispiel favorisierte Webseiten oder Anzahl der Nutzer einer Site) fallen nicht darunter.</p>
|
||||
<p style={body}>Die statistische Auswertung anonymisierter Datensätze bleibt vorbehalten. Wir nutzen die persönlichen Daten zu Zwecken der technischen Administration der Webseiten und zur Kundenverwaltung nur im jeweils dafür erforderlichen Umfang. Darüber hinaus werden persönliche Daten nur dann gespeichert, wenn diese freiwillig angegeben werden.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="2" title="Weitergabe personenbezogener Daten">
|
||||
<p style={body}>Wir verwenden personenbezogene Informationen nur für diese Webseite. Wir geben die Informationen nicht ohne ausdrückliches Einverständnis an Dritte weiter. Sollten im Rahmen der Auftragsdatenverarbeitung Daten an Dienstleister weitergegeben werden, so sind diese an das Bundesdatenschutzgesetz BDSG, andere gesetzliche Vorschriften und an diese Privacy Policy gebunden.</p>
|
||||
<p style={body}>Erhebungen beziehungsweise Übermittlungen persönlicher Daten an staatliche Einrichtungen und Behörden erfolgen nur im Rahmen zwingender Rechtsvorschriften.</p>
|
||||
<p style={body}>Bitte beachten Sie gesondert die Hinweise zur Datenverarbeitung im Zusammenhang mit Google reCAPTCHA unter <Link to="/datenschutz#recaptcha" style={{ color: NAVY }}>Datenschutz</Link>.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="3" title="Kinder">
|
||||
<p style={body}>Personen unter 18 Jahren sollten ohne Zustimmung der Eltern oder Erziehungsberechtigten keine personenbezogenen Daten an uns übermitteln. Wir fordern keine personenbezogenen Daten von Kindern an, sammeln diese nicht und geben sie nicht an Dritte weiter.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="4" title="Recht auf Widerruf">
|
||||
<p style={body}>Wenn Sie uns personenbezogene Daten überlassen haben, können Sie diese jederzeit im Benutzerprofil wieder ändern und löschen. Für eine vollständige Löschung des Accounts bitte an den Webmaster wenden. Bis zu diesem Zeitpunkt erfolgte Beiträge in Foren, Kommentaren, Terminankündigungen und Artikeln bleiben allerdings unter Umständen erhalten – Informationen dazu auch bei den allgemeinen Nutzungsbedingungen.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="5" title="Links zu anderen Websites">
|
||||
<p style={body}>Unser Online-Angebot enthält Links zu anderen Websites. Wir haben keinen Einfluss darauf, dass deren Betreiber die Datenschutzbestimmungen einhalten.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="6" title="Beiträge">
|
||||
<p style={body}>Die Beiträge auf unserer Seite sind für jeden zugänglich. Beiträge sollten vor der Veröffentlichung sorgfältig darauf überprüft werden, ob sie Angaben enthalten, die nicht für die Öffentlichkeit bestimmt sind. Die Beiträge werden möglicherweise in Suchmaschinen erfasst und auch ohne gezielten Aufruf dieser Website weltweit zugreifbar.</p>
|
||||
<p style={body}>Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. Für den Inhalt der verlinkten Seiten sind ausschließlich deren Betreiber verantwortlich. Alle hier verwendeten Namen, Begriffe, Zeichen und Grafiken können Marken- oder Warenzeichen im Besitze ihrer rechtlichen Eigentümer sein. Die Rechte aller erwähnten und benutzten Marken- und Warenzeichen liegen ausschließlich bei deren Besitzern.</p>
|
||||
</SubSection>
|
||||
|
||||
<SubSection num="7" title="Fragen und Kommentare">
|
||||
<p style={body}>Bei Fragen und für Anregungen und Kommentare zum Thema Datenschutz bitte per Mail an den Webmaster wenden.</p>
|
||||
<AddressBlock>{ADDR}</AddressBlock>
|
||||
</SubSection>
|
||||
</Section>
|
||||
|
||||
<Section id="bildnachweise" title="Bildnachweise">
|
||||
<ul style={{ ...body, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<li>Headline Maximilianeum: © Dietmar Egerer, München</li>
|
||||
<li>Ingrid Großmann, Taufkirchen</li>
|
||||
<li>EWIF Deutschland, München</li>
|
||||
<li>icon.icons.com</li>
|
||||
<li>Bilder zum Bayerischen Mittelstandspreis: © VM Verbands-Management GmbH, gesetzl. vertreten durch Friedrich Marx</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<Section id="haftung" title="Haftungsausschluss">
|
||||
<p style={body}>Trotz sorgfältiger inhaltlicher Kontrolle übernehmen wir keine Haftung für die Inhalte externer Links. Für den Inhalt der verlinkten Seiten sind ausschließlich deren Betreiber verantwortlich.</p>
|
||||
<p style={body}>Alle hier verwendeten Namen, Begriffe, Zeichen und Grafiken können Marken- oder Warenzeichen im Besitze ihrer rechtlichen Eigentümer sein. Die Rechte aller erwähnten und benutzten Marken- und Warenzeichen liegen ausschließlich bei deren Besitzern.</p>
|
||||
<p style={body}>Einen allgemeinen Haftungsausschluss finden Sie unter:{' '}
|
||||
<a href="https://www.disclaimer.de/disclaimer.htm" target="_blank" rel="noopener noreferrer" style={{ color: NAVY }}>disclaimer.de</a>
|
||||
</p>
|
||||
</Section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── shared styles ── */
|
||||
const body: React.CSSProperties = {
|
||||
fontFamily: '"Inter", sans-serif',
|
||||
fontSize: 15,
|
||||
color: 'rgba(58,58,58,0.82)',
|
||||
lineHeight: 1.85,
|
||||
margin: '0 0 16px',
|
||||
overflowWrap: 'anywhere',
|
||||
};
|
||||
|
||||
function Section({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {
|
||||
return (
|
||||
<div id={id} style={{ scrollMarginTop: 80 }}>
|
||||
<div style={{ borderLeft: `3px solid ${GOLD}`, paddingLeft: 16, marginBottom: 28 }}>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.2em', color: NAVY, margin: 0 }}>
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
<div style={{ background: '#fff', padding: 'clamp(20px, 5vw, 28px) clamp(20px, 5vw, 32px)', boxShadow: '0 1px 3px rgba(0,0,0,0.06)' }}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SubSection({ num, title, children }: { num: string; title: string; children: React.ReactNode }) {
|
||||
return (
|
||||
<div style={{ marginBottom: 28 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 10 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: GOLD, letterSpacing: '0.12em' }}>{num}.</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: NAVY, margin: 0 }}>{title}</h3>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AddressBlock({ children }: { children: React.ReactNode }) {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<address style={{ fontFamily: '"Inter", sans-serif', fontSize: isMobile ? 15 : 14, color: 'rgba(58,58,58,0.75)', lineHeight: 1.9, fontStyle: 'normal', background: 'rgba(17,29,85,0.04)', padding: '16px 20px', borderLeft: '2px solid rgba(239,191,4,0.4)', marginBottom: 16, overflowWrap: 'anywhere' }}>
|
||||
{children}
|
||||
</address>
|
||||
);
|
||||
}
|
||||
|
||||
function Legal({ children }: { children: React.ReactNode }) {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<p style={{ fontFamily: '"Inter", sans-serif', fontSize: isMobile ? 15 : 14, color: NAVY, lineHeight: 1.75, background: 'rgba(17,29,85,0.04)', padding: '12px 16px', borderLeft: `3px solid ${NAVY}`, margin: '0 0 16px', fontWeight: 500, overflowWrap: 'anywhere' }}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
1479
src/spa/pages/MitgliedWerden.tsx
Normal file
1479
src/spa/pages/MitgliedWerden.tsx
Normal file
File diff suppressed because it is too large
Load Diff
876
src/spa/pages/Netzwerk.tsx
Normal file
876
src/spa/pages/Netzwerk.tsx
Normal file
@@ -0,0 +1,876 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { ChevronRight, X, ArrowRight, Globe, Linkedin, Building2, MapPin, ExternalLink } from 'lucide-react';
|
||||
import SponsoringForm from '@/spa/components/forms/SponsoringForm';
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#E4E2E3';
|
||||
|
||||
const ROLE_COLOR: Record<string, string> = {
|
||||
'Hauptsponsor': '#EFBF04',
|
||||
'Sponsor': '#2563EB',
|
||||
'Finanzpartner': '#16A34A',
|
||||
'Partner': '#111D55',
|
||||
'Medienpartner': '#DC2626',
|
||||
};
|
||||
|
||||
// ── PersonCard (Schirmherrschaft) ─────────────────────────────────────────────
|
||||
|
||||
interface PersonCardProps {
|
||||
imgSrc: string;
|
||||
imgAlt: string;
|
||||
name: string;
|
||||
titleLine1: string;
|
||||
titleLine2: string;
|
||||
institution: string;
|
||||
borderRight?: boolean;
|
||||
}
|
||||
|
||||
function PersonCard({ imgSrc, imgAlt, name, titleLine1, titleLine2, institution, borderRight }: PersonCardProps) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileCard = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
style={{ borderRight: borderRight && !isMobileCard ? '1px solid rgba(255,255,255,0.08)' : 'none', display: 'flex', flexDirection: 'column', ...(isMobileCard ? { minWidth: '85vw', maxWidth: '85vw', flexShrink: 0, scrollSnapAlign: 'start', borderRadius: 16, overflow: 'hidden' } : {}) }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<div style={{ position: 'relative', height: isMobileCard ? 250 : 320, overflow: 'hidden', width: '100%' }}>
|
||||
<img
|
||||
src={imgSrc}
|
||||
alt={imgAlt}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', filter: hovered ? 'grayscale(0%)' : 'grayscale(100%)', transition: 'filter 0.55s ease, transform 0.55s ease', transform: hovered ? 'scale(1.04)' : 'scale(1)' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(3,9,58,0.8) 0%, transparent 60%)', pointerEvents: 'none' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 3, background: GOLD }} />
|
||||
</div>
|
||||
<div style={{ padding: isMobileCard ? '28px 24px' : '36px 40px', background: NAVY, flex: 1 }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 20, fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, marginBottom: 10 }}>{name}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 400, color: `${GOLD}CC`, lineHeight: 1.6, marginBottom: 2 }}>{titleLine1}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 400, color: 'rgba(255,255,255,0.5)', lineHeight: 1.6 }}>{titleLine2}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.2em', color: 'rgba(255,255,255,0.3)', marginTop: 12 }}>{institution}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── JuryCard ──────────────────────────────────────────────────────────────────
|
||||
|
||||
interface JuryMember {
|
||||
name: string;
|
||||
role: string;
|
||||
bio: string;
|
||||
img: string;
|
||||
}
|
||||
|
||||
const JuryCard: React.FC<{ member: JuryMember; idx: number }> = ({ member, idx }) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileCard = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{ borderLeft: !isMobileCard && idx > 0 ? '1px solid rgba(255,255,255,0.07)' : 'none', display: 'flex', flexDirection: 'column', cursor: 'default', background: hovered ? 'rgba(255,255,255,0.03)' : 'transparent', transition: 'background 0.2s', ...(isMobileCard ? { minWidth: '74vw', maxWidth: '74vw', flexShrink: 0, scrollSnapAlign: 'start', border: '1px solid rgba(255,255,255,0.08)', borderRadius: 16, overflow: 'hidden' } : {}) }}
|
||||
>
|
||||
<div style={{ position: 'relative', overflow: 'hidden', aspectRatio: '3/4' }}>
|
||||
<img src={member.img} alt={member.name} style={{ width: '100%', height: '100%', objectFit: 'cover', filter: hovered ? 'none' : 'grayscale(100%)', transition: 'filter 0.5s', display: 'block' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: '40%', background: 'linear-gradient(to top, rgba(3,9,58,0.65), transparent)' }} />
|
||||
</div>
|
||||
<div style={{ padding: isMobileCard ? '28px 28px 32px' : '32px 32px 36px' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 20, fontWeight: 700, color: '#fff', marginBottom: 5 }}>{member.name}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 12, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.16em', fontWeight: 700, marginBottom: 14 }}>{member.role}</div>
|
||||
<div style={{ width: hovered ? '100%' : 24, height: 1, background: GOLD, opacity: 0.4, transition: 'width 0.4s ease', marginBottom: 14 }} />
|
||||
<div style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.55)', lineHeight: 1.7 }}>{member.bio}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── JuryChairCard (Vorsitz – prominent) ───────────────────────────────────────
|
||||
|
||||
const JuryChairCard: React.FC<{ member: JuryMember }> = ({ member }) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileCard = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobileCard ? '1fr' : '380px 1fr',
|
||||
gap: 0,
|
||||
background: 'rgba(255,255,255,0.03)',
|
||||
border: `1px solid ${GOLD}40`,
|
||||
borderRadius: 20,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div style={{ position: 'relative', overflow: 'hidden', aspectRatio: isMobileCard ? '16/10' : '3/4', minHeight: isMobileCard ? 240 : 'auto' }}>
|
||||
<img src={member.img} alt={member.name} style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center top', filter: hovered ? 'none' : 'grayscale(100%)', transition: 'filter 0.5s', display: 'block' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: '45%', background: 'linear-gradient(to top, rgba(3,9,58,0.7), transparent)' }} />
|
||||
</div>
|
||||
<div style={{ padding: isMobileCard ? '32px 28px 36px' : '56px 56px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
<span style={{ alignSelf: 'flex-start', fontFamily: FF, fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.18em', color: NAVY, background: GOLD, padding: '7px 16px', borderRadius: 999, marginBottom: 24 }}>
|
||||
Jury-Vorsitz
|
||||
</span>
|
||||
<div style={{ fontFamily: FF, fontSize: isMobileCard ? 26 : 34, fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.05, marginBottom: 10 }}>{member.name}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 13, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.18em', fontWeight: 700, marginBottom: 24 }}>{member.role}</div>
|
||||
<div style={{ width: 48, height: 2, background: GOLD, opacity: 0.5, marginBottom: 24 }} />
|
||||
<div style={{ fontFamily: FB, fontSize: isMobileCard ? 18 : 21, color: 'rgba(255,255,255,0.6)', lineHeight: 1.7, maxWidth: 620 }}>{member.bio}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── PartnerCell ───────────────────────────────────────────────────────────────
|
||||
|
||||
interface Partner {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
tier: 1 | 2 | 3;
|
||||
desc: string;
|
||||
fullDesc: string;
|
||||
logo: React.ReactNode;
|
||||
industry: string;
|
||||
location: string;
|
||||
website: string;
|
||||
heroImg?: string;
|
||||
linkedin?: string;
|
||||
}
|
||||
|
||||
const PartnerCell: React.FC<{ partner: Partner; idx: number; total: number; onClick: () => void }> = ({ partner, idx, total, onClick }) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileCell = useIsMobile();
|
||||
const borderLeft = isMobileCell ? 'none' : (idx % 4 === 0 ? 'none' : '1px solid rgba(3,9,58,0.08)');
|
||||
const showBottom = isMobileCell ? idx < total - 1 : idx < 8;
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{ padding: isMobileCell ? '24px 20px' : '36px 32px', borderLeft, borderBottom: showBottom ? '1px solid rgba(3,9,58,0.08)' : 'none', display: 'flex', flexDirection: 'column', gap: 16, cursor: 'pointer', background: hovered ? '#E8E5E4' : 'transparent', transition: 'background 0.15s' }}
|
||||
>
|
||||
<div style={{ height: 48, display: 'flex', alignItems: 'center' }}>{partner.logo}</div>
|
||||
<div style={{ width: hovered ? 48 : 20, height: 1, background: GOLD, transition: 'width 0.3s ease' }} />
|
||||
<div style={{ fontFamily: FF, fontSize: 18, fontWeight: 700, color: '#101828' }}>{partner.name}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.2em', fontWeight: 700 }}>{partner.role}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.45)', lineHeight: 1.6, flexGrow: 1 }}>{partner.desc}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em', color: GOLD, fontWeight: 700, display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||
Details <ArrowRight size={10} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── SponsorCell (tiered) ──────────────────────────────────────────────────────
|
||||
|
||||
const SponsorCell: React.FC<{ partner: Partner; variant: 'lg' | 'md' | 'sm'; idx: number; cols: number; onClick: () => void }> = ({ partner, variant, idx, cols, onClick }) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobileCell = useIsMobile();
|
||||
const lg = variant === 'lg';
|
||||
const sm = variant === 'sm';
|
||||
const lastCol = (idx % cols) === cols - 1;
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{
|
||||
padding: isMobileCell ? '24px 20px' : lg ? '40px 36px' : sm ? '28px 28px' : '32px 32px',
|
||||
borderRight: !lastCol && !isMobileCell ? '1px solid rgba(3,9,58,0.08)' : 'none',
|
||||
borderBottom: '1px solid rgba(3,9,58,0.08)',
|
||||
display: 'flex', flexDirection: 'column', gap: 14,
|
||||
cursor: 'pointer',
|
||||
background: hovered ? '#E8E5E4' : 'transparent',
|
||||
transition: 'background 0.15s',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{lg && (
|
||||
<span style={{ position: 'absolute', top: 18, right: 18, fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.18em', color: '#101828', background: GOLD, padding: '4px 10px', borderRadius: 100, zIndex: 1 }}>Premium</span>
|
||||
)}
|
||||
<div style={{ height: lg ? 52 : 44, display: 'flex', alignItems: 'center' }}>{partner.logo}</div>
|
||||
<div style={{ width: hovered ? 48 : 20, height: 1, background: GOLD, transition: 'width 0.3s ease' }} />
|
||||
<div style={{ fontFamily: FF, fontSize: lg ? 22 : 18, fontWeight: 700, color: '#101828', letterSpacing: '-0.01em', lineHeight: 1.15 }}>{partner.name}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: sm ? 10 : 11, color: GOLD, textTransform: 'uppercase', letterSpacing: '0.2em', fontWeight: 700 }}>{partner.role}</div>
|
||||
{!sm && <div style={{ fontFamily: FB, fontSize: lg ? 17 : 16, color: 'rgba(16,24,40,0.45)', lineHeight: 1.6, flexGrow: 1 }}>{partner.desc}</div>}
|
||||
<div style={{ fontFamily: FF, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em', color: GOLD, fontWeight: 700, display: 'flex', alignItems: 'center', gap: 4 }}>
|
||||
Details <ArrowRight size={10} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── PartnerModal ─────────────────────────────────────────────────────────────
|
||||
|
||||
function PartnerModal({ partner, onClose }: { partner: Partner; onClose: () => void }) {
|
||||
const accentColor = ROLE_COLOR[partner.role] ?? GOLD;
|
||||
|
||||
useEffect(() => {
|
||||
document.body.style.overflow = 'hidden';
|
||||
return () => { document.body.style.overflow = ''; };
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
|
||||
style={{
|
||||
position: 'fixed', inset: 0, zIndex: 500,
|
||||
background: 'rgba(0,0,0,0.4)',
|
||||
backdropFilter: 'blur(10px)',
|
||||
WebkitBackdropFilter: 'blur(10px)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
padding: 24, overflowY: 'auto',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
style={{
|
||||
background: '#fff', width: '100%', maxWidth: 720,
|
||||
boxShadow: '0 32px 80px rgba(0,0,0,0.35)',
|
||||
overflow: 'hidden', flexShrink: 0,
|
||||
maxHeight: '92vh', overflowY: 'auto',
|
||||
}}
|
||||
>
|
||||
{/* ── Hero ── */}
|
||||
<div style={{ position: 'relative', height: 220, flexShrink: 0, overflow: 'hidden' }}>
|
||||
{/* Background */}
|
||||
{partner.heroImg
|
||||
? <img src={partner.heroImg} alt="" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }} />
|
||||
: <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(135deg, ${accentColor}33 0%, ${NAVY} 70%)` }} />
|
||||
}
|
||||
{/* Gradient to white */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0) 35%, rgba(255,255,255,0.6) 75%, #fff 100%)' }} />
|
||||
|
||||
{/* Category badge – top left */}
|
||||
<div style={{ position: 'absolute', top: 20, left: 24 }}>
|
||||
<span style={{
|
||||
background: 'rgba(255,255,255,0.15)',
|
||||
backdropFilter: 'blur(8px)', WebkitBackdropFilter: 'blur(8px)',
|
||||
border: '1px solid rgba(255,255,255,0.25)',
|
||||
color: '#fff', padding: '5px 13px',
|
||||
fontFamily: FF, fontSize: 9, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.22em',
|
||||
display: 'inline-block',
|
||||
}}>
|
||||
{partner.role}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Social + Close – top right */}
|
||||
<div style={{ position: 'absolute', top: 16, right: 20, display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||
{partner.linkedin && (
|
||||
<a href={partner.linkedin} target="_blank" rel="noopener noreferrer" style={{
|
||||
width: 36, height: 36, borderRadius: '50%',
|
||||
background: 'rgba(255,255,255,0.92)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
color: NAVY, textDecoration: 'none',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.18)',
|
||||
}}>
|
||||
<Linkedin size={14} />
|
||||
</a>
|
||||
)}
|
||||
{partner.website && (
|
||||
<a href={`https://${partner.website}`} target="_blank" rel="noopener noreferrer" style={{
|
||||
width: 36, height: 36, borderRadius: '50%',
|
||||
background: 'rgba(255,255,255,0.92)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
color: NAVY, textDecoration: 'none',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.18)',
|
||||
}}>
|
||||
<Globe size={14} />
|
||||
</a>
|
||||
)}
|
||||
<button onClick={onClose} style={{
|
||||
width: 36, height: 36, borderRadius: '50%',
|
||||
background: 'rgba(255,255,255,0.92)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
border: 'none', cursor: 'pointer',
|
||||
boxShadow: '0 2px 8px rgba(0,0,0,0.18)', color: NAVY,
|
||||
}}>
|
||||
<X size={15} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Logo box – bottom left (overflows hero) */}
|
||||
<div style={{
|
||||
position: 'absolute', bottom: -28, left: 28,
|
||||
width: 80, height: 80, background: '#fff',
|
||||
borderRadius: 12, boxShadow: '0 4px 24px rgba(0,0,0,0.14)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
padding: 10, zIndex: 2,
|
||||
}}>
|
||||
{partner.logo}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Content ── */}
|
||||
<div style={{ padding: '52px 32px 32px' }}>
|
||||
<h2 style={{
|
||||
fontFamily: FF, fontSize: 'clamp(1.5rem, 3vw, 2rem)',
|
||||
fontWeight: 900, color: '#101828',
|
||||
letterSpacing: '-0.025em', lineHeight: 1.05,
|
||||
margin: '0 0 10px',
|
||||
}}>
|
||||
{partner.name}
|
||||
</h2>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.65, margin: '0 0 24px' }}>
|
||||
{partner.desc}
|
||||
</p>
|
||||
|
||||
{/* 3 info cards */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginBottom: 28 }}>
|
||||
{[
|
||||
{ Icon: Building2, label: 'Branche', value: partner.industry },
|
||||
{ Icon: MapPin, label: 'Standort', value: partner.location },
|
||||
{ Icon: Globe, label: 'Web', value: partner.website },
|
||||
].map(({ Icon, label, value }) => (
|
||||
<div key={label} style={{ background: 'hsl(220,40%,97%)', padding: '14px 16px', borderRadius: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
|
||||
<Icon size={11} color="rgba(16,24,40,0.35)" />
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.14em', color: 'rgba(16,24,40,0.35)' }}>{label}</span>
|
||||
</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 17, fontWeight: 600, color: '#101828', lineHeight: 1.4, wordBreak: 'break-word' }}>{value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div style={{ height: 1, background: 'rgba(16,24,40,0.08)', marginBottom: 28 }} />
|
||||
|
||||
{/* Über section */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
|
||||
<div style={{ width: 4, height: 20, background: accentColor, borderRadius: 2, flexShrink: 0 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: '#101828' }}>
|
||||
Über das Unternehmen
|
||||
</span>
|
||||
</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 19, color: 'rgba(16,24,40,0.6)', lineHeight: 1.82, marginBottom: 36 }}>
|
||||
{partner.fullDesc}
|
||||
</p>
|
||||
|
||||
{/* CTAs */}
|
||||
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
||||
{partner.website && (
|
||||
<a
|
||||
href={`https://${partner.website}`}
|
||||
target="_blank" rel="noopener noreferrer"
|
||||
style={{
|
||||
padding: '13px 28px', background: GOLD, color: '#101828',
|
||||
fontFamily: FF, fontSize: 11, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.1em',
|
||||
textDecoration: 'none',
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8,
|
||||
transition: 'background 0.15s, box-shadow 0.2s',
|
||||
}}
|
||||
onMouseEnter={e => { const el = e.currentTarget as HTMLElement; el.style.background = '#FFD130'; el.style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.background = GOLD; el.style.boxShadow = 'none'; }}
|
||||
>
|
||||
Website besuchen <ExternalLink size={12} />
|
||||
</a>
|
||||
)}
|
||||
<button
|
||||
onClick={onClose}
|
||||
style={{
|
||||
padding: '13px 28px', background: 'transparent',
|
||||
color: 'rgba(16,24,40,0.45)', border: '1px solid rgba(16,24,40,0.12)',
|
||||
fontFamily: FF, fontSize: 11, fontWeight: 700,
|
||||
textTransform: 'uppercase', letterSpacing: '0.1em',
|
||||
cursor: 'pointer', transition: 'all 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => { const el = e.currentTarget as HTMLElement; el.style.background = NAVY; el.style.color = '#fff'; el.style.borderColor = NAVY; }}
|
||||
onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.background = 'transparent'; el.style.color = 'rgba(16,24,40,0.45)'; el.style.borderColor = 'rgba(16,24,40,0.12)'; }}
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Footer strip ── */}
|
||||
<div style={{
|
||||
background: 'hsl(220,20%,96%)', padding: '14px 32px',
|
||||
display: 'flex', justifyContent: 'space-between', alignItems: 'center',
|
||||
borderTop: '1px solid rgba(16,24,40,0.06)',
|
||||
}}>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'rgba(16,24,40,0.3)' }}>
|
||||
Bayerischer Mittelstandspreis 2026
|
||||
</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: accentColor }}>
|
||||
Offizieller {partner.role}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Netzwerk ──────────────────────────────────────────────────────────────────
|
||||
|
||||
const Netzwerk: React.FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const [selectedPartner, setSelectedPartner] = useState<Partner | null>(null);
|
||||
|
||||
const juryMembers: JuryMember[] = [
|
||||
{ name: 'Prof. Dr. Klaus Bergmann', role: 'Vorsitzender / LMU München', bio: 'Spezialist für KMU-Strategien und Innovations-Ökosysteme.', img: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&q=80&w=400' },
|
||||
{ name: 'Dr. Sabine Hofmann', role: 'IHK Bayern', bio: 'Expertin für digitale Transformation und regionale Wertschöpfung.', img: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=400' },
|
||||
{ name: 'Maximilian Reiter', role: 'Unternehmer', bio: 'CEO der Reiter Group, bringt die wertvolle Unternehmer-Perspektive ein.', img: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&q=80&w=400' },
|
||||
{ name: 'Dr. Elena Fischer', role: 'TU München', bio: 'Lehrstuhl für nachhaltige Unternehmensführung.', img: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=400' },
|
||||
];
|
||||
|
||||
const partners: Partner[] = [
|
||||
/* ── TIER 1 · Hauptsponsoren ─────────────────────────────── */
|
||||
{
|
||||
id: 'rsm', name: 'RSM Ebner Stolz', role: 'Hauptsponsor', tier: 1,
|
||||
desc: 'Führende mittelständische Wirtschaftsprüfungs- und Steuerberatungsgesellschaft.',
|
||||
fullDesc: 'RSM Ebner Stolz ist eine der größten unabhängigen Wirtschaftsprüfungs- und Steuerberatungsgesellschaften Deutschlands mit besonderer Expertise im Mittelstand. Als Hauptsponsor des BMP unterstützen sie die Identifikation herausragender Unternehmen und bringen ihre Netzwerke aktiv in die Nominierungsphase ein.',
|
||||
logo: (<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ display: 'flex', gap: 2 }}><span style={{ width: 10, height: 10, background: '#6b7280', display: 'block' }} /><span style={{ width: 10, height: 10, background: '#22c55e', display: 'block' }} /><span style={{ width: 10, height: 10, background: '#3b82f6', display: 'block' }} /></span><span style={{ fontWeight: 900, fontSize: 15, letterSpacing: '-0.02em', color: '#374151', fontFamily: FF }}>RSM <span style={{ color: '#6b7280', fontWeight: 600 }}>EBNER STOLZ</span></span></span>),
|
||||
industry: 'Wirtschaftsprüfung & Beratung', location: 'München, Bayern', website: 'rsm-ebner-stolz.de', linkedin: 'https://linkedin.com/company/rsm-ebner-stolz',
|
||||
},
|
||||
{
|
||||
id: 'wwk', name: 'WWK', role: 'Hauptsponsor', tier: 1,
|
||||
desc: 'Eine starke Gemeinschaft – Lebensversicherungsgruppe mit bayerischen Wurzeln.',
|
||||
fullDesc: 'Die WWK Lebensversicherung a. G. ist eine der leistungsstärksten deutschen Lebensversicherungsgruppen. Als Münchner Traditionsunternehmen verbindet die WWK tiefe bayerische Verwurzelung mit finanzieller Stärke – Werte, die sie mit dem Bayerischen Mittelstandspreis teilt.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 24, letterSpacing: '-0.02em', color: '#16a34a', fontFamily: 'Arial Black, sans-serif' }}>WWK</span>),
|
||||
industry: 'Lebensversicherung', location: 'München, Bayern', website: 'wwk.de', linkedin: 'https://linkedin.com/company/wwk-versicherung',
|
||||
},
|
||||
|
||||
/* ── TIER 2 · Medienpartner ──────────────────────────────── */
|
||||
{
|
||||
id: 'radiogong', name: 'Radio Gong 96.3', role: 'Medienpartner', tier: 2,
|
||||
desc: 'Der reichweitenstärkste Radiosender Münchens – Stimme des Mittelstands.',
|
||||
fullDesc: 'Radio Gong 96.3 ist der reichweitenstärkste Radiosender Münchens. Als Medienpartner des BMP sorgt er für Aufmerksamkeit für die Nominierten in Sendemitschnitten und redaktionellen Beiträgen.',
|
||||
logo: (<span style={{ background: '#e11d48', color: '#fff', fontWeight: 900, fontSize: 14, padding: '4px 10px', lineHeight: 1.25, display: 'inline-block', textAlign: 'center' as const, fontFamily: '"IBM Plex Sans", sans-serif' }}>Radio<br/>Gong <span style={{ color: '#fde047' }}>96.3</span></span>),
|
||||
industry: 'Medien', location: 'München', website: 'radiogong.com',
|
||||
},
|
||||
{
|
||||
id: 'muenchentv', name: 'münchen.tv', role: 'Medienpartner', tier: 2,
|
||||
desc: 'Der lokale Fernsehsender der Landeshauptstadt München.',
|
||||
fullDesc: 'münchen.tv ist der lokale Fernsehsender der Landeshauptstadt München. Als Medienpartner überträgt münchen.tv Highlights der BMP-Gala und produziert Porträts der Nominierten.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 15, color: '#0ea5e9', fontFamily: '"Inter", sans-serif' }}>münchen<span style={{ color: '#1e293b' }}>.tv</span></span>),
|
||||
industry: 'Medien', location: 'München', website: 'muenchen.tv',
|
||||
},
|
||||
|
||||
/* ── TIER 3 · Weitere Sponsoren ──────────────────────────── */
|
||||
{
|
||||
id: 'metzler', name: 'METZLER', role: 'Sponsor', tier: 3,
|
||||
desc: 'Älteste Privatbank Deutschlands – Unabhängigkeit seit 1674.',
|
||||
fullDesc: 'B. Metzler seel. Sohn & Co. KGaA ist die älteste deutsche Privatbank in Familienbesitz – seit über 350 Jahren unabhängig. Ihr Engagement für den BMP unterstreicht die tiefe Verbundenheit mit dem Mittelstand, dessen Werte wie Verlässlichkeit, Substanz und Langfristigkeit Metzler selbst verkörpert.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 21, letterSpacing: '0.15em', color: '#1a1a1a', fontFamily: 'Georgia, serif' }}>METZLER</span>),
|
||||
industry: 'Privatbankwesen', location: 'Frankfurt a. M.', website: 'metzler.com', linkedin: 'https://linkedin.com/company/metzler',
|
||||
},
|
||||
{
|
||||
id: 'wieselhuber', name: 'Dr. Wieselhuber & Partner', role: 'Sponsor', tier: 3,
|
||||
desc: 'Unabhängige Top-Management-Beratung für Familienunternehmen und Mittelstand.',
|
||||
fullDesc: 'Dr. Wieselhuber & Partner ist eine unabhängige, branchenübergreifende Top-Management-Beratung mit besonderem Fokus auf Familienunternehmen und Mittelstand. Als Sponsor bringt das Haus seine Strategie- und Transformationsexpertise in das Netzwerk des BMP ein.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 16, letterSpacing: '-0.01em', color: '#1a2b4a', fontFamily: FF }}>W&P <span style={{ fontWeight: 600, color: '#5a6b85' }}>WIESELHUBER</span></span>),
|
||||
industry: 'Unternehmensberatung', location: 'München, Bayern', website: 'wieselhuber.de',
|
||||
},
|
||||
{
|
||||
id: 'fristads', name: 'Fristads', role: 'Sponsor', tier: 3,
|
||||
desc: 'Premium-Arbeitsbekleidung – Funktion, Qualität und Design.',
|
||||
fullDesc: 'Fristads steht für hochwertige, funktionale Arbeitsbekleidung, die Schutz, Komfort und Design vereint. Als Sponsor des Bayerischen Mittelstandspreises unterstützt das Unternehmen die Auszeichnung herausragender mittelständischer Betriebe.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 19, letterSpacing: '0.02em', color: '#1a1a1a', fontFamily: 'Arial Black, sans-serif' }}>FRISTADS</span>),
|
||||
industry: 'Workwear & Textil', location: 'Deutschland', website: 'fristads.com',
|
||||
},
|
||||
{
|
||||
id: 'newedge', name: 'New Edge', role: 'Sponsor', tier: 3,
|
||||
desc: 'Digitale Markenführung, Web und Design für den Mittelstand.',
|
||||
fullDesc: 'New Edge gestaltet Marken, Web-Erlebnisse und digitale Auftritte für mittelständische Unternehmen. Als Sponsor des BMP unterstützt die Agentur die Sichtbarkeit und das digitale Profil ausgezeichneter Unternehmen.',
|
||||
logo: (<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 22, height: 22, background: '#3a3a3a', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 900, fontSize: 11, fontFamily: FF }}>NE</span><span style={{ fontWeight: 700, fontSize: 15, color: '#005E67', fontFamily: FF }}>New Edge</span></span>),
|
||||
industry: 'Branding & Digital', location: 'Bayern', website: 'newedgebrand.com',
|
||||
},
|
||||
{
|
||||
id: 'moodtalk', name: 'Moodtalk', role: 'Sponsor', tier: 3,
|
||||
desc: 'Plattform für Teamkultur und Mitarbeiter-Feedback.',
|
||||
fullDesc: 'Moodtalk ist eine Plattform für Teamkultur, Stimmung und kontinuierliches Mitarbeiter-Feedback. Als Sponsor des BMP steht das Unternehmen für moderne, wertebasierte Unternehmensführung.',
|
||||
logo: (<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><span style={{ width: 20, height: 20, borderRadius: '50%', background: '#7c3aed', display: 'block' }} /><span style={{ fontWeight: 700, fontSize: 16, color: '#7c3aed', fontFamily: FF }}>moodtalk</span></span>),
|
||||
industry: 'HR & Software', location: 'Bayern', website: 'moodtalk.io',
|
||||
},
|
||||
{
|
||||
id: 'deutschebank', name: 'Deutsche Bank', role: 'Sponsor', tier: 3,
|
||||
desc: 'Partnerbank für die Finanzierung und Skalierung von KMU-Wachstum.',
|
||||
fullDesc: 'Die Deutsche Bank begleitet mittelständische Unternehmen als verlässlicher Finanzpartner durch alle Wachstumsphasen. Im Rahmen des BMP stellt sie ihr deutschlandweites Netzwerk, spezifische Mittelstandsprodukte und direkte Ansprechpartner für die Nominierten bereit.',
|
||||
logo: (<span style={{ display: 'flex', alignItems: 'center', gap: 8 }}><svg width="20" height="20" viewBox="0 0 20 20"><rect x="1" y="1" width="18" height="18" fill="none" stroke="#1d1d1b" strokeWidth="1.5" /><line x1="5" y1="15" x2="15" y2="5" stroke="#1d1d1b" strokeWidth="2" /></svg><span style={{ fontWeight: 600, fontSize: 15, color: '#1d1d1b', fontFamily: FB }}>Deutsche Bank</span></span>),
|
||||
industry: 'Bankwesen & Finanzen', location: 'Frankfurt a. M.', website: 'db.com', linkedin: 'https://linkedin.com/company/deutsche-bank',
|
||||
},
|
||||
{
|
||||
id: 'bionorica', name: 'Bionorica', role: 'Sponsor', tier: 3,
|
||||
desc: 'Weltmarktführer für pflanzliche Arzneimittel aus dem bayerischen Neumarkt.',
|
||||
fullDesc: 'Bionorica SE ist ein international agierendes Pharmaunternehmen mit Sitz in Neumarkt i. d. OPf. und Weltmarktführer bei pflanzlichen Arzneimitteln. Das Unternehmen selbst ist ein Paradebeispiel eines bayerischen Mittelständlers mit globalem Anspruch und verkörpert die Innovationskraft, die der BMP würdigt.',
|
||||
logo: (<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}><svg width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="10" r="9" fill="#16a34a" /><path d="M10 3 Q14 7 14 10 Q14 14 10 17 Q6 14 6 10 Q6 7 10 3Z" fill="white" opacity="0.8" /></svg><span style={{ fontWeight: 700, fontSize: 15, color: '#16a34a', fontFamily: FB }}>Bionorica<sup style={{ fontSize: 8 }}>®</sup></span></span>),
|
||||
industry: 'Pharmaindustrie', location: 'Neumarkt i.d.OPf., Bayern', website: 'bionorica.de', linkedin: 'https://linkedin.com/company/bionorica',
|
||||
},
|
||||
{
|
||||
id: 'primus', name: 'Primus', role: 'Sponsor', tier: 3,
|
||||
desc: 'Partner des Bayerischen Mittelstandspreises.',
|
||||
fullDesc: 'Primus unterstützt als Sponsor den Bayerischen Mittelstandspreis und sein Engagement für herausragende Unternehmen des bayerischen Mittelstands.',
|
||||
logo: (<span style={{ fontWeight: 900, fontSize: 18, letterSpacing: '0.04em', color: '#b8860b', fontFamily: 'Georgia, serif' }}>PRIMUS</span>),
|
||||
industry: 'Partner', location: 'Bayern', website: '',
|
||||
},
|
||||
];
|
||||
|
||||
const expertiseRows = [
|
||||
{ num: '01', label: 'Aktenstudium', body: 'Alle Einreichungen werden zunächst vollständig gesichtet und nach den festgelegten Kriterien geprüft.' },
|
||||
{ num: '02', label: 'Scoring-Matrix', body: 'Jedes Jurymitglied bewertet die Einreichungen unabhängig nach den festgelegten Kriterien.' },
|
||||
{ num: '03', label: 'Jury-Plenum', body: 'In der gemeinsamen Sitzung werden Argumente und Ansichten ausgetauscht, Eigenschaften verglichen und gemeinsam bewertet. Daraus entsteht die Liste der Finalisten.' },
|
||||
{ num: '04', label: 'Ergebnis', body: 'Die Gewinner des Bayerischen Mittelstandspreises werden nach vorgegebenem Punktesystem bestimmt, erweitert um Jury-Mitglieder aus der Praxis.' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="animate-fade-in">
|
||||
|
||||
{/* ── 1. HERO ──────────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', minHeight: '72vh', display: 'flex', alignItems: 'flex-end', overflow: 'hidden', background: '#060C14' }}>
|
||||
<img src="/images/netzwerk-hero.jpg" alt="BMP Netzwerk Preisverleihung" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile ? 'linear-gradient(to top, rgba(2,9,48,0.95) 0%, rgba(2,9,48,0.72) 38%, rgba(2,9,48,0.22) 72%, transparent 100%)' : 'linear-gradient(to right, #020930 0%, rgba(2,9,48,0.90) 38%, rgba(2,9,48,0.18) 65%, transparent 100%)' }} />
|
||||
<div style={{ position: 'absolute', top: 0, left: 80, width: 2, height: '100%', background: `linear-gradient(to bottom, transparent, ${GOLD}, transparent)`, opacity: 0.4 }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.3), transparent)', zIndex: 2 }} />
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '0 24px 48px' : '0 80px 88px', maxWidth: 860 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 28 }}>
|
||||
<div style={{ width: 40, height: 2, background: GOLD }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: GOLD }}>Jury & Partner</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.6rem, 6vw, 5rem)' : 'clamp(2.8rem, 6vw, 5rem)', fontWeight: 900, color: '#fff', lineHeight: 0.95, letterSpacing: '-0.03em', textTransform: 'uppercase', margin: '0 0 28px' }}>
|
||||
DAS NETZWERK<br />HINTER DEM <span style={{ color: GOLD }}>AWARD.</span>
|
||||
</h1>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.65)', lineHeight: 1.7, maxWidth: 560, margin: 0, fontWeight: 300 }}>
|
||||
Der Bayerische Mittelstandspreis wird getragen von einem starken Netzwerk aus Schirmherrschaft, unabhängiger Fach-Jury und langjährigen Partnern aus Wirtschaft und Gesellschaft.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 2. SCHIRMHERRSCHAFT ──────────────────────────────────────────────── */}
|
||||
<section id="schirmherrschaft" style={{ background: NAVY }}>
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '80px 80px 56px' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: GOLD, display: 'block', marginBottom: 16 }}>Die Schirmherrschaft</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 4vw, 3rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1, margin: '0 0 20px' }}>Schirmherrin und Schirmherr</h2>
|
||||
<div style={{ width: 40, height: 2, background: GOLD, marginBottom: 14 }} />
|
||||
<p style={{ fontFamily: FF, fontSize: 18, color: 'rgba(255,255,255,0.5)', margin: 0 }}>des Bayerischen Mittelstandspreises</p>
|
||||
</div>
|
||||
|
||||
<div style={{ display: isMobile ? 'flex' : 'grid', gridTemplateColumns: isMobile ? undefined : '1fr 1fr', overflowX: isMobile ? 'auto' : undefined, scrollSnapType: isMobile ? 'x mandatory' : undefined, gap: isMobile ? 14 : 0, padding: isMobile ? '0 24px 28px' : 0, WebkitOverflowScrolling: 'touch', scrollbarWidth: 'none' }}>
|
||||
<PersonCard
|
||||
imgSrc="https://images.unsplash.com/photo-1551836022-d5d88e9218df?auto=format&fit=crop&q=80&w=800"
|
||||
imgAlt="Ilse Aigner"
|
||||
name="Ilse Aigner MdL"
|
||||
titleLine1="Präsidentin des Bayerischen Landtags"
|
||||
titleLine2="Bayerische Staatsministerin für Wirtschaft a.D."
|
||||
institution="Bayerischer Landtag"
|
||||
borderRight
|
||||
/>
|
||||
<PersonCard
|
||||
imgSrc="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&q=80&w=800"
|
||||
imgAlt="Hubert Aiwanger"
|
||||
name="Hubert Aiwanger MdL"
|
||||
titleLine1="Bayerischer Staatsminister für Wirtschaft,"
|
||||
titleLine2="Landesentwicklung und Energie · Stv. Ministerpräsident"
|
||||
institution="Bayerische Staatsregierung"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Grußwort – Ilse Aigner */}
|
||||
<div style={{ background: 'rgba(255,255,255,0.03)', borderTop: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
<div style={{ padding: isMobile ? '32px 24px' : '64px 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '40% 60%', gap: isMobile ? '24px 0' : '0 64px', alignItems: 'flex-start' }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: GOLD, display: 'block', marginBottom: 8 }}>Grußwort</span>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, fontWeight: 400, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'rgba(255,255,255,0.3)', marginBottom: 16 }}>Schirmherrin</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 18, fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.15, marginBottom: 10 }}>Ilse Aigner MdL</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 18, color: 'rgba(255,255,255,0.5)', lineHeight: 1.6, marginBottom: 4 }}>Präsidentin des Bayerischen Landtags</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, color: 'rgba(255,255,255,0.4)', lineHeight: 1.6 }}>Bayerische Staatsministerin für Wirtschaft a.D.</div>
|
||||
</div>
|
||||
<div>
|
||||
<blockquote style={{ fontFamily: FF, fontSize: 18, fontStyle: 'italic', color: 'rgba(255,255,255,0.8)', lineHeight: 1.75, margin: 0, paddingLeft: 24, borderLeft: `3px solid ${GOLD}` }}>
|
||||
"Der Bayerische Mittelstandspreis steht für das, was Bayern stark macht: Unternehmergeist, Verantwortung und Qualität. Mit großer Freude übernehme ich erneut die Schirmherrschaft für diesen bedeutenden Preis."
|
||||
</blockquote>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, color: 'rgba(255,255,255,0.35)', marginTop: 20, paddingLeft: 24 }}>
|
||||
– Ilse Aigner MdL, Präsidentin des Bayerischen Landtags
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.2), transparent)` }} />
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 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 ? (
|
||||
/* Mobile: one cohesive navy module – copy + compact stat strip */
|
||||
<div style={{ padding: '48px 24px', position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, display: 'block', marginBottom: 18 }}>Wer entscheidet?</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.7rem, 8vw, 2.2rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.08, margin: '0 0 22px' }}>
|
||||
UNABHÄNGIGE EXPERTISE FÜR DEN MITTELSTAND.
|
||||
</h2>
|
||||
<div style={{ width: 40, height: 2, background: GOLD, marginBottom: 22 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.55)', lineHeight: 1.75, margin: 0 }}>
|
||||
Die Jury des Bayerischen Mittelstandspreises besteht ausschließlich aus ehrenamtlich tätigen Expertinnen und Experten. Kein Mitglied steht in wirtschaftlicher Verbindung zu einem Bewerber – Transparenz und Unparteilichkeit sind die Grundpfeiler unseres Verfahrens.
|
||||
</p>
|
||||
{/* Stat strip */}
|
||||
<div style={{ display: 'flex', marginTop: 32, paddingTop: 26, borderTop: '1px solid rgba(255,255,255,0.14)' }}>
|
||||
{[
|
||||
{ v: '11', l: 'Jurymitglieder' },
|
||||
{ v: 'Mehrstufig', l: 'Bewertungsverfahren' },
|
||||
{ v: '100%', l: 'Unabhängig' },
|
||||
].map((s, i) => (
|
||||
<div key={i} style={{ flex: 1, minWidth: 0, paddingLeft: i > 0 ? 14 : 0, borderLeft: i > 0 ? '1px solid rgba(255,255,255,0.14)' : 'none' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(2.2rem, 9vw, 3rem)', fontWeight: 900, color: GOLD, letterSpacing: '-0.03em', lineHeight: 1 }}>{s.v}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'rgba(255,255,255,0.5)', marginTop: 8, lineHeight: 1.3 }}>{s.l}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Left – Cream, stats */}
|
||||
<div style={{ background: CREAM, padding: '72px 64px', display: 'flex', flexDirection: 'column', justifyContent: 'center', position: 'relative', zIndex: 1 }}>
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(5rem, 8.5vw, 7.5rem)', fontWeight: 900, color: '#101828', letterSpacing: '-0.04em', lineHeight: 1 }}>11</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.15em', color: 'rgba(16,24,40,0.4)', marginTop: 4 }}>Unabhängige Jurymitglieder</div>
|
||||
</div>
|
||||
<div style={{ width: '100%', height: 1, background: 'rgba(3,9,58,0.1)', margin: '32px 0' }} />
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(2.4rem, 4vw, 3.4rem)', fontWeight: 900, color: '#101828', letterSpacing: '-0.03em', lineHeight: 1 }}>Mehrstufig</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.15em', color: 'rgba(16,24,40,0.4)', marginTop: 8 }}>Bewertungsverfahren</div>
|
||||
</div>
|
||||
<div style={{ width: '100%', height: 1, background: 'rgba(3,9,58,0.1)', margin: '32px 0' }} />
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(5rem, 8.5vw, 7.5rem)', fontWeight: 900, color: '#101828', letterSpacing: '-0.04em', lineHeight: 1 }}>100%</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.15em', color: 'rgba(16,24,40,0.4)', marginTop: 4 }}>Unabhängig & ehrenamtlich</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Right – Navy, editorial copy */}
|
||||
<div style={{ background: NAVY, padding: '72px 64px', display: 'flex', flexDirection: 'column', justifyContent: 'center', position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, marginBottom: 20 }}>Wer entscheidet?</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.6rem, 2.5vw, 2.2rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.08, margin: '0 0 24px' }}>
|
||||
UNABHÄNGIGE EXPERTISE FÜR DEN MITTELSTAND.
|
||||
</h2>
|
||||
<div style={{ width: 40, height: 2, background: GOLD }} />
|
||||
<p style={{ marginTop: 24, fontFamily: FB, fontSize: 19, color: 'rgba(255,255,255,0.45)', lineHeight: 1.85 }}>
|
||||
Die Jury des Bayerischen Mittelstandspreises besteht ausschließlich aus ehrenamtlich tätigen Expertinnen und Experten. Kein Mitglied steht in wirtschaftlicher Verbindung zu einem Bewerber – Transparenz und Unparteilichkeit sind die Grundpfeiler unseres Verfahrens.
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 4. JURY-MITGLIEDER ───────────────────────────────────────────────── */}
|
||||
<section id="jury" style={{ background: NAVY, overflow: 'hidden', position: 'relative' }}>
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '80px 80px 56px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 16 : 48, alignItems: 'flex-end', borderBottom: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, display: 'block', marginBottom: 16 }}>Das Gremium</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.5vw, 3rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 0.95, margin: 0 }}>UNSERE JURY 2026</h2>
|
||||
</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 19, color: 'rgba(255,255,255,0.4)', lineHeight: 1.8, margin: 0 }}>
|
||||
Unabhängige Expertinnen und Experten aus Wirtschaft, Wissenschaft und Verbänden, für einen vollständig unabhängigen Bewertungsprozess.
|
||||
</p>
|
||||
</div>
|
||||
{/* ── Prominenter Vorsitz-Bereich ─────────────────────────────────── */}
|
||||
{/* TODO: echten Jury-Vorsitzenden bestätigen (Name & Foto sind Platzhalter) */}
|
||||
<div style={{ padding: isMobile ? '28px 24px 8px' : '64px 80px 16px' }}>
|
||||
<JuryChairCard member={juryMembers[0]} />
|
||||
</div>
|
||||
|
||||
{/* ── Übrige Jury-Mitglieder ──────────────────────────────────────── */}
|
||||
<div style={{ display: isMobile ? 'flex' : 'grid', gridTemplateColumns: isMobile ? undefined : 'repeat(3, 1fr)', overflowX: isMobile ? 'auto' : undefined, scrollSnapType: isMobile ? 'x mandatory' : undefined, gap: isMobile ? 14 : 0, padding: isMobile ? '24px 24px 12px' : '0', WebkitOverflowScrolling: 'touch', scrollbarWidth: 'none', borderTop: isMobile ? 'none' : '1px solid rgba(255,255,255,0.07)' }}>
|
||||
{juryMembers.slice(1).map((member, idx) => (
|
||||
<JuryCard key={idx} member={member} idx={idx} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* ── Hinweis: Doppelrolle Jury / Partner (#179) ──────────────────── */}
|
||||
<div style={{ padding: isMobile ? '4px 24px 36px' : '8px 80px 56px' }}>
|
||||
<p style={{ fontFamily: FB, fontSize: isMobile ? 13 : 14, color: 'rgba(255,255,255,0.35)', lineHeight: 1.6, margin: 0, maxWidth: 720 }}>
|
||||
Hinweis: Einzelne Persönlichkeiten engagieren sich sowohl in der Jury als auch als Partner des BMP – beide Rollen werden auf dieser Seite getrennt ausgewiesen.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 5. HINTERGRUND & EXPERTISE ───────────────────────────────────────── */}
|
||||
<section style={{ background: '#101828', overflow: 'hidden', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 45%', borderTop: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
<div style={{ padding: isMobile ? '48px 24px' : 80, display: 'flex', flexDirection: 'column', justifyContent: 'center', background: '#101828' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, display: 'block', marginBottom: 16 }}>Hintergrund & Expertise</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.8rem, 3vw, 2.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.0, margin: '0 0 24px' }}>WIE BEWERTET DIE JURY?</h2>
|
||||
<div style={{ width: 40, height: 2, background: GOLD, marginBottom: 40 }} />
|
||||
<div>
|
||||
{expertiseRows.map((row) => (
|
||||
<div key={row.num} style={{ display: 'grid', gridTemplateColumns: '40px 1fr', gap: '0 20px', padding: '20px 0', borderBottom: '1px solid rgba(255,255,255,0.06)', alignItems: 'center' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(239,191,4,0.5)' }}>{row.num}</div>
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 3 }}>{row.label}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.4)', lineHeight: 1.6 }}>{row.body}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '80px 64px', display: 'flex', flexDirection: 'column', justifyContent: 'center', borderLeft: isMobile ? 'none' : '1px solid rgba(255,255,255,0.07)', borderTop: isMobile ? '1px solid rgba(255,255,255,0.07)' : 'none', overflow: 'hidden', background: '#101828' }}>
|
||||
<span style={{ fontFamily: 'Georgia, serif', fontSize: 'clamp(60px, 8vw, 120px)', color: 'rgba(239,191,4,0.1)', lineHeight: 0.8, display: 'block', marginBottom: -20 }}>“</span>
|
||||
<p style={{ fontFamily: FF, fontSize: 'clamp(1.1rem, 1.8vw, 1.4rem)', fontWeight: 300, color: 'rgba(255,255,255,0.75)', lineHeight: 1.65, margin: '0 0 40px' }}>
|
||||
Die Jury des BMP ist vollständig von wirtschaftlichen Interessen unabhängig. Jede Entscheidung wird transparent nachvollzogen – das ist unser Versprechen an die Unternehmen Bayerns.
|
||||
</p>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<div style={{ width: 40, height: 2, background: GOLD, flexShrink: 0 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 17, color: 'rgba(255,255,255,0.4)' }}>Prof. Dr. Klaus Bergmann, Juryvorsitzender</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 6. PARTNER & SPONSOREN ───────────────────────────────────────────── */}
|
||||
<section id="partner" style={{ background: CREAM, overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ padding: isMobile ? '48px 24px 32px' : '80px 80px 56px', display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 12 : 0, justifyContent: 'space-between', alignItems: isMobile ? 'flex-start' : 'flex-end', borderBottom: '1px solid rgba(3,9,58,0.1)' }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: '#4A8FC9', display: 'block', marginBottom: 16 }}>Netzwerkqualität</span>
|
||||
<h2 style={{ fontFamily: FF, fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', fontSize: 'clamp(2rem, 3.5vw, 3rem)', lineHeight: 0.95, margin: 0 }}>PARTNER & SPONSOREN</h2>
|
||||
</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.4)', maxWidth: isMobile ? '100%' : 220, textAlign: isMobile ? 'left' : 'right', lineHeight: 1.6, margin: 0 }}>
|
||||
Partner in drei Kategorien: Hauptsponsoren, Medienpartner und weitere Sponsoren. Klicken für Details.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Tiered grid – continuous, ranks marked by label bars */}
|
||||
<div style={{ position: 'relative', zIndex: 1 }}>
|
||||
{([
|
||||
{ tier: 1 as const, label: 'Hauptsponsoren', note: 'Premium', variant: 'lg' as const, cols: isMobile ? 1 : 2 },
|
||||
{ tier: 2 as const, label: 'Medienpartner', note: '', variant: 'md' as const, cols: isMobile ? 2 : 2 },
|
||||
{ tier: 3 as const, label: 'Weitere Sponsoren', note: '', variant: 'sm' as const, cols: isMobile ? 2 : 4 },
|
||||
]).map(t => {
|
||||
const items = partners.filter(p => p.tier === t.tier);
|
||||
return (
|
||||
<div key={t.tier} style={{ display: 'grid', gridTemplateColumns: `repeat(${t.cols}, 1fr)` }}>
|
||||
{items.map((p, i) => (
|
||||
<SponsorCell key={p.id} partner={p} variant={t.variant} idx={i} cols={t.cols} onClick={() => setSelectedPartner(p)} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 7. SPONSORING-FORM ───────────────────────────────────────────────── */}
|
||||
<section id="sponsoring" style={{
|
||||
background: NAVY, overflow: 'hidden', position: 'relative',
|
||||
minHeight: isMobile ? 'auto' : 'calc(100vh - 60px)',
|
||||
display: 'flex', flexDirection: 'column',
|
||||
}}>
|
||||
<div style={{ flex: 1, position: 'relative', zIndex: 1, display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr', minHeight: 0, overflow: isMobile ? 'visible' : 'visible' }}>
|
||||
{/* Left – pitch */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 24px' : '36px 36px 32px 52px', display: 'flex', flexDirection: 'column', justifyContent: 'center', overflow: 'visible' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: GOLD, display: 'block', marginBottom: 8 }}>Wachstum durch Partnerschaft</span>
|
||||
<h2 style={{ fontFamily: FF, fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', fontSize: 'clamp(1.6rem, 2.4vw, 2.4rem)', lineHeight: 1.0, margin: '0 0 12px' }}>WIR FREUEN UNS ÜBER NEUE SPONSOREN.</h2>
|
||||
<div style={{ width: 36, height: 2, background: GOLD, margin: '0 0 14px', flexShrink: 0 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 'clamp(15px, 1.2vw, 17px)', color: 'rgba(255,255,255,0.75)', lineHeight: 1.65, marginBottom: 16 }}>
|
||||
Positionieren Sie Ihre Marke im exklusivsten Netzwerk des bayerischen Mittelstands – mit maßgeschneiderten Sponsoring-Paketen.
|
||||
</p>
|
||||
{[
|
||||
{ num: '01', label: 'Markenpräsenz', sub: 'Bühne, Drucksachen, digitale Kanäle' },
|
||||
{ num: '02', label: 'Top-Entscheider', sub: 'Exklusives Netzwerk-Dinner für Partner' },
|
||||
{ num: '03', label: 'Multichannel', sub: 'Online, Print, Radio & TV-Partner' },
|
||||
].map((item) => (
|
||||
<div key={item.num} style={{ display: 'grid', gridTemplateColumns: '32px 1fr', gap: '0 12px', padding: '10px 0', borderBottom: '1px solid rgba(255,255,255,0.06)', alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(239,191,4,0.5)' }}>{item.num}</span>
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(14px, 1.05vw, 16px)', fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 2 }}>{item.label}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 'clamp(13px, 1vw, 15px)', color: 'rgba(255,255,255,0.65)', lineHeight: 1.4 }}>{item.sub}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Center divider */}
|
||||
{!isMobile && <div style={{ background: 'rgba(255,255,255,0.07)' }} />}
|
||||
{/* Right – gold form panel */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: 'visible', minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 0 }} aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="sponsoringCross" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
<path d="M0,0 L18,18 M18,0 L0,18" stroke="rgba(17,29,85,0.055)" strokeWidth="0.65" />
|
||||
</pattern>
|
||||
<pattern id="sponsoringDiamond" width="36" height="36" patternUnits="userSpaceOnUse">
|
||||
<polygon points="18,2 34,18 18,34 2,18" fill="none" stroke="rgba(17,29,85,0.045)" strokeWidth="0.6" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#sponsoringCross)" />
|
||||
<rect width="100%" height="100%" fill="url(#sponsoringDiamond)" />
|
||||
</svg>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at center, transparent 55%, rgba(100,70,0,0.25) 100%)', pointerEvents: 'none', zIndex: 0 }} />
|
||||
|
||||
{!isMobile && (
|
||||
<div style={{ height: 220, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
||||
<img src="/images/networking-innenhof.jpg" alt="BMP Partnernetzwerk" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 40%', filter: 'sepia(0.18) brightness(0.92)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 14, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ width: 5, height: 5, borderRadius: '50%', background: 'rgba(17,29,85,0.7)' }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(17,29,85,0.75)', textTransform: 'uppercase', letterSpacing: '0.2em' }}>BMP Partnernetzwerk</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ padding: isMobile ? '28px 20px' : '24px 48px 32px 40px', flex: 1, display: 'flex', flexDirection: 'column', minHeight: isMobile ? 560 : 0, position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, color: 'rgba(17,29,85,0.5)', display: 'block', marginBottom: 8 }}>Sponsoring 2026</span>
|
||||
<SponsoringForm theme="gold" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Footnote */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '16px 20px 20px' : '14px 56px 18px', display: 'flex', flexWrap: 'wrap', justifyContent: 'center', alignItems: 'center', borderTop: '1px solid rgba(255,255,255,0.06)', flexShrink: 0 }}>
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 15, color: 'rgba(255,255,255,0.45)', marginRight: 10 }}>Oder:</span>
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
style={{
|
||||
fontFamily: '"IBM Plex Sans", sans-serif',
|
||||
fontSize: 15,
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
color: 'rgba(239,191,4,0.7)',
|
||||
textDecoration: 'none',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
borderBottom: '1px solid rgba(239,191,4,0.3)',
|
||||
paddingBottom: 1,
|
||||
transition: 'color 0.15s, borderColor 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = '#EFBF04';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = '#EFBF04';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = 'rgba(239,191,4,0.7)';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = 'rgba(239,191,4,0.3)';
|
||||
}}
|
||||
>
|
||||
Vereinsmitglied werden <ChevronRight size={11} />
|
||||
</Link>
|
||||
</div>
|
||||
<div style={{ position: 'relative', zIndex: 1, height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.3), transparent)`, flexShrink: 0 }} />
|
||||
</section>
|
||||
|
||||
|
||||
{/* ── 8. PARTNER MODAL ─────────────────────────────────────────────────── */}
|
||||
{selectedPartner && (
|
||||
<PartnerModal partner={selectedPartner} onClose={() => setSelectedPartner(null)} />
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Netzwerk;
|
||||
608
src/spa/pages/Participation.tsx
Normal file
608
src/spa/pages/Participation.tsx
Normal file
@@ -0,0 +1,608 @@
|
||||
import React, { useRef } from 'react';
|
||||
import { MapPin, Users, TrendingUp, Building2, ArrowRight, CheckCircle2, UserCheck, Send, Star } from 'lucide-react';
|
||||
import { Link } from '@/spa/router';
|
||||
import BewerbungsForm from '@/spa/components/forms/BewerbungsForm';
|
||||
import WegZurAuszeichnungSection from '@/spa/components/WegZurAuszeichnungSection';
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#E4E2E3';
|
||||
|
||||
const Participation: React.FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const qualSectionRef = useRef<HTMLElement>(null);
|
||||
|
||||
return (
|
||||
<div className="animate-fade-in">
|
||||
|
||||
{/* ── HERO ─────────────────────────────────────────────────────────────── */}
|
||||
<section style={{ position: 'relative', minHeight: '65vh', display: 'flex', alignItems: 'flex-end', overflow: 'hidden', background: NAVY }}>
|
||||
<img
|
||||
src="/images/preisuebergabe.jpg"
|
||||
alt="Teilnahme BMP"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: isMobile ? 'linear-gradient(to top, rgba(2,9,48,0.95) 0%, rgba(2,9,48,0.72) 38%, rgba(2,9,48,0.22) 72%, transparent 100%)' : 'linear-gradient(to right, #020930 0%, rgba(2,9,48,0.90) 38%, rgba(2,9,48,0.18) 65%, transparent 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.3), transparent)` }} />
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '0 24px 48px' : '0 80px 80px', maxWidth: 800 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 24 }}>
|
||||
<div style={{ width: 36, height: 2, background: GOLD }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, letterSpacing: '0.28em', textTransform: 'uppercase', color: '#EFBF04' }}>Bewerbungsphase 2026</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.6rem, 6vw, 5rem)' : 'clamp(2.8rem, 6vw, 5rem)', fontWeight: 900, color: '#fff', lineHeight: 0.95, letterSpacing: '-0.03em', textTransform: 'uppercase', margin: '0 0 24px' }}>
|
||||
GESTALTEN SIE<br />BAYERNS ZUKUNFT.
|
||||
</h1>
|
||||
<div style={{ width: 48, height: 2, background: GOLD, marginBottom: 24 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.6)', lineHeight: 1.7, maxWidth: 520, fontWeight: 300 }}>
|
||||
Alles, was Sie für Ihre erfolgreiche Bewerbung zum Bayerischen Mittelstandspreis wissen müssen.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── TIMELINE – direkt nach Hero ──────────────────────────────────────── */}
|
||||
<WegZurAuszeichnungSection />
|
||||
|
||||
{/* ── QUALIFICATIONS ───────────────────────────────────────────────────── */}
|
||||
<section id="voraussetzungen" ref={qualSectionRef} style={{ background: CREAM, overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
|
||||
{/* Header */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '48px 24px 32px' : '80px 80px 56px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 24 : 48, alignItems: 'flex-end', borderBottom: `1px solid #D0D5DD` }}>
|
||||
<div>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Berechtigung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.5vw, 3rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.03, margin: 0 }}>
|
||||
WER KANN<br />TEILNEHMEN?
|
||||
</h2>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: isMobile ? 'flex-start' : 'flex-end', justifyContent: 'space-between', gap: 24 }}>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, flexShrink: 0 }}>
|
||||
<Link
|
||||
to="#bewerben"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '11px 22px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'opacity 0.2s', whiteSpace: 'nowrap' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Jetzt bewerben <ArrowRight size={13} />
|
||||
</Link>
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: NAVY, border: `1.5px solid rgba(3,9,58,0.3)`, padding: '10px 22px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'border-color 0.2s, color 0.2s', whiteSpace: 'nowrap' }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.borderColor = NAVY; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.borderColor = 'rgba(3,9,58,0.3)'; }}
|
||||
>
|
||||
Mitglied werden
|
||||
</Link>
|
||||
</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.8, margin: 0, textAlign: isMobile ? 'left' : 'right' }}>
|
||||
Vier klar definierte Kriterien: Erfüllen Sie alle, bewerben Sie sich kostenlos und ohne bürokratischen Aufwand.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 4 criteria as editorial rows */}
|
||||
<div style={{ position: 'relative', zIndex: 1, borderBottom: `1px solid #D0D5DD` }}>
|
||||
{[
|
||||
{ num: '01', title: 'Standort Bayern', body: 'Sitz oder wesentliche Betriebsstätte im Freistaat Bayern.', Icon: MapPin },
|
||||
{ num: '02', title: 'KMU-Größe', body: '50 bis 1.500 Mitarbeiter: klassischer Mittelstand im privatwirtschaftlichen Bereich.', Icon: Users },
|
||||
{ num: '03', title: 'Marktreife', body: 'Mindestens drei vollständige Geschäftsjahre am Markt tätig.', Icon: TrendingUp },
|
||||
{ num: '04', title: 'Privatwirtschaft', body: 'Keine überwiegende Zugehörigkeit zu staatlichen oder kommunalen Trägern.', Icon: Building2 },
|
||||
].map((item, i, arr) => {
|
||||
const Icon = item.Icon;
|
||||
return (
|
||||
<QualRow key={i} item={item} Icon={Icon} last={i === arr.length - 1} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Zusätzliche Hinweise: Verbund + Wiederbewerber */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '28px 24px' : '40px 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 24 : 48, borderBottom: '1px solid #D0D5DD' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 14 }}>
|
||||
<Building2 size={18} style={{ color: GOLD, flexShrink: 0, marginTop: 3 }} strokeWidth={1.7} />
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 13, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 8 }}>Verbund & Gemeinschaft</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.6)', lineHeight: 1.7, margin: 0 }}>
|
||||
Oder Sie sind ein Verbund bzw. eine Gemeinschaft von mittelständischen Unternehmen oder von mittelständischen Unternehmen und Organisationen/Institutionen, die einen Schwerpunkt in Bayern hat.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', gap: 14 }}>
|
||||
<UserCheck size={18} style={{ color: GOLD, flexShrink: 0, marginTop: 3 }} strokeWidth={1.7} />
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 13, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 8 }}>Erneute Bewerbung</div>
|
||||
<p style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.6)', lineHeight: 1.7, margin: 0 }}>
|
||||
Nominierte ohne Gewinn können sich sofort erneut bewerben. Preisträger können sich nach 7 Jahren erneut bewerben.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CTA nudge */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '24px 24px' : '32px 80px', display: 'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'flex-start' : 'center', justifyContent: 'space-between', gap: 24 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<CheckCircle2 size={18} style={{ color: GOLD, flexShrink: 0 }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 18, fontWeight: 600, color: '#101828' }}>Alle 4 Punkte erfüllt? Dann jetzt kostenlos bewerben.</span>
|
||||
</div>
|
||||
<Link
|
||||
to="#bewerben"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '13px 28px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'opacity 0.2s', whiteSpace: 'nowrap' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Zum Formular <ArrowRight size={13} />
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── CRITERIA / BEWERTUNG ─────────────────────────────────────────────── */}
|
||||
<section id="kriterien" style={{ background: NAVY, overflow: 'hidden', position: 'relative' }}>
|
||||
|
||||
{/* TOP: editorial split – image left (45%) / header right (55%) */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '45% 55%', minHeight: isMobile ? 'auto' : 480 }}>
|
||||
|
||||
{/* Left – full-bleed image with gradient blend into navy on the right (+ heading on mobile) */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', minHeight: isMobile ? 280 : undefined }}>
|
||||
<img
|
||||
src="/images/buehne-gewinner.jpg"
|
||||
alt="Jury-Bewertung BMP"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center', display: 'block' }}
|
||||
/>
|
||||
{/* Dark overlay for depth */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(3,9,58,0.35) 0%, rgba(3,9,58,0.15) 50%, rgba(3,9,58,0.35) 100%)' }} />
|
||||
{/* Right-side blend into navy (desktop) */}
|
||||
{!isMobile && <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to right, transparent 50%, rgba(3,9,58,0.7) 80%, #111D55 100%)' }} />}
|
||||
{/* Mobile heading shadow (bottom-left) */}
|
||||
{isMobile && <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(3,9,58,0.94) 0%, rgba(3,9,58,0.55) 38%, rgba(3,9,58,0.12) 72%, transparent 100%), linear-gradient(to right, rgba(3,9,58,0.5) 0%, transparent 55%)' }} />}
|
||||
{/* Bottom blend for continuity with grid below */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 120, background: 'linear-gradient(to bottom, transparent, #111D55)' }} />
|
||||
{/* Heading overlay – mobile only */}
|
||||
{isMobile && (
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, padding: '0 24px 24px', zIndex: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 12 }}>Bewertung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 9vw, 2.8rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 0.97, margin: 0, textShadow: '0 2px 18px rgba(3,9,58,0.6)' }}>
|
||||
UNSERE<br />KRITERIEN.
|
||||
</h2>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right – overline + headline + intro */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 40px' : '80px 80px 72px 64px', display: 'flex', flexDirection: 'column', justifyContent: 'center', borderBottom: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
{!isMobile && (
|
||||
<>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 20 }}>Bewertung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2.4rem, 4vw, 3.6rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.03em', lineHeight: 0.97, margin: '0 0 28px' }}>
|
||||
UNSERE<br />KRITERIEN.
|
||||
</h2>
|
||||
</>
|
||||
)}
|
||||
<div style={{ width: 40, height: 2, background: GOLD, marginBottom: 28 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 19, color: 'rgba(255,255,255,0.68)', lineHeight: 1.8, margin: 0, maxWidth: 420 }}>
|
||||
Vier zentrale Säulen, bewertet durch eine vollständig unabhängige Expertenjury aus Wirtschaft, Wissenschaft und Gesellschaft.
|
||||
<br />
|
||||
<br />
|
||||
Die Kriterien werden nicht gleich gewichtet.
|
||||
</p>
|
||||
<a
|
||||
href="https://www.der-bayerische-mittelstandspreis.de/der-preis/kriterien/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: GOLD, textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 28, borderBottom: `1px solid rgba(239,191,4,0.4)`, paddingBottom: 2, alignSelf: 'flex-start' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.8')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Kriterien & Bewertung <ArrowRight size={13} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* BOTTOM: full-width 4-column criteria grid */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(4, 1fr)', borderTop: '1px solid rgba(255,255,255,0.07)', position: 'relative' }}>
|
||||
{[
|
||||
{ title: 'Innovations\u00ADkraft', desc: 'Zukunftsweisende Produkte, Dienstleistungen oder interne Prozessinnovationen.' },
|
||||
{ title: 'Nachhaltigkeit', desc: 'Ökologische Verantwortung und Ressourcen-Effizienz im operativen Kern.' },
|
||||
{ title: 'Unternehmens\u00ADkultur', desc: 'Mitarbeiterbindung, Aus- und Weiterbildung sowie wertebasierte Führung.' },
|
||||
{ title: 'Regionale Wurzeln', desc: 'Engagement am Standort Bayern und Beitrag zur regionalen Wertschöpfung.' },
|
||||
].map((crit, i) => (
|
||||
<CriteriaCell key={i} crit={crit} idx={i} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div style={{ height: 2, background: `linear-gradient(to right, ${GOLD}, rgba(239,191,4,0.2), transparent)` }} />
|
||||
</section>
|
||||
|
||||
{/* ── BEWERBUNGSWEGE ───────────────────────────────────────────────────── */}
|
||||
<BewerbungswegeSection />
|
||||
|
||||
{/* ── DATES BANNER ─────────────────────────────────────────────────────── */}
|
||||
<section id="fristen" style={{ background: GOLD }}>
|
||||
{isMobile ? (
|
||||
/* Mobile: slim horizontal bar */
|
||||
<div style={{ padding: '24px 22px 26px' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.2em', marginBottom: 18 }}>Wichtige Termine 2026</div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{[
|
||||
{ date: '30. Juni 2026', label: 'Bewerbungsschluss' },
|
||||
{ date: 'August 2026', label: 'Nominierte' },
|
||||
{ date: 'Oktober 2026', label: 'Gala-Verleihung' },
|
||||
].map((d, i) => (
|
||||
<div key={i} style={{ flex: 1, minWidth: 0, paddingLeft: i > 0 ? 14 : 0, borderLeft: i > 0 ? '1px solid rgba(3,9,58,0.2)' : 'none' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 900, color: '#101828', letterSpacing: '-0.02em', lineHeight: 1.12, marginBottom: 6 }}>{d.date}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 9.5, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'rgba(16,24,40,0.55)', lineHeight: 1.25 }}>{d.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
/* Desktop: full banner */
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1px 1fr 1px 1fr 1px 1fr', maxWidth: 1200, margin: '0 auto' }}>
|
||||
<div style={{ padding: '48px 56px' }}>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 18, fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', marginBottom: 6 }}>Wichtige Termine 2026</h3>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.6)', margin: 0 }}>Planen Sie Ihre Teilnahme rechtzeitig.</p>
|
||||
</div>
|
||||
<div style={{ background: 'rgba(3,9,58,0.12)' }} />
|
||||
{[
|
||||
{ date: '30. Juni 2026', label: 'Bewerbungsschluss' },
|
||||
{ date: 'August 2026', label: 'Bekanntgabe Nominierte' },
|
||||
{ date: 'Oktober 2026', label: 'Gala-Verleihung' },
|
||||
].map((d, i) => (
|
||||
<React.Fragment key={i}>
|
||||
<div style={{ padding: '48px 40px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 'clamp(1.1rem, 1.8vw, 1.4rem)', fontWeight: 900, color: '#101828', letterSpacing: '-0.02em', marginBottom: 6 }}>{d.date}</div>
|
||||
<div style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'rgba(16,24,40,0.55)' }}>{d.label}</div>
|
||||
</div>
|
||||
{i < 2 && <div style={{ background: 'rgba(3,9,58,0.12)' }} />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
{/* ── FORM SECTION ─────────────────────────────────────────────────────── */}
|
||||
<section style={{ background: NAVY, position: 'relative', overflow: 'hidden', height: isMobile ? 'auto' : 'calc(100vh - 60px)', display: 'flex', flexDirection: 'column' }} id="bewerben">
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '4fr 1px 8fr', flex: 1, minHeight: 0, overflow: isMobile ? 'visible' : 'hidden' }}>
|
||||
{/* Left – copy */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 24px' : '36px 36px 32px 52px', display: 'flex', flexDirection: 'column', justifyContent: 'center', overflow: isMobile ? 'visible' : 'hidden' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#EFBF04', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 20 }}>Direktbewerbung</span>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.2vw, 2.8rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 20px' }}>
|
||||
BEWERBEN ODER<br />VORSCHLAGEN.
|
||||
</h2>
|
||||
<div style={{ width: 36, height: 2, background: GOLD, marginBottom: 28 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.68)', lineHeight: 1.8, maxWidth: 400, marginBottom: 48 }}>
|
||||
Sie können sich selbst bewerben oder ein herausragendes Unternehmen vorschlagen. Firmenverbunde können sich ebenfalls bewerben. Die Teilnahme ist vollständig kostenfrei.
|
||||
</p>
|
||||
<div style={{ borderTop: '1px solid rgba(255,255,255,0.08)' }}>
|
||||
{[
|
||||
{ num: '01', label: '0 EUR', desc: 'Teilnahmegebühr' },
|
||||
{ num: '02', label: 'Schnell', desc: 'Ca. 30–45 Minuten' },
|
||||
{ num: '03', label: 'Mehrstufig', desc: 'Transparenter Prozess' },
|
||||
].map((item, i) => (
|
||||
<div key={i} style={{ display: 'grid', gridTemplateColumns: '36px 1fr', gap: '0 16px', padding: '16px 0', borderBottom: '1px solid rgba(255,255,255,0.06)', alignItems: 'center' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(239,191,4,0.5)', letterSpacing: '0.1em' }}>{item.num}</span>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.08em' }}>{item.label}</span>
|
||||
<span style={{ fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.62)' }}>{item.desc}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
{!isMobile && <div style={{ background: 'rgba(255,255,255,0.07)' }} />}
|
||||
|
||||
{/* Right – gold form panel */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', overflow: isMobile ? 'visible' : 'hidden', minHeight: 0, position: 'relative', background: 'linear-gradient(160deg,#DDB84A 0%,#C9A227 52%,#A87800 100%)' }}>
|
||||
<svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 0 }} aria-hidden="true">
|
||||
<defs>
|
||||
<pattern id="participationCross" width="18" height="18" patternUnits="userSpaceOnUse">
|
||||
<path d="M0,0 L18,18 M18,0 L0,18" stroke="rgba(17,29,85,0.055)" strokeWidth="0.65" />
|
||||
</pattern>
|
||||
<pattern id="participationDiamond" width="36" height="36" patternUnits="userSpaceOnUse">
|
||||
<polygon points="18,2 34,18 18,34 2,18" fill="none" stroke="rgba(17,29,85,0.045)" strokeWidth="0.6" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#participationCross)" />
|
||||
<rect width="100%" height="100%" fill="url(#participationDiamond)" />
|
||||
</svg>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse at center, transparent 55%, rgba(100,70,0,0.25) 100%)', pointerEvents: 'none', zIndex: 0 }} />
|
||||
|
||||
{!isMobile && (
|
||||
<div style={{ height: 220, position: 'relative', overflow: 'hidden', flexShrink: 0, zIndex: 1 }}>
|
||||
<img src="/images/preistraeger-jubel.jpg" alt="Preisverleihung 2025" style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%', filter: 'sepia(0.18) brightness(0.92)' }} />
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, rgba(168,120,0,0.1) 0%, rgba(168,120,0,0.25) 50%, rgba(168,120,0,0.92) 88%, #A87800 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'rgba(17,29,85,0.35)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 16, left: 40, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ width: 5, height: 5, borderRadius: '50%', background: 'rgba(17,29,85,0.7)' }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(17,29,85,0.75)', textTransform: 'uppercase', letterSpacing: '0.2em' }}>Preisverleihung 2025</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ padding: isMobile ? '28px 20px' : '24px 48px 32px 40px', flex: 1, display: 'flex', flexDirection: 'column', minHeight: isMobile ? 560 : 0, position: 'relative', zIndex: 1 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, marginBottom: 24 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: 'rgba(17,29,85,0.5)', textTransform: 'uppercase', letterSpacing: '0.28em', fontWeight: 700 }}>Bewerbung 2026</span>
|
||||
<Link
|
||||
to="/formular-hochladen"
|
||||
style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'rgba(17,29,85,0.55)', border: '1px solid rgba(17,29,85,0.2)', padding: '7px 14px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 6, transition: 'color 0.15s, border-color 0.15s', whiteSpace: 'nowrap', flexShrink: 0 }}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = '#111D55'; (e.currentTarget as HTMLElement).style.borderColor = '#111D55'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = 'rgba(17,29,85,0.55)'; (e.currentTarget as HTMLElement).style.borderColor = 'rgba(17,29,85,0.2)'; }}
|
||||
>
|
||||
<svg width="10" height="10" viewBox="0 0 12 12" fill="none"><path d="M6 1v7M3 4l3-3 3 3M1 10h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||
PDF hochladen
|
||||
</Link>
|
||||
</div>
|
||||
<BewerbungsForm theme="gold" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '16px 20px 20px' : '14px 56px 18px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, justifyContent: 'center', textAlign: 'center', borderTop: '1px solid rgba(255,255,255,0.06)', flexShrink: 0 }}>
|
||||
<span style={{ fontFamily: FB, fontSize: 14, color: 'rgba(255,255,255,0.55)', lineHeight: 1.6, maxWidth: 520 }}>
|
||||
Sie haben Ihre Unterlagen bereits als PDF vorbereitet? Laden Sie sie direkt hoch, statt das Formular auszufüllen.
|
||||
</span>
|
||||
<Link to="/formular-hochladen" style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'rgba(239,191,4,0.7)', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 6, borderBottom: '1px solid rgba(239,191,4,0.3)', paddingBottom: 1 }}>
|
||||
Formular hochladen →
|
||||
</Link>
|
||||
</div>
|
||||
<div style={{ height: 2, background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.25), transparent)', flexShrink: 0 }} />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// ── QualRow ───────────────────────────────────────────────────────────────────
|
||||
|
||||
function QualRow({ item, Icon, last }: { item: { num: string; title: string; body: string }; Icon: React.ElementType; last: boolean }) {
|
||||
const [hovered, setHovered] = React.useState(false);
|
||||
const isMobileRow = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
style={{ display: 'grid', gridTemplateColumns: isMobileRow ? '40px 1fr' : '80px 200px 1fr 48px', gap: isMobileRow ? '0 16px' : '0 32px', padding: isMobileRow ? '24px 24px' : '28px 80px', borderBottom: last ? 'none' : '1px solid #D0D5DD', alignItems: isMobileRow ? 'flex-start' : 'center', background: hovered ? '#EAE7E6' : 'transparent', transition: 'background 0.15s', cursor: 'default' }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<span style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, color: hovered ? GOLD : 'rgba(239,191,4,0.5)', letterSpacing: '0.1em', transition: 'color 0.2s', paddingTop: 2 }}>{item.num}</span>
|
||||
{isMobileRow ? (
|
||||
<div>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.07em', marginBottom: 4 }}>{item.title}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.5)', lineHeight: 1.6 }}>{item.body}</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.07em' }}>{item.title}</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.5)', lineHeight: 1.6 }}>{item.body}</div>
|
||||
<div style={{ width: 36, height: 36, background: hovered ? GOLD : 'rgba(3,9,58,0.06)', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background 0.2s' }}>
|
||||
<Icon size={16} style={{ color: hovered ? '#101828' : 'rgba(16,24,40,0.3)', transition: 'color 0.2s' }} strokeWidth={1.5} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── CriteriaCell ──────────────────────────────────────────────────────────────
|
||||
|
||||
function CriteriaCell({ crit, idx }: { crit: { title: string; desc: string }; idx: number }) {
|
||||
const [hovered, setHovered] = React.useState(false);
|
||||
const isMobileCell = useIsMobile();
|
||||
return (
|
||||
<div
|
||||
style={{ padding: isMobileCell ? '32px 24px' : '56px 40px', borderLeft: !isMobileCell && idx > 0 ? '1px solid rgba(255,255,255,0.07)' : 'none', borderTop: isMobileCell && idx > 0 ? '1px solid rgba(255,255,255,0.07)' : 'none', display: 'flex', flexDirection: 'column', gap: 0, cursor: 'default', transition: 'background 0.2s', background: hovered ? 'rgba(255,255,255,0.03)' : 'transparent' }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 24 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, fontWeight: 700, color: 'rgba(255,255,255,0.50)', letterSpacing: '0.15em', textTransform: 'uppercase' }}>0{idx + 1}</span>
|
||||
</div>
|
||||
<div style={{ width: hovered ? '100%' : 28, height: 1, background: hovered ? 'rgba(239,191,4,0.6)' : 'rgba(239,191,4,0.3)', marginBottom: 20, transition: 'width 0.5s ease' }} />
|
||||
<h4 style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.08em', lineHeight: 1.3, marginBottom: 14 }}>{crit.title}</h4>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.65)', lineHeight: 1.7, flex: 1 }}>{crit.desc}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── BewerbungswegeSection ─────────────────────────────────────────────────────
|
||||
|
||||
const INSTITUTIONEN = [
|
||||
'Senatoren und Mitglieder der Verbandsgruppe „Wir Eigentümerunternehmer"',
|
||||
'Bundesverband Deutscher Mittelstand (BM)',
|
||||
'Europäisches Wirtschaftsforum (EWIF)',
|
||||
'Union Mittelständischer Unternehmen (UMU)',
|
||||
'HAM – Hochschule für angewandtes Management und deren Regionalpartner',
|
||||
'Mitglieder des Wirtschaftsbeirates Bayern',
|
||||
'Ehemalige Preisträger des Bayerischen Mittelstandspreises',
|
||||
];
|
||||
|
||||
function BewerbungswegeSection() {
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<section style={{ background: CREAM, position: 'relative', overflow: 'hidden', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
|
||||
{/* Header */}
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '48px 24px 32px' : '80px 80px 56px', borderBottom: '1px solid #D0D5DD' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.32em', fontWeight: 700, display: 'block', marginBottom: 16 }}>Bewerbung 2026</span>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', gap: isMobile ? 16 : 48, alignItems: 'flex-end' }}>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(2rem, 3.5vw, 3rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.03, margin: 0 }}>
|
||||
HIER KÖNNEN SIE SICH<br />BEWERBEN ODER EIN<br />UNTERNEHMEN VORSCHLAGEN.
|
||||
</h2>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.55)', lineHeight: 1.8, margin: 0 }}>
|
||||
Als Unternehmen haben Sie zwei Möglichkeiten: Sie werden von einem unterstützenden Partner oder einer Institution vorgeschlagen, oder Sie ergreifen selbst die Initiative und füllen unsere Anmeldung aus. Die Teilnahme ist in allen Fällen kostenfrei.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3 Wege – premium swipe cards on mobile, 3-col grid on desktop */}
|
||||
<div style={{ position: 'relative', zIndex: 1, display: isMobile ? 'flex' : 'grid', gridTemplateColumns: isMobile ? undefined : 'repeat(3, 1fr)', overflowX: isMobile ? 'auto' : undefined, scrollSnapType: isMobile ? 'x mandatory' : undefined, WebkitOverflowScrolling: 'touch', scrollbarWidth: 'none', gap: isMobile ? 14 : 0, padding: isMobile ? '28px 24px 36px' : 0 }}>
|
||||
|
||||
{/* ── MOBILE: unified premium cards ── */}
|
||||
{isMobile && ([
|
||||
{ weg: 'Weg 01', title: 'Vorschlag unterbreiten', desc: 'Durch ehemalige Preisträger, die HAM, Senatoren und den Preis unterstützende Institutionen.', Icon: Send, checkItems: INSTITUTIONEN, cta: 'Vorschlag unterbreiten', featured: false },
|
||||
{ weg: 'Weg 02', title: 'Initiativbewerbung', desc: 'Für Unternehmer, die selbst die Initiative ergreifen.', Icon: UserCheck, kvItems: [ { k: '0 EUR', v: 'Teilnahmegebühr' }, { k: 'Eigeninitiative', v: 'Direkt ohne Intermediär' }, { k: 'Für Unternehmer', v: 'Inhabergeführte KMU in Bayern' }, { k: 'Deadline', v: '30. Juni 2026' } ], cta: 'Jetzt bewerben', featured: true },
|
||||
{ weg: 'Weg 03 · Sonderpreis', title: 'Bavarian Future Award', desc: 'Sonderpreis, initiiert durch die Studierenden der HAM, Hochschule für angewandtes Management.', Icon: Star, kvItems: [ { k: 'Vorschlag möglich', v: 'Durch HAM & Partner' }, { k: 'Selbstbewerbung', v: 'Direkte Einreichung' }, { k: 'Initiiert von', v: 'Studierenden der HAM' }, { k: 'Kategorie', v: 'Zukunft & Innovation' } ], cta: 'Zum Formular', featured: false },
|
||||
] as { weg: string; title: string; desc: string; Icon: any; checkItems?: string[]; kvItems?: { k: string; v: string }[]; cta: string; featured: boolean }[]).map((w) => {
|
||||
const Icon = w.Icon;
|
||||
return (
|
||||
<div key={w.weg} style={{ flexShrink: 0, minWidth: '85vw', maxWidth: '85vw', scrollSnapAlign: 'center', display: 'flex', flexDirection: 'column', background: '#fff', borderRadius: 18, overflow: 'hidden', border: w.featured ? `1.5px solid ${GOLD}` : '1px solid rgba(17,29,85,0.10)', boxShadow: w.featured ? '0 14px 34px rgba(239,191,4,0.20), 0 6px 16px rgba(3,9,58,0.10)' : '0 10px 28px rgba(3,9,58,0.08)' }}>
|
||||
{/* Header */}
|
||||
<div style={{ padding: '22px 22px 0', position: 'relative' }}>
|
||||
{w.featured && (
|
||||
<span style={{ position: 'absolute', top: 22, right: 22, fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '5px 10px', borderRadius: 100 }}>Empfohlen</span>
|
||||
)}
|
||||
<div style={{ width: 46, height: 46, borderRadius: 12, background: w.featured ? GOLD : NAVY, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 18 }}>
|
||||
<Icon size={20} style={{ color: w.featured ? '#101828' : GOLD }} strokeWidth={1.6} />
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.28em', textTransform: 'uppercase', color: w.featured ? '#A87800' : 'rgba(16,24,40,0.4)', display: 'block', marginBottom: 8 }}>{w.weg}</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: '1.45rem', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.08, margin: '0 0 10px' }}>{w.title}</h3>
|
||||
<p style={{ fontFamily: FB, fontSize: 16, color: 'rgba(16,24,40,0.55)', lineHeight: 1.6, margin: '0 0 20px' }}>{w.desc}</p>
|
||||
<div style={{ width: 36, height: 2, background: GOLD }} />
|
||||
</div>
|
||||
{/* Detail list */}
|
||||
<div style={{ padding: '4px 22px 0', flex: 1 }}>
|
||||
{w.checkItems && w.checkItems.map((inst, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '12px 0', borderBottom: '1px solid rgba(17,29,85,0.08)' }}>
|
||||
<div style={{ width: 18, height: 18, borderRadius: 5, background: GOLD, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 1 }}>
|
||||
<svg width="9" height="9" viewBox="0 0 8 8"><polyline points="1,4 3,6 7,2" stroke="#101828" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||
</div>
|
||||
<span style={{ fontFamily: FB, fontSize: 16, color: 'rgba(16,24,40,0.7)', lineHeight: 1.5 }}>{inst}</span>
|
||||
</div>
|
||||
))}
|
||||
{w.kvItems && w.kvItems.map((item, i) => (
|
||||
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 12, padding: '13px 0', borderBottom: '1px solid rgba(17,29,85,0.08)' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 14, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.06em', flexShrink: 0 }}>{item.k}</span>
|
||||
<span style={{ fontFamily: FB, fontSize: 15, color: 'rgba(16,24,40,0.5)', textAlign: 'right' }}>{item.v}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* CTA */}
|
||||
<div style={{ padding: '18px 22px 22px' }}>
|
||||
<a href="#bewerben" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, minHeight: 52, background: GOLD, color: '#101828', fontFamily: FF, fontSize: 14, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', textDecoration: 'none', borderRadius: 10 }}>{w.cta} <ArrowRight size={14} /></a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* ── DESKTOP: original 3 columns ── */}
|
||||
{!isMobile && (<>
|
||||
|
||||
{/* ── Weg A: Vorschlag ── */}
|
||||
<div style={{ padding: isMobile ? '32px 24px' : '56px 48px 56px', borderRight: '1px solid #D0D5DD', display: 'flex', flexDirection: 'column', ...(isMobile ? { minWidth: '83vw', maxWidth: '83vw', flexShrink: 0, scrollSnapAlign: 'start' } : {}) }}>
|
||||
<div style={{ width: 44, height: 44, background: NAVY, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 28 }}>
|
||||
<Send size={18} style={{ color: GOLD }} strokeWidth={1.5} />
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: 'rgba(16,24,40,0.4)', display: 'block', marginBottom: 10 }}>Weg 01</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.3rem, 2vw, 1.7rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, margin: '0 0 8px' }}>
|
||||
Vorschlag<br />unterbreiten
|
||||
</h3>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.7, margin: '0 0 32px' }}>
|
||||
Durch ehemalige Preisträger, die HAM, Senatoren und den Preis unterstützende Institutionen.
|
||||
</p>
|
||||
|
||||
{/* Institution list */}
|
||||
<div style={{ borderTop: '1px solid #D0D5DD', flex: 1 }}>
|
||||
{INSTITUTIONEN.map((inst, i) => (
|
||||
<div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '12px 0', borderBottom: '1px solid #D0D5DD' }}>
|
||||
<div style={{ width: 16, height: 16, background: GOLD, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2 }}>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8"><polyline points="1,4 3,6 7,2" stroke="#101828" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>
|
||||
</div>
|
||||
<span style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.65)', lineHeight: 1.55 }}>{inst}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#bewerben"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 24px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 36, alignSelf: 'flex-start', transition: 'opacity 0.15s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Vorschlag unterbreiten <ArrowRight size={13} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* ── Weg B: Initiativbewerbung ── */}
|
||||
<div style={{ padding: isMobile ? '32px 24px' : '56px 48px 56px', borderRight: '1px solid #D0D5DD', display: 'flex', flexDirection: 'column', background: NAVY, ...(isMobile ? { minWidth: '83vw', maxWidth: '83vw', flexShrink: 0, scrollSnapAlign: 'start' } : {}) }}>
|
||||
<div style={{ width: 44, height: 44, background: GOLD, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 28 }}>
|
||||
<UserCheck size={18} style={{ color: '#101828' }} strokeWidth={1.5} />
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.35)', display: 'block', marginBottom: 10 }}>Weg 02</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.3rem, 2vw, 1.7rem)', fontWeight: 900, color: '#fff', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, margin: '0 0 8px' }}>
|
||||
Initiativbewerbung
|
||||
</h3>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(255,255,255,0.62)', lineHeight: 1.7, margin: '0 0 32px' }}>
|
||||
Für Unternehmer, die selbst die Initiative ergreifen.
|
||||
</p>
|
||||
|
||||
<div style={{ borderTop: '1px solid rgba(255,255,255,0.1)', flex: 1 }}>
|
||||
{[
|
||||
{ label: '0 EUR', desc: 'Teilnahmegebühr' },
|
||||
{ label: 'Eigeninitiative', desc: 'Direkt ohne Intermediär' },
|
||||
{ label: 'Für Unternehmer', desc: 'Inhabergeführte KMU in Bayern' },
|
||||
{ label: 'Deadline', desc: '30. Juni 2026' },
|
||||
].map((item, i) => (
|
||||
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '14px 0', borderBottom: '1px solid rgba(255,255,255,0.07)' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#fff', textTransform: 'uppercase', letterSpacing: '0.07em' }}>{item.label}</span>
|
||||
<span style={{ fontFamily: FB, fontSize: 16, color: 'rgba(255,255,255,0.50)' }}>{item.desc}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#bewerben"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 24px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 36, alignSelf: 'flex-start', transition: 'opacity 0.15s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Jetzt bewerben <ArrowRight size={13} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* ── Weg C: Sonderpreis ── */}
|
||||
<div style={{ padding: isMobile ? '32px 24px' : '56px 48px 56px', display: 'flex', flexDirection: 'column', ...(isMobile ? { minWidth: '83vw', maxWidth: '83vw', flexShrink: 0, scrollSnapAlign: 'start' } : {}) }}>
|
||||
<div style={{ width: 44, height: 44, background: NAVY, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 28 }}>
|
||||
<Star size={18} style={{ color: GOLD }} strokeWidth={1.5} />
|
||||
</div>
|
||||
<span style={{ fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase', color: 'rgba(16,24,40,0.4)', display: 'block', marginBottom: 10 }}>Weg 03 · Sonderpreis</span>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.3rem, 2vw, 1.7rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', lineHeight: 1.1, margin: '0 0 8px' }}>
|
||||
Bavarian<br />Future Award
|
||||
</h3>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.7, margin: '0 0 32px' }}>
|
||||
Sonderpreis, initiiert durch die Studierenden der HAM, Hochschule für angewandtes Management.
|
||||
</p>
|
||||
|
||||
<div style={{ borderTop: '1px solid #D0D5DD', flex: 1 }}>
|
||||
{[
|
||||
{ label: 'Vorschlag möglich', desc: 'Durch HAM & Partner' },
|
||||
{ label: 'Selbstbewerbung', desc: 'Direkte Einreichung' },
|
||||
{ label: 'Initiiert von', desc: 'Studierenden der HAM' },
|
||||
{ label: 'Kategorie', desc: 'Zukunft & Innovation' },
|
||||
].map((item, i) => (
|
||||
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', padding: '14px 0', borderBottom: '1px solid #D0D5DD' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.07em' }}>{item.label}</span>
|
||||
<span style={{ fontFamily: FB, fontSize: 16, color: 'rgba(16,24,40,0.45)' }}>{item.desc}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="#bewerben"
|
||||
style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#101828', background: GOLD, padding: '14px 24px', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, marginTop: 36, alignSelf: 'flex-start', transition: 'opacity 0.15s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.opacity = '0.85')}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.opacity = '1')}
|
||||
>
|
||||
Zum Formular <ArrowRight size={13} />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</>)}
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Participation;
|
||||
324
src/spa/pages/Preistraeger.tsx
Normal file
324
src/spa/pages/Preistraeger.tsx
Normal file
@@ -0,0 +1,324 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { Trophy, Search, ChevronDown, ChevronRight, X, ArrowRight } from 'lucide-react';
|
||||
import { WINNERS, CATEGORIES, YEARS } from '@/spa/data/winners';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const BORDER = '#D0D5DD';
|
||||
const GRAY = '#666666';
|
||||
const BG_ALT = '#E4E2E3';
|
||||
|
||||
export default function Preistraeger() {
|
||||
const isMobile = useIsMobile();
|
||||
const [activeYear, setActiveYear] = useState(YEARS[0]); // default: most recent
|
||||
const [filterCategory, setFilterCategory] = useState('');
|
||||
const [search, setSearch] = useState('');
|
||||
const [mediaOnly, setMediaOnly] = useState(false);
|
||||
|
||||
const filtered = useMemo(() => WINNERS.filter(w => {
|
||||
if (w.year !== activeYear) return false;
|
||||
if (filterCategory && w.category !== filterCategory) return false;
|
||||
if (search && !w.name.toLowerCase().includes(search.toLowerCase())) return false;
|
||||
if (mediaOnly && !w.hasMedia) return false;
|
||||
return true;
|
||||
}), [activeYear, filterCategory, search, mediaOnly]);
|
||||
|
||||
const reset = () => { setFilterCategory(''); setSearch(''); setMediaOnly(false); };
|
||||
const hasFilter = !!(filterCategory || search || mediaOnly);
|
||||
|
||||
return (
|
||||
<div style={{ background: '#fff', minHeight: '100vh' }}>
|
||||
{/* Hero */}
|
||||
<div style={{ width: '100%', height: '50vh', overflow: 'hidden', position: 'relative' }}>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1492684223066-81342ee5ff30?auto=format&fit=crop&q=80&w=2000"
|
||||
alt="Preisverleihung"
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, transparent 40%, rgba(3,9,58,0.82) 100%)' }} />
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 2, background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.3), transparent)' }} />
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb */}
|
||||
<div style={{ background: '#fff', borderBottom: `1px solid ${BORDER}`, padding: isMobile ? '18px 24px' : '18px 80px' }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 16, color: GOLD, fontWeight: 600, letterSpacing: '0.04em' }}>Preisträger:innen</span>
|
||||
</div>
|
||||
|
||||
{/* Filter Section */}
|
||||
<div style={{ background: '#fff', padding: isMobile ? '32px 24px 24px' : '48px 80px 32px' }}>
|
||||
{/* #93: Headline entfernt – Seitenname steht bereits oben im Breadcrumb. */}
|
||||
|
||||
{/* Year Tabs */}
|
||||
<div style={{ display: 'flex', flexWrap: isMobile ? 'nowrap' : 'wrap', gap: 0, marginBottom: 32, borderBottom: `2px solid ${BORDER}`, overflowX: isMobile ? 'auto' : 'visible', WebkitOverflowScrolling: 'touch', maxWidth: '100%' }}>
|
||||
{YEARS.map(year => (
|
||||
<button
|
||||
key={year}
|
||||
onClick={() => { setActiveYear(year); reset(); }}
|
||||
style={{
|
||||
fontFamily: FF, fontSize: 16, fontWeight: 700,
|
||||
padding: isMobile ? '12px 20px' : '12px 32px',
|
||||
flexShrink: 0,
|
||||
background: 'none', border: 'none', cursor: 'pointer',
|
||||
color: activeYear === year ? NAVY : GRAY,
|
||||
borderBottom: activeYear === year ? `2px solid ${GOLD}` : '2px solid transparent',
|
||||
marginBottom: -2,
|
||||
letterSpacing: '0.04em',
|
||||
transition: 'color 0.15s, border-color 0.15s',
|
||||
}}
|
||||
>
|
||||
{year}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Filter Row */}
|
||||
<div style={{ display: 'flex', flexDirection: isMobile ? 'column' : 'row', gap: 16, alignItems: 'stretch', marginBottom: 20, flexWrap: 'wrap' }}>
|
||||
<SelectControl
|
||||
value={filterCategory}
|
||||
onChange={setFilterCategory}
|
||||
placeholder="Preiskategorie …"
|
||||
options={CATEGORIES.map(c => ({ label: c, value: c }))}
|
||||
width={isMobile ? undefined : 280}
|
||||
/>
|
||||
<SearchControl value={search} onChange={setSearch} />
|
||||
</div>
|
||||
|
||||
{/* Toggle row */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: '#101828' }}>
|
||||
Diese Erfolgsgeschichten müssen erzählt werden.
|
||||
</span>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<span style={{ fontSize: 15 }}>💬</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, color: GRAY }}>Mit Medienbeiträgen (Videos & Storys)</span>
|
||||
<button
|
||||
onClick={() => setMediaOnly(v => !v)}
|
||||
style={{
|
||||
width: 40, height: 22, borderRadius: 11, border: 'none', cursor: 'pointer',
|
||||
background: mediaOnly ? NAVY : BORDER,
|
||||
position: 'relative', transition: 'background 0.2s',
|
||||
}}
|
||||
>
|
||||
<span style={{
|
||||
position: 'absolute', top: 3, left: mediaOnly ? 20 : 3, width: 16, height: 16,
|
||||
borderRadius: '50%', background: '#fff', transition: 'left 0.2s',
|
||||
}} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{hasFilter && (
|
||||
<button
|
||||
onClick={reset}
|
||||
style={{ fontFamily: FF, fontSize: 16, color: GRAY, background: 'none', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6 }}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = GOLD)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = GRAY)}
|
||||
>
|
||||
<X size={14} /> Filter zurücksetzen
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Count bar */}
|
||||
<div style={{ padding: isMobile ? '12px 24px' : '12px 80px', background: BG_ALT, borderTop: `1px solid ${BORDER}`, borderBottom: `1px solid ${BORDER}`, display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<Trophy size={13} style={{ color: GOLD }} fill={GOLD} />
|
||||
<span style={{ fontFamily: FF, fontSize: 15, color: GRAY }}>
|
||||
<strong style={{ color: '#101828' }}>{activeYear}</strong> – {filtered.length} Preisträger:innen
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Grid */}
|
||||
{filtered.length === 0 ? (
|
||||
<div style={{ padding: isMobile ? '56px 24px' : '80px', textAlign: 'center', color: GRAY, fontFamily: FF }}>
|
||||
Keine Preisträger für diese Auswahl.
|
||||
</div>
|
||||
) : (
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? undefined : 'repeat(4, 1fr)',
|
||||
gridAutoFlow: isMobile ? 'column' : undefined,
|
||||
gridTemplateRows: isMobile ? 'repeat(2, 1fr)' : undefined,
|
||||
gridAutoColumns: isMobile ? '74vw' : undefined,
|
||||
overflowX: isMobile ? 'auto' : undefined,
|
||||
scrollSnapType: isMobile ? 'x mandatory' : undefined,
|
||||
gap: isMobile ? 8 : 0,
|
||||
padding: isMobile ? '0 16px 8px' : 0,
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
scrollbarWidth: 'none',
|
||||
}}>
|
||||
{filtered.map(w => (
|
||||
<WinnerCard key={w.id} winner={w} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Bottom CTA */}
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '64px 80px', borderTop: `1px solid ${BORDER}`, textAlign: 'center' }}>
|
||||
<p style={{ fontFamily: FF, fontSize: 17, color: GRAY, marginBottom: 20 }}>Werden Sie der nächste Preisträger.</p>
|
||||
<Link
|
||||
to="/teilnahme"
|
||||
style={{
|
||||
fontFamily: FF, fontSize: 16, fontWeight: 700, textTransform: 'uppercase',
|
||||
letterSpacing: '0.12em', color: '#101828', background: GOLD,
|
||||
padding: '15px 36px', textDecoration: 'none',
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8, transition: 'background 0.15s, box-shadow 0.2s',
|
||||
}}
|
||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#FFD130'; (e.currentTarget as HTMLElement).style.boxShadow = '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)'; }}
|
||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = GOLD; (e.currentTarget as HTMLElement).style.boxShadow = 'none'; }}
|
||||
>
|
||||
Jetzt kostenlos bewerben <ArrowRight size={14} />
|
||||
</Link>
|
||||
<div style={{ marginTop: 20, display: 'flex', alignItems: 'center', justifyContent: isMobile ? 'center' : undefined, flexWrap: isMobile ? 'wrap' : 'nowrap', gap: 8 }}>
|
||||
<span style={{ width: 20, height: 1, background: 'rgba(239,191,4,0.3)', display: 'inline-block' }} />
|
||||
<span style={{ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: 11, color: 'rgba(16,24,40,0.4)' }}>Diese Arbeit unterstützen:</span>
|
||||
<Link
|
||||
to="/mitglied-werden"
|
||||
style={{
|
||||
fontFamily: '"IBM Plex Sans", sans-serif',
|
||||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.12em',
|
||||
textTransform: 'uppercase',
|
||||
color: 'rgba(239,191,4,0.7)',
|
||||
textDecoration: 'none',
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
borderBottom: '1px solid rgba(239,191,4,0.3)',
|
||||
paddingBottom: 1,
|
||||
transition: 'color 0.15s, borderColor 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = '#EFBF04';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = '#EFBF04';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(e.currentTarget as HTMLElement).style.color = 'rgba(239,191,4,0.7)';
|
||||
(e.currentTarget as HTMLElement).style.borderBottomColor = 'rgba(239,191,4,0.3)';
|
||||
}}
|
||||
>
|
||||
Vereinsmitglied werden <ChevronRight size={10} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── WinnerCard ───────────────────────────────────────────────────────────────
|
||||
|
||||
function WinnerCard({ winner }: { winner: import('@/spa/data/winners').Winner }) {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const isMobile = useIsMobile();
|
||||
return (
|
||||
<Link
|
||||
to={`/preistraeger/${winner.slug}`}
|
||||
style={{ textDecoration: 'none', display: 'block', position: 'relative', height: isMobile ? 260 : 340, overflow: 'hidden', boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.07)', scrollSnapAlign: isMobile ? 'start' : undefined }}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
>
|
||||
<img
|
||||
src={winner.img}
|
||||
alt={winner.name}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', transition: 'transform 0.5s ease', transform: hovered ? 'scale(1.06)' : 'scale(1)' }}
|
||||
/>
|
||||
{/* base gradient */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.15) 55%, transparent 100%)' }} />
|
||||
{/* hover overlay */}
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.22)', opacity: hovered ? 1 : 0, transition: 'opacity 0.25s' }} />
|
||||
|
||||
{/* Text */}
|
||||
<div style={{ position: 'absolute', bottom: 0, left: 0, padding: '18px 22px', width: '100%', boxSizing: 'border-box' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 5 }}>
|
||||
<Trophy size={12} style={{ color: GOLD, flexShrink: 0 }} fill={GOLD} />
|
||||
<span style={{ fontFamily: FF, fontSize: 12, fontWeight: 700, color: GOLD, letterSpacing: '0.12em', textTransform: 'uppercase' }}>
|
||||
{winner.year} · {winner.type}
|
||||
</span>
|
||||
</div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 18, fontWeight: 700, color: '#fff', margin: 0, lineHeight: 1.3, textShadow: '0 1px 4px rgba(0,0,0,0.5)' }}>
|
||||
{winner.name}
|
||||
</h3>
|
||||
<p style={{ fontFamily: FF, fontSize: 16, color: 'rgba(255,255,255,0.82)', margin: '4px 0 0', lineHeight: 1.3 }}>
|
||||
{winner.category}
|
||||
</p>
|
||||
|
||||
{/* Pill button */}
|
||||
<div style={{
|
||||
marginTop: 12,
|
||||
display: 'inline-flex', alignItems: 'center', gap: 7,
|
||||
background: NAVY, color: '#fff',
|
||||
padding: '9px 18px', borderRadius: 999,
|
||||
fontSize: 16, fontWeight: 700, fontFamily: FF,
|
||||
textTransform: 'uppercase', letterSpacing: '0.06em',
|
||||
opacity: hovered ? 1 : 0,
|
||||
transform: hovered ? 'translateY(0)' : 'translateY(6px)',
|
||||
transition: 'opacity 0.25s, transform 0.25s',
|
||||
}}>
|
||||
<Trophy size={14} /> Mehr erfahren
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// ── SelectControl ────────────────────────────────────────────────────────────
|
||||
|
||||
function SelectControl({ value, onChange, placeholder, options, width }: {
|
||||
value: string; onChange: (v: string) => void;
|
||||
placeholder: string; options: { label: string; value: string }[];
|
||||
width?: number;
|
||||
}) {
|
||||
const active = !!value;
|
||||
return (
|
||||
<div style={{ position: 'relative', width: width ?? '100%', flexShrink: width ? 0 : 1 }}>
|
||||
<select
|
||||
value={value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
style={{
|
||||
width: '100%', height: 44, padding: '0 36px 0 14px',
|
||||
fontFamily: FF, fontSize: 16,
|
||||
border: `1px solid ${active ? NAVY : BORDER}`,
|
||||
color: active ? NAVY : GRAY,
|
||||
background: '#fff', borderRadius: 0,
|
||||
appearance: 'none', cursor: 'pointer', outline: 'none',
|
||||
transition: 'border-color 0.15s',
|
||||
}}
|
||||
onFocus={e => (e.currentTarget.style.borderColor = GOLD)}
|
||||
onBlur={e => (e.currentTarget.style.borderColor = active ? NAVY : BORDER)}
|
||||
>
|
||||
<option value="">{placeholder}</option>
|
||||
{options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
|
||||
</select>
|
||||
<ChevronDown size={16} style={{ position: 'absolute', right: 12, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: '#101828' }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── SearchControl ────────────────────────────────────────────────────────────
|
||||
|
||||
function SearchControl({ value, onChange }: { value: string; onChange: (v: string) => void }) {
|
||||
return (
|
||||
<div style={{ position: 'relative', flex: 1, minWidth: 200 }}>
|
||||
<input
|
||||
type="text"
|
||||
value={value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
placeholder="Stichwortsuche …"
|
||||
style={{
|
||||
width: '100%', height: 44, padding: '0 40px 0 14px',
|
||||
fontFamily: FF, fontSize: 16,
|
||||
border: `1px solid ${BORDER}`, borderRadius: 0,
|
||||
background: '#fff', outline: 'none', boxSizing: 'border-box',
|
||||
transition: 'border-color 0.15s', color: '#101828',
|
||||
}}
|
||||
onFocus={e => (e.currentTarget.style.borderColor = GOLD)}
|
||||
onBlur={e => (e.currentTarget.style.borderColor = BORDER)}
|
||||
/>
|
||||
<Search size={16} style={{ position: 'absolute', right: 14, top: '50%', transform: 'translateY(-50%)', pointerEvents: 'none', color: GRAY }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
164
src/spa/pages/PreistraegerDetail.tsx
Normal file
164
src/spa/pages/PreistraegerDetail.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import React from 'react';
|
||||
import { Link, useParams, Navigate } from '@/spa/router';
|
||||
import { Trophy, ArrowLeft, MapPin, Building2, Globe, ChevronRight } from 'lucide-react';
|
||||
import { WINNERS } from '@/spa/data/winners';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const BORDER = '#D0D5DD';
|
||||
const GRAY = '#666666';
|
||||
const BG_ALT = '#E4E2E3';
|
||||
|
||||
export default function PreistraegerDetail() {
|
||||
const { slug } = useParams<{ slug: string }>();
|
||||
const winner = WINNERS.find(w => w.slug === slug);
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (!winner) return <Navigate to="/preistraeger" replace />;
|
||||
|
||||
// Pick a second photo (offset from primary)
|
||||
const secondImg = winner.img.replace('w=800', 'w=900').replace('q=80', 'q=75');
|
||||
|
||||
return (
|
||||
<div style={{ background: '#fff', minHeight: '100vh' }}>
|
||||
{/* Hero */}
|
||||
<div style={{ width: '100%', height: '60vh', overflow: 'hidden', position: 'relative' }}>
|
||||
<img
|
||||
src={winner.img}
|
||||
alt={winner.name}
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
|
||||
/>
|
||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, transparent 50%, rgba(3,9,58,0.82) 100%)' }} />
|
||||
</div>
|
||||
|
||||
{/* Breadcrumb */}
|
||||
<div style={{ background: '#fff', borderBottom: `1px solid ${BORDER}`, padding: isMobile ? '16px 24px' : '16px 80px', display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<Link to="/preistraeger" style={{ fontFamily: FF, fontSize: 16, color: GOLD, textDecoration: 'none', fontWeight: 600 }}>
|
||||
Preisträger:innen
|
||||
</Link>
|
||||
<ChevronRight size={14} style={{ color: GRAY }} />
|
||||
<span style={{ fontFamily: FF, fontSize: 16, color: GRAY }}>{winner.name}</span>
|
||||
</div>
|
||||
|
||||
{/* Header block */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 28px' : '48px 80px 40px', borderBottom: `1px solid ${BORDER}` }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 16, flexWrap: 'wrap' }}>
|
||||
<span style={{
|
||||
fontFamily: FF, fontSize: 11, fontWeight: 700, color: '#fff',
|
||||
background: NAVY, padding: '4px 14px', borderRadius: 999,
|
||||
textTransform: 'uppercase', letterSpacing: '0.1em',
|
||||
}}>
|
||||
{winner.category}
|
||||
</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: GOLD }}>
|
||||
{winner.year}
|
||||
</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 15, color: GRAY, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||||
{winner.type}
|
||||
</span>
|
||||
</div>
|
||||
<h1 style={{ fontFamily: FF, fontSize: isMobile ? 'clamp(1.6rem, 5vw, 3rem)' : 'clamp(2rem, 5vw, 3rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.02em', margin: '0 0 12px' }}>
|
||||
{winner.name}
|
||||
</h1>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: GRAY, margin: 0, maxWidth: 640, lineHeight: 1.6 }}>
|
||||
{winner.shortDesc}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Content 2-col */}
|
||||
<div style={{ padding: isMobile ? '48px 24px' : '64px 80px', display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 1fr', gap: isMobile ? 40 : 64 }}>
|
||||
{/* Left: Text */}
|
||||
<div>
|
||||
<h2 style={{ fontFamily: FF, fontSize: 18, fontWeight: 800, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 20 }}>
|
||||
Über das Unternehmen
|
||||
</h2>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: '#333', lineHeight: 1.8, marginBottom: 40 }}>
|
||||
{winner.longDesc}
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontFamily: FF, fontSize: 18, fontWeight: 800, color: '#101828', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 20 }}>
|
||||
Warum ausgezeichnet?
|
||||
</h2>
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: '#333', lineHeight: 1.8, marginBottom: 40 }}>
|
||||
Die Jury des Bayerischen Mittelstandspreises überzeugte {winner.name} durch außergewöhnliche Leistungen im Bereich <strong>{winner.category}</strong>. Das Unternehmen steht exemplarisch für die Stärken des bayerischen Mittelstands: unternehmerischen Mut, wertebasierte Führung und nachhaltige Wirkung weit über den eigenen Betrieb hinaus.
|
||||
</p>
|
||||
|
||||
{/* Quote */}
|
||||
<div style={{ borderLeft: `4px solid ${GOLD}`, paddingLeft: 24, marginBottom: 40 }}>
|
||||
<p style={{ fontFamily: FB, fontStyle: 'italic', fontSize: 18, color: '#101828', lineHeight: 1.7, marginBottom: 12 }}>
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginRight: 4, fontFamily: '"IBM Plex Sans"' }}>"</span>
|
||||
{winner.quote}
|
||||
<span style={{ color: GOLD, fontSize: 28, lineHeight: 1, marginLeft: 2, fontFamily: '"IBM Plex Sans"' }}>"</span>
|
||||
</p>
|
||||
<p style={{ fontFamily: FF, fontSize: 16, fontWeight: 700, color: GRAY, margin: 0, textTransform: 'uppercase', letterSpacing: '0.08em' }}>
|
||||
– {winner.quotePerson}, {winner.quoteRole}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: Photo + Info box */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
|
||||
{/* Photo */}
|
||||
<div style={{ borderRadius: 0, overflow: 'hidden', aspectRatio: '4/3' }}>
|
||||
<img src="/gala-preistraeger.jpg" alt="Gala Preisverleihung" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', filter: 'brightness(0.95)' }} />
|
||||
</div>
|
||||
|
||||
{/* Kenndaten */}
|
||||
<div style={{ background: BG_ALT, borderLeft: `3px solid ${GOLD}`, padding: '20px 24px' }}>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: GRAY, textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 20 }}>
|
||||
Auf einen Blick
|
||||
</h3>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
{[
|
||||
{ label: 'Kategorie', value: winner.category, icon: <Trophy size={14} style={{ color: GOLD }} /> },
|
||||
{ label: 'Auszeichnung', value: winner.type, icon: <Trophy size={14} style={{ color: GOLD }} /> },
|
||||
{ label: 'Jahr', value: String(winner.year), icon: null },
|
||||
{ label: 'Standort', value: winner.location, icon: <MapPin size={14} style={{ color: GOLD }} /> },
|
||||
{ label: 'Branche', value: winner.industry, icon: <Building2 size={14} style={{ color: GOLD }} /> },
|
||||
].map(row => (
|
||||
<div key={row.label} style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||
<span style={{ fontFamily: FF, fontSize: 11, color: GRAY, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{row.label}</span>
|
||||
<span style={{ fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', overflowWrap: 'anywhere' }}>{row.value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Website button */}
|
||||
<a
|
||||
href={`https://${winner.website}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 8,
|
||||
fontFamily: FF, fontSize: 16, fontWeight: 700,
|
||||
color: '#101828', border: `2px solid ${NAVY}`,
|
||||
padding: '12px 20px', textDecoration: 'none',
|
||||
textTransform: 'uppercase', letterSpacing: '0.08em',
|
||||
transition: 'all 0.2s', borderRadius: 0, overflowWrap: 'anywhere',
|
||||
}}
|
||||
onMouseEnter={e => { const el = e.currentTarget as HTMLElement; el.style.background = NAVY; el.style.color = '#fff'; }}
|
||||
onMouseLeave={e => { const el = e.currentTarget as HTMLElement; el.style.background = 'transparent'; el.style.color = NAVY; }}
|
||||
>
|
||||
<Globe size={16} /> Website besuchen ↗
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Back link */}
|
||||
<div style={{ padding: isMobile ? '32px 24px 48px' : '32px 80px 64px', borderTop: `1px solid ${BORDER}` }}>
|
||||
<Link
|
||||
to="/preistraeger"
|
||||
style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontFamily: FF, fontSize: 17, fontWeight: 700, color: '#101828', textDecoration: 'none', textTransform: 'uppercase', letterSpacing: '0.06em', transition: 'color 0.15s' }}
|
||||
onMouseEnter={e => ((e.currentTarget as HTMLElement).style.color = GOLD)}
|
||||
onMouseLeave={e => ((e.currentTarget as HTMLElement).style.color = NAVY)}
|
||||
>
|
||||
<ArrowLeft size={16} /> Alle Preisträger
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
841
src/spa/pages/Press.tsx
Normal file
841
src/spa/pages/Press.tsx
Normal file
@@ -0,0 +1,841 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from '@/spa/router';
|
||||
import { Calendar, MapPin, Download, ArrowRight, FileText } from 'lucide-react';
|
||||
import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||
|
||||
const NAVY = '#111D55';
|
||||
const GOLD = '#EFBF04';
|
||||
const CREAM = '#E4E2E3';
|
||||
const FF = '"IBM Plex Sans", sans-serif';
|
||||
const FB = '"Inter", sans-serif';
|
||||
|
||||
const events = [
|
||||
{
|
||||
title: 'Preisverleihung 2026',
|
||||
date: '22. Okt 2026',
|
||||
location: 'München, Residenz',
|
||||
cat: 'Gala / Event',
|
||||
status: 'In Planung',
|
||||
img: '/images/buehne-moderatoren.jpg',
|
||||
desc: 'Der glanzvolle Höhepunkt des Jahres. Die Verleihung der Preise in der prachtvollen Kulisse der Residenz München.',
|
||||
slug: '/presse/events/preisverleihung-2026',
|
||||
},
|
||||
{
|
||||
title: 'Mittelstands-Gipfel',
|
||||
date: '15. Juni 2026',
|
||||
location: 'Nürnberg',
|
||||
cat: 'Workshop',
|
||||
status: 'Anmeldung offen',
|
||||
img: '/images/networking-innenhof.jpg',
|
||||
desc: 'Regionaler Austausch und Best-Practices für bayerische Unternehmen auf dem Weg zum Preis.',
|
||||
slug: '/presse/events/mittelstands-gipfel-2026',
|
||||
},
|
||||
{
|
||||
title: 'Nominierten-Auswahl',
|
||||
date: '04. Aug 2026',
|
||||
location: 'Regensburg',
|
||||
cat: 'Jury-Sitzung',
|
||||
status: 'Intern',
|
||||
img: '/images/saal-gedeckt.jpg',
|
||||
desc: 'Das Gremium sichtet die Ergebnisse der Audits und legt die Nominierten für die Hauptpreise fest.',
|
||||
slug: '/presse/events/nominierten-auswahl-2026',
|
||||
},
|
||||
];
|
||||
|
||||
const news = [
|
||||
{
|
||||
title: 'Wie Bayerns KMU die KI nutzen',
|
||||
excerpt:
|
||||
'Ein Deep-Dive in die Bewerbungsunterlagen 2024 zeigt: Der Mittelstand treibt die Digitalisierung aktiv voran.',
|
||||
cat: 'Innovation',
|
||||
img: '/images/gala-saal-overview.jpg',
|
||||
slug: '/presse/blog/ki-nutzung-bayerischer-kmu',
|
||||
},
|
||||
{
|
||||
title: 'Start der Ehrenamts-Initiative',
|
||||
excerpt:
|
||||
'Gemeinsam mit unseren Partnern fördern wir soziale Projekte mittelständischer Unternehmen.',
|
||||
cat: 'Engagement',
|
||||
img: '/images/networking-innenhof.jpg',
|
||||
slug: '/presse/blog/ehrenamts-initiative-2026',
|
||||
},
|
||||
{
|
||||
title: 'Bayerische Wirtschaft wächst',
|
||||
excerpt:
|
||||
'Neue Prognosen zeigen ein stabiles Wachstum für den Mittelstand – gute Aussichten für die Awards.',
|
||||
cat: 'Wirtschaft',
|
||||
img: '/images/gala-dinner.jpg',
|
||||
slug: '/presse/blog/bayerische-wirtschaft-waechst',
|
||||
},
|
||||
];
|
||||
|
||||
function NewsCard({ item, idx, isMobile }: { item: typeof news[0]; idx: number; isMobile: boolean }) {
|
||||
const [hovered, setHovered] = React.useState(false);
|
||||
return (
|
||||
<Link
|
||||
to={item.slug}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
cursor: 'pointer',
|
||||
borderLeft: isMobile ? 'none' : (idx > 0 ? '1px solid rgba(255,255,255,0.07)' : 'none'),
|
||||
borderBottom: isMobile && idx < news.length - 1 ? '1px solid rgba(255,255,255,0.07)' : 'none',
|
||||
textDecoration: 'none',
|
||||
}}
|
||||
>
|
||||
{/* image */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', height: 220 }}>
|
||||
<img
|
||||
src={item.img}
|
||||
alt={item.title}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
filter: hovered ? 'none' : 'grayscale(100%)',
|
||||
transition: 'filter 0.5s',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '50%',
|
||||
background: 'linear-gradient(to top, rgba(3,9,58,0.8), transparent)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/* body */}
|
||||
<div style={{ padding: isMobile ? '24px 24px 32px' : '32px 36px 40px', display: 'flex', flexDirection: 'column', flex: 1 }}>
|
||||
<span
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 9,
|
||||
color: GOLD,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.22em',
|
||||
fontWeight: 700,
|
||||
marginBottom: 12,
|
||||
display: 'block',
|
||||
}}
|
||||
>
|
||||
{item.cat}
|
||||
</span>
|
||||
<h3
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 'clamp(1rem, 1.5vw, 1.2rem)',
|
||||
fontWeight: 700,
|
||||
color: '#fff',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.01em',
|
||||
lineHeight: 1.25,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</h3>
|
||||
<div
|
||||
style={{
|
||||
width: hovered ? '100%' : 24,
|
||||
height: 1,
|
||||
background: 'rgba(239,191,4,0.5)',
|
||||
transition: 'width 0.4s ease',
|
||||
marginBottom: 16,
|
||||
}}
|
||||
/>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(255,255,255,0.4)',
|
||||
lineHeight: 1.7,
|
||||
flex: 1,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
{item.excerpt}
|
||||
</p>
|
||||
<span
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.12em',
|
||||
color: GOLD,
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 5,
|
||||
}}
|
||||
>
|
||||
Weiterlesen <ArrowRight size={12} />
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
const Press: React.FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const [hoveredEvent, setHoveredEvent] = useState<number | null>(null);
|
||||
const [dlHovered, setDlHovered] = useState(false);
|
||||
const [submitHovered, setSubmitHovered] = useState(false);
|
||||
|
||||
// Form state
|
||||
const [medium, setMedium] = useState('');
|
||||
const [name, setName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (medium.trim() && name.trim() && email.trim()) {
|
||||
setSubmitted(true);
|
||||
}
|
||||
};
|
||||
|
||||
// DarkInput defined inline as required
|
||||
function DarkInput(props: React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
const [f, setF] = React.useState(false);
|
||||
return (
|
||||
<input
|
||||
{...props}
|
||||
onFocus={(e) => {
|
||||
setF(true);
|
||||
props.onFocus?.(e);
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
setF(false);
|
||||
props.onBlur?.(e);
|
||||
}}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 44,
|
||||
padding: '0 14px',
|
||||
fontFamily: FF,
|
||||
fontSize: 18,
|
||||
color: '#fff',
|
||||
border: `1px solid ${f ? 'rgba(239,191,4,0.8)' : 'rgba(255,255,255,0.12)'}`,
|
||||
background: f ? 'rgba(255,255,255,0.08)' : 'rgba(255,255,255,0.05)',
|
||||
outline: 'none',
|
||||
boxSizing: 'border-box',
|
||||
transition: 'border-color 0.15s, background 0.15s',
|
||||
...props.style,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="animate-fade-in">
|
||||
|
||||
{/* ── 1. HERO ─────────────────────────────────────────────────────── */}
|
||||
<section
|
||||
style={{
|
||||
position: 'relative',
|
||||
minHeight: '65vh',
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
overflow: 'hidden',
|
||||
background: NAVY,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src="/images/gala-dinner.jpg"
|
||||
alt="Presse BMP"
|
||||
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
background: isMobile
|
||||
? 'linear-gradient(to top, rgba(2,9,48,0.95) 0%, rgba(2,9,48,0.72) 38%, rgba(2,9,48,0.22) 72%, transparent 100%)'
|
||||
: 'linear-gradient(to right, #020930 0%, rgba(2,9,48,0.90) 38%, rgba(2,9,48,0.18) 65%, transparent 100%)',
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: 2,
|
||||
background: 'linear-gradient(to right, #EFBF04, rgba(239,191,4,0.3), transparent)',
|
||||
}}
|
||||
/>
|
||||
<div style={{ position: 'relative', zIndex: 1, padding: isMobile ? '0 24px 48px' : '0 80px 80px', maxWidth: 860 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 24 }}>
|
||||
<div style={{ width: 36, height: 2, background: GOLD }} />
|
||||
<span
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.32em',
|
||||
textTransform: 'uppercase',
|
||||
color: GOLD,
|
||||
}}
|
||||
>
|
||||
Presse & Newsroom
|
||||
</span>
|
||||
</div>
|
||||
<h1
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: isMobile ? 'clamp(2rem, 8vw, 2.8rem)' : 'clamp(2.8rem, 6vw, 5rem)',
|
||||
fontWeight: 900,
|
||||
color: '#fff',
|
||||
lineHeight: 0.95,
|
||||
letterSpacing: '-0.03em',
|
||||
textTransform: 'uppercase',
|
||||
margin: '0 0 24px',
|
||||
overflowWrap: 'anywhere',
|
||||
}}
|
||||
>
|
||||
EVENTS &<br />BERICHTERSTATTUNG.
|
||||
</h1>
|
||||
<div style={{ width: 48, height: 2, background: GOLD, marginBottom: 24 }} />
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(255,255,255,0.6)',
|
||||
fontWeight: 300,
|
||||
maxWidth: 520,
|
||||
lineHeight: 1.7,
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
Alle Termine, Pressemitteilungen und Medienmaterial rund um den Bayerischen Mittelstandspreis.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── 2. EVENTS ───────────────────────────────────────────────────── */}
|
||||
<section id="events" style={{ background: CREAM, overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
{/* Section header */}
|
||||
<div
|
||||
style={{
|
||||
padding: isMobile ? '48px 24px 40px' : '80px 80px 56px',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
|
||||
gap: isMobile ? 24 : 48,
|
||||
alignItems: 'flex-end',
|
||||
borderBottom: '1px solid rgba(3,9,58,0.1)',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.28em',
|
||||
color: '#4A8FC9',
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
Termine 2026
|
||||
</div>
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontWeight: 900,
|
||||
color: '#101828',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.025em',
|
||||
fontSize: 'clamp(2rem, 3.5vw, 3rem)',
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
EVENTS RUND UM DEN PREIS.
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(16,24,40,0.45)',
|
||||
lineHeight: 1.8,
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
Von der Jurysitzung bis zur festlichen Gala – alle Veranstaltungen auf einen Blick.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Event rows */}
|
||||
{events.map((event, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
onMouseEnter={() => setHoveredEvent(idx)}
|
||||
onMouseLeave={() => setHoveredEvent(null)}
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? '1fr' : '320px 1fr',
|
||||
borderBottom: '1px solid rgba(3,9,58,0.08)',
|
||||
background: hoveredEvent === idx ? '#EAE7E6' : 'transparent',
|
||||
transition: 'background 0.15s',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
{/* Left – image cell */}
|
||||
<div style={{ position: 'relative', overflow: 'hidden', height: isMobile ? 200 : 240 }}>
|
||||
<img src={event.img} alt={event.title} style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
|
||||
<div style={{ position: 'absolute', top: 20, left: 20, padding: '5px 12px', fontFamily: FF, fontSize: 9, fontWeight: 700, textTransform: 'uppercase' as const, letterSpacing: '0.18em', background: event.status === 'Anmeldung offen' ? GOLD : 'rgba(3,9,58,0.85)', color: event.status === 'Anmeldung offen' ? NAVY : 'rgba(255,255,255,0.6)' }}>
|
||||
{event.status}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right – copy cell */}
|
||||
<div style={{ padding: isMobile ? '24px 24px 32px' : '40px 56px 40px 48px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
<div style={{ fontFamily: FF, fontSize: 9, color: '#4A8FC9', textTransform: 'uppercase' as const, letterSpacing: '0.22em', fontWeight: 700, marginBottom: 10 }}>{event.cat}</div>
|
||||
<h3 style={{ fontFamily: FF, fontSize: 'clamp(1.3rem, 2vw, 1.7rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase' as const, letterSpacing: '-0.02em', margin: '0 0 14px' }}>{event.title}</h3>
|
||||
<div style={{ display: 'flex', gap: isMobile ? 16 : 28, alignItems: 'center', flexWrap: 'wrap', marginBottom: 16 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 6, fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)' }}>
|
||||
<Calendar size={14} color={GOLD} />{event.date}
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 6, fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)' }}>
|
||||
<MapPin size={14} color={GOLD} />{event.location}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ width: 24, height: 1, background: 'rgba(239,191,4,0.4)', marginBottom: 14 }} />
|
||||
<p style={{ fontFamily: FB, fontSize: 18, color: 'rgba(16,24,40,0.5)', lineHeight: 1.7, flex: 1 }}>{event.desc}</p>
|
||||
<Link to={event.slug} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, marginTop: 16, fontFamily: FF, fontSize: 16, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em', color: '#101828', textDecoration: 'none' }}>
|
||||
Details <ArrowRight size={12} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* ── 3. NEWSROOM ─────────────────────────────────────────────────── */}
|
||||
<section style={{ background: NAVY, overflow: 'hidden' }}>
|
||||
{/* Section header */}
|
||||
<div
|
||||
style={{
|
||||
padding: isMobile ? '48px 24px 40px' : '80px 80px 56px',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr',
|
||||
gap: isMobile ? 24 : 48,
|
||||
alignItems: 'flex-end',
|
||||
borderBottom: '1px solid rgba(255,255,255,0.07)',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.28em',
|
||||
color: GOLD,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
Newsroom
|
||||
</div>
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontWeight: 900,
|
||||
color: '#fff',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.025em',
|
||||
fontSize: 'clamp(2rem, 3.5vw, 3rem)',
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
NACHRICHTEN & EINBLICKE.
|
||||
</h2>
|
||||
</div>
|
||||
<div>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(255,255,255,0.4)',
|
||||
lineHeight: 1.8,
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
Berichte, Hintergründe und Einblicke rund um den bayerischen Mittelstand und den BMP.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 3-column news grid */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : 'repeat(3, 1fr)' }}>
|
||||
{news.map((item, idx) => (
|
||||
<NewsCard key={idx} item={item} idx={idx} isMobile={isMobile} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ── 4. PRESSE-MATERIAL & AKKREDITIERUNG ─────────────────────────── */}
|
||||
<section id="downloads" style={{ background: CREAM, overflow: 'hidden', position: 'relative', isolation: 'isolate' }}>
|
||||
<MunichSkylineBg />
|
||||
<div style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : '55% 45%', minHeight: isMobile ? 'auto' : 600 }}>
|
||||
|
||||
{/* Left col */}
|
||||
<div
|
||||
style={{
|
||||
padding: isMobile ? '48px 24px' : '88px 80px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
borderRight: isMobile ? 'none' : '1px solid rgba(3,9,58,0.1)',
|
||||
borderBottom: isMobile ? '1px solid rgba(3,9,58,0.1)' : 'none',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.28em',
|
||||
color: '#4A8FC9',
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
Pressekontakt & Material
|
||||
</div>
|
||||
|
||||
<h2
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontWeight: 900,
|
||||
color: '#101828',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.025em',
|
||||
fontSize: 'clamp(1.8rem, 3vw, 2.6rem)',
|
||||
margin: '0 0 20px',
|
||||
}}
|
||||
>
|
||||
PRESSE-MATERIAL & KONTAKT.
|
||||
</h2>
|
||||
|
||||
{/* Gold divider */}
|
||||
<div style={{ width: 40, height: 2, background: GOLD, margin: '0 0 28px' }} />
|
||||
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(16,24,40,0.5)',
|
||||
lineHeight: 1.8,
|
||||
maxWidth: 380,
|
||||
marginBottom: 48,
|
||||
}}
|
||||
>
|
||||
Laden Sie unser offizielles Material herunter oder kontaktieren Sie direkt unser Presseteam für individuelle Anfragen.
|
||||
</p>
|
||||
|
||||
{/* Download button */}
|
||||
<a
|
||||
href="/Print_BMP.zip"
|
||||
download="Print_BMP.zip"
|
||||
onMouseEnter={() => setDlHovered(true)}
|
||||
onMouseLeave={() => setDlHovered(false)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 20,
|
||||
padding: '24px 28px',
|
||||
border: `1px solid ${dlHovered ? GOLD : 'rgba(3,9,58,0.12)'}`,
|
||||
background: '#fff',
|
||||
cursor: 'pointer',
|
||||
marginBottom: 20,
|
||||
transition: 'border-color 0.15s',
|
||||
textDecoration: 'none',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
background: NAVY,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<Download size={20} color={GOLD} />
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 18,
|
||||
fontWeight: 700,
|
||||
color: '#101828',
|
||||
marginBottom: 3,
|
||||
}}
|
||||
>
|
||||
Download Presse-Kit
|
||||
</div>
|
||||
<div style={{ fontFamily: FB, fontSize: 17, color: 'rgba(16,24,40,0.4)' }}>
|
||||
Print_BMP.zip – 1,5 MB
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{/* Press contact block */}
|
||||
<div style={{ borderLeft: `3px solid ${GOLD}`, paddingLeft: 24, marginTop: 32 }}>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
color: '#4A8FC9',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.2em',
|
||||
fontWeight: 700,
|
||||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
Pressekontakt
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 18,
|
||||
fontWeight: 700,
|
||||
color: '#101828',
|
||||
marginBottom: 4,
|
||||
}}
|
||||
>
|
||||
Tanja Meier
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(16,24,40,0.55)',
|
||||
lineHeight: 1.8,
|
||||
overflowWrap: 'anywhere',
|
||||
}}
|
||||
>
|
||||
presse@bmp-bayern.de
|
||||
<br />
|
||||
+49 89 123 456 99
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right col */}
|
||||
<div
|
||||
style={{
|
||||
background: NAVY,
|
||||
padding: isMobile ? '48px 24px' : '72px 64px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{submitted ? (
|
||||
/* Success state */
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
background: GOLD,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 28,
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<FileText size={24} color={NAVY} />
|
||||
</div>
|
||||
<h3
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 'clamp(1.4rem, 2.2vw, 1.8rem)',
|
||||
fontWeight: 900,
|
||||
color: '#fff',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.02em',
|
||||
margin: '0 0 16px',
|
||||
}}
|
||||
>
|
||||
Anfrage eingegangen
|
||||
</h3>
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(255,255,255,0.45)',
|
||||
lineHeight: 1.8,
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
Vielen Dank für Ihre Akkreditierungsanfrage. Unser Presseteam meldet sich zeitnah bei Ihnen.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
color: GOLD,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.32em',
|
||||
fontWeight: 700,
|
||||
marginBottom: 20,
|
||||
}}
|
||||
>
|
||||
Akkreditierung
|
||||
</div>
|
||||
|
||||
<h3
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 'clamp(1.4rem, 2.2vw, 1.8rem)',
|
||||
fontWeight: 900,
|
||||
color: '#fff',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '-0.02em',
|
||||
margin: '0 0 16px',
|
||||
}}
|
||||
>
|
||||
AKKREDITIERUNG ANFRAGEN.
|
||||
</h3>
|
||||
|
||||
{/* Gold divider */}
|
||||
<div style={{ width: 36, height: 2, background: GOLD, marginBottom: 28 }} />
|
||||
|
||||
<p
|
||||
style={{
|
||||
fontFamily: FB,
|
||||
fontSize: 18,
|
||||
color: 'rgba(255,255,255,0.45)',
|
||||
lineHeight: 1.8,
|
||||
marginBottom: 36,
|
||||
}}
|
||||
>
|
||||
Melden Sie sich für unsere Presse-Verteiler an oder fordern Sie eine Akkreditierung für die Gala-Verleihung an.
|
||||
</p>
|
||||
|
||||
{/* Form fields */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.2em',
|
||||
color: 'rgba(255,255,255,0.35)',
|
||||
}}
|
||||
>
|
||||
Medium / Redaktion *
|
||||
</label>
|
||||
<DarkInput
|
||||
type="text"
|
||||
value={medium}
|
||||
onChange={(e) => setMedium(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.2em',
|
||||
color: 'rgba(255,255,255,0.35)',
|
||||
}}
|
||||
>
|
||||
Ihr Name *
|
||||
</label>
|
||||
<DarkInput
|
||||
type="text"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontFamily: FF,
|
||||
fontSize: 10,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.2em',
|
||||
color: 'rgba(255,255,255,0.35)',
|
||||
}}
|
||||
>
|
||||
E-Mail-Adresse *
|
||||
</label>
|
||||
<DarkInput
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Submit button */}
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
onMouseEnter={() => setSubmitHovered(true)}
|
||||
onMouseLeave={() => setSubmitHovered(false)}
|
||||
style={{
|
||||
background: submitHovered ? '#FFD130' : GOLD,
|
||||
boxShadow: submitHovered ? '0 0 18px rgba(239,191,4,0.65), 0 0 40px rgba(239,191,4,0.3)' : 'none',
|
||||
color: '#101828',
|
||||
border: 'none',
|
||||
fontFamily: FF,
|
||||
fontSize: 16,
|
||||
fontWeight: 700,
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: '0.12em',
|
||||
cursor: 'pointer',
|
||||
padding: '14px 28px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 8,
|
||||
width: '100%',
|
||||
transition: 'background 0.15s, box-shadow 0.2s',
|
||||
}}
|
||||
>
|
||||
Akkreditierung anfragen <ArrowRight size={13} />
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Press;
|
||||
Reference in New Issue
Block a user