Compare commits
4 Commits
feature/ta
...
v2.2.13-rc
| Author | SHA1 | Date | |
|---|---|---|---|
| 11b9e4630b | |||
| a47d378521 | |||
| 30047cb1c4 | |||
| 394ac5a19c |
@@ -19,6 +19,7 @@ import { TransitionProvider } from '@/components/providers/TransitionProvider';
|
||||
import { PageTransitionShutter } from '@/components/providers/PageTransitionShutter';
|
||||
import { InitialLoader } from '@/components/providers/InitialLoader';
|
||||
import { CorporateBackground } from '@/components/decorations/CorporateBackground';
|
||||
import { EUFundingBadge } from '@/components/decorations/EUFundingBadge';
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
@@ -202,6 +203,7 @@ export default async function Layout(props: {
|
||||
<PageTransitionShutter />
|
||||
<SkipLink />
|
||||
<Header navLinks={navLinks} />
|
||||
<EUFundingBadge />
|
||||
<MobileBottomNav navLinks={navLinks} currentLocale={safeLocale} />
|
||||
|
||||
<main
|
||||
|
||||
@@ -42,7 +42,7 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
||||
|
||||
return (
|
||||
<section
|
||||
className={`relative min-h-[45vh] md:min-h-[55vh] flex items-center pt-32 pb-20 md:pt-36 md:pb-24 overflow-hidden bg-neutral-dark ${alignment === 'center' ? 'justify-center text-center' : ''}`}
|
||||
className={`relative min-h-[45vh] md:min-h-[55vh] flex items-center pt-24 pb-16 md:pt-36 md:pb-24 overflow-hidden bg-neutral-dark ${alignment === 'center' ? 'justify-center text-center' : ''}`}
|
||||
>
|
||||
{bgSrc && (
|
||||
<motion.div
|
||||
|
||||
@@ -133,14 +133,16 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
||||
<Link
|
||||
href={`/${locale}/referenzen/${ref.slug}`}
|
||||
data-testid="reference-tile"
|
||||
draggable={false}
|
||||
onClick={(e) => {
|
||||
if (dragDistanceRef.current > 15) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
className="block relative aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl"
|
||||
className="block relative select-none aspect-[16/10] bg-neutral-800 rounded-2xl overflow-hidden mb-5 border border-white/5 shadow-2xl"
|
||||
>
|
||||
<Image
|
||||
draggable={false}
|
||||
src={imgSrc}
|
||||
alt={ref.title}
|
||||
fill
|
||||
|
||||
@@ -79,7 +79,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
)}
|
||||
|
||||
<motion.div
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
|
||||
className="flex overflow-x-auto snap-x snap-mandatory pb-6 md:pb-0 md:grid md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 hide-scrollbar -mx-4 px-4 md:mx-0 md:px-0"
|
||||
variants={containerVariants}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
@@ -236,7 +236,7 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
<motion.div
|
||||
key={index}
|
||||
variants={itemVariants}
|
||||
className="h-full"
|
||||
className="h-full flex-shrink-0 snap-center w-[85%] sm:w-[70%] md:w-full"
|
||||
>
|
||||
{hasUrl ? (
|
||||
isExternal ? (
|
||||
|
||||
@@ -78,7 +78,7 @@ export function CorporateBackground() {
|
||||
const y5 = useTransform(scrollYProgress, [0, 1], [0, -500]);
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 z-[50] overflow-hidden pointer-events-none" aria-hidden="true">
|
||||
<div className="absolute inset-0 z-[50] overflow-hidden pointer-events-none hidden md:block" aria-hidden="true">
|
||||
{/* 1. Top Right - Medium, rotating moderately */}
|
||||
<motion.div
|
||||
style={{
|
||||
|
||||
44
components/decorations/EUFundingBadge.tsx
Normal file
44
components/decorations/EUFundingBadge.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export function EUFundingBadge() {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="fixed top-24 right-4 md:right-6 lg:right-8 z-40 pointer-events-none select-none"
|
||||
>
|
||||
<div className="bg-white p-2.5 rounded-sm shadow-[0_8px_30px_rgba(0,0,0,0.12)] border border-neutral-200/60 flex flex-col items-center w-[110px] sm:w-[130px]">
|
||||
{/* EU Flag */}
|
||||
<svg viewBox="0 0 810 540" xmlns="http://www.w3.org/2000/svg" className="w-full h-auto">
|
||||
<path d="M0 0h810v540H0z" fill="#003399"/>
|
||||
<g fill="#fc0" transform="translate(405 270)">
|
||||
<use href="#eu-star" y="-180"/>
|
||||
<use href="#eu-star" y="180"/>
|
||||
<use href="#eu-star" x="-180"/>
|
||||
<use href="#eu-star" x="180"/>
|
||||
<use href="#eu-star" x="-155.885" y="-90"/>
|
||||
<use href="#eu-star" x="155.885" y="90"/>
|
||||
<use href="#eu-star" x="-155.885" y="90"/>
|
||||
<use href="#eu-star" x="155.885" y="-90"/>
|
||||
<use href="#eu-star" x="-90" y="-155.885"/>
|
||||
<use href="#eu-star" x="90" y="155.885"/>
|
||||
<use href="#eu-star" x="-90" y="155.885"/>
|
||||
<use href="#eu-star" x="90" y="-155.885"/>
|
||||
</g>
|
||||
<defs>
|
||||
<path id="eu-star" d="m0-30 7.053 21.708H29.39L10.36 7.64l7.054 21.709L0 15.692l-17.414 13.657 7.054-21.71L-29.39-8.292h22.337z"/>
|
||||
</defs>
|
||||
</svg>
|
||||
{/* Text */}
|
||||
<div className="mt-2 text-center w-full">
|
||||
<span className="block text-[9.5px] sm:text-[11.5px] font-bold text-[#003399] leading-[1.25] tracking-tight font-sans">
|
||||
Kofinanziert von der<br />Europäischen Union
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
const locale = useLocale();
|
||||
|
||||
return (
|
||||
<footer className="bg-[#050B14] text-neutral-light py-10 md:py-16 relative overflow-hidden border-t border-white/5">
|
||||
<footer className="bg-[#050B14] text-neutral-light pt-10 pb-28 md:py-16 relative overflow-hidden border-t border-white/5">
|
||||
{/* Subtle background tech grid */}
|
||||
<div className="absolute inset-0 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:32px_32px] [mask-image:radial-gradient(ellipse_80%_50%_at_50%_0%,#000_70%,transparent_100%)] pointer-events-none" />
|
||||
|
||||
@@ -28,7 +28,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
|
||||
<div className="container relative z-10 grid grid-cols-1 md:grid-cols-4 lg:grid-cols-12 gap-4 md:gap-6 lg:gap-8 mb-8 md:mb-12">
|
||||
{/* Brand Column Bento */}
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-5 flex flex-col justify-between bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden">
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-5 flex flex-col justify-between bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700" />
|
||||
|
||||
<div className="space-y-4 md:space-y-6 relative z-10">
|
||||
@@ -96,7 +96,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
<div className="col-span-1 md:col-span-4 lg:col-span-7 grid grid-cols-1 sm:grid-cols-2 gap-4 md:gap-6 lg:gap-8">
|
||||
|
||||
{/* Company Column */}
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="absolute inset-0 bg-gradient-to-bl from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
||||
<h4 className="font-heading font-bold uppercase tracking-widest text-sm mb-6 md:mb-8 text-white">
|
||||
{locale === 'de' ? 'Unternehmen' : 'Company'}
|
||||
@@ -124,7 +124,7 @@ export function Footer({ companyInfo }: FooterProps) {
|
||||
</div>
|
||||
|
||||
{/* Legal Column */}
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-6 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="bg-white/[0.02] border border-white/5 rounded-3xl p-5 md:p-8 lg:p-10 backdrop-blur-md relative group overflow-hidden flex flex-col">
|
||||
<div className="absolute inset-0 bg-gradient-to-tr from-white/[0.04] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700 pointer-events-none" />
|
||||
<h4 className="font-heading font-bold uppercase tracking-widest text-sm mb-6 md:mb-8 text-white">
|
||||
{locale === 'de' ? 'Rechtliches' : 'Legal'}
|
||||
|
||||
@@ -72,7 +72,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
className={`fixed top-0 left-0 right-0 z-50 flex justify-center transition-all duration-700 ease-[cubic-bezier(0.16,1,0.3,1)] ${
|
||||
isStandard
|
||||
? 'bg-[#050B14]/95 backdrop-blur-xl border-b border-white/10'
|
||||
: (isSolidMode ? 'pt-4 px-4' : 'pt-0 px-0')
|
||||
: (isSolidMode ? 'pt-4 px-4 sm:px-6' : 'pt-0 px-0')
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
@@ -80,7 +80,7 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
isStandard
|
||||
? 'py-4 px-6 md:px-8'
|
||||
: isSolidMode
|
||||
? 'rounded-full bg-white/50 backdrop-blur-xl shadow-[0_8px_32px_rgba(0,0,0,0.08)] border border-white/40 py-2.5 px-6 md:px-8'
|
||||
? 'rounded-full bg-white/50 backdrop-blur-xl shadow-[0_8px_32px_rgba(0,0,0,0.08)] border border-white/40 py-2.5 px-8 md:px-10'
|
||||
: 'rounded-none bg-transparent py-6 px-4 md:px-8 border border-transparent'
|
||||
}`}
|
||||
>
|
||||
@@ -165,6 +165,20 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink, currentLocale: string, pathname: string, isSolidMode: boolean }) {
|
||||
const [isHovered, setIsHovered] = React.useState(false);
|
||||
|
||||
// Close dropdown on navigation
|
||||
React.useEffect(() => {
|
||||
setIsHovered(false);
|
||||
}, [pathname]);
|
||||
|
||||
// Close dropdown on scroll
|
||||
React.useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (isHovered) setIsHovered(false);
|
||||
};
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, [isHovered]);
|
||||
|
||||
const mappedUrl = link.url.startsWith('/') && !link.url.match(/^\/(en|de)/)
|
||||
? `/${currentLocale}${link.url}`
|
||||
: link.url;
|
||||
@@ -237,6 +251,7 @@ function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink
|
||||
<TransitionLink
|
||||
key={child.url}
|
||||
href={childUrl}
|
||||
onClick={() => setIsHovered(false)}
|
||||
className={`group/dropitem relative block px-4 py-3.5 rounded-2xl text-sm font-medium transition-all duration-300 overflow-hidden ${
|
||||
isSolidMode
|
||||
? isChildActive ? 'bg-primary/10 text-primary' : 'text-neutral-600 hover:text-primary hover:bg-neutral-50/80'
|
||||
|
||||
Reference in New Issue
Block a user