performance
All checks were successful
Build & Deploy MB Grid Solutions / build-and-deploy (push) Successful in 1m38s

This commit is contained in:
2026-01-29 17:08:45 +01:00
parent e033fd6290
commit 25759f3d4a
16 changed files with 95 additions and 57 deletions

View File

@@ -1,6 +1,7 @@
'use client';
import React from 'react';
import Image from 'next/image';
import { Award, Clock, Lightbulb, Linkedin, MessageSquare, ShieldCheck, Truck } from 'lucide-react';
import { Reveal } from './Reveal';
import { TechBackground } from './TechBackground';
@@ -13,9 +14,12 @@ export default function About() {
{/* Hero Section */}
<section className="relative min-h-[60vh] flex items-center pt-32 pb-20 overflow-hidden">
<div className="absolute inset-0 z-0">
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: 'url("/media/drums/iStock-487538226 (1).jpg")' }}
<Image
src="/media/drums/about-hero.jpg"
alt="About MB Grid Solutions"
fill
className="object-cover"
priority
/>
<div className="absolute inset-0 bg-gradient-to-r from-white via-white/95 to-white/40" />
<TechBackground />

View File

@@ -1,7 +1,7 @@
'use client';
import React, { useRef, useState } from 'react';
import { motion } from 'framer-motion';
import { m, LazyMotion, domAnimation } from 'framer-motion';
import Link from 'next/link';
import { ArrowRight } from 'lucide-react';
@@ -60,13 +60,15 @@ export const Button = ({
);
const spotlight = (
<motion.div
<LazyMotion features={domAnimation}>
<m.div
className="absolute inset-0 z-0 pointer-events-none transition-opacity duration-500"
style={{
opacity: isHovered ? 1 : 0,
background: `radial-gradient(600px circle at ${mousePosition.x}px ${mousePosition.y}px, rgba(255,255,255,0.15), transparent 40%)`,
}}
/>
</LazyMotion>
);
const buttonProps = {

View File

@@ -1,6 +1,7 @@
'use client';
import React, { useState } from 'react';
import Image from 'next/image';
import { Mail, MapPin, CheckCircle } from 'lucide-react';
import { Button } from './Button';
import { Counter } from './Counter';
@@ -41,9 +42,12 @@ export default function Contact() {
{/* Hero Section */}
<section className="relative min-h-[40vh] flex items-center pt-32 pb-20 overflow-hidden">
<div className="absolute inset-0 z-0">
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: 'url("/media/laying/iStock-1282259999.jpg")' }}
<Image
src="/media/laying/contact-hero.jpg"
alt="Contact MB Grid Solutions"
fill
className="object-cover"
priority
/>
<div className="absolute inset-0 bg-gradient-to-r from-white via-white/95 to-white/40" />
<TechBackground />

View File

@@ -1,7 +1,8 @@
'use client';
import { motion } from 'framer-motion';
import { m, LazyMotion, domAnimation } from 'framer-motion';
import { BarChart3, CheckCircle2, ChevronRight, Shield, Zap } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { Button } from './Button';
import { Counter } from './Counter';
@@ -59,9 +60,13 @@ export default function Home() {
{/* Hero Section */}
<section className="relative min-h-[90vh] flex items-center pt-32 pb-20 overflow-hidden">
<div className="absolute inset-0 z-0">
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: 'url("/media/business/iStock-1068752548.jpg")' }}
<Image
src="/media/business/hero-bg.jpg"
alt="MB Grid Solutions Hero"
fill
className="object-cover"
priority
quality={90}
/>
<div className="absolute inset-0 bg-gradient-to-r from-slate-100/80 via-white/90 to-white/40 md:to-transparent" />
<TechBackground />
@@ -169,9 +174,11 @@ export default function Home() {
<Reveal direction="right">
<div className="relative overflow-hidden rounded-2xl shadow-lg group">
<div className="absolute inset-0 bg-accent/10 opacity-0 group-hover:opacity-100 transition-opacity duration-500 z-10 pointer-events-none" />
<img
src="/media/cables/HS Kabel.png"
<Image
src="/media/cables/hs-kabel.png"
alt="Technical Engineering"
width={800}
height={600}
className="w-full h-[400px] md:h-[500px] object-cover hover:scale-105 transition-transform duration-700"
/>
<div className="tech-corner top-4 left-4 border-t-2 border-l-2 z-20" />
@@ -214,10 +221,11 @@ export default function Home() {
{/* Technical Specs Section */}
<section className="relative py-24 md:py-32 text-white overflow-hidden bg-slate-900">
<div className="absolute inset-0 opacity-20">
<img
src="/media/drums/iStock-487538226 (1).jpg"
alt="Background"
className="w-full h-full object-cover"
<Image
src="/media/drums/about-hero.jpg"
alt="Background"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-b from-slate-900 via-slate-900/80 to-slate-900" />
</div>
@@ -277,23 +285,25 @@ export default function Home() {
<div className="tech-corner bottom-8 right-8 border-b-2 border-r-2" />
<div className="absolute top-0 right-0 w-1/2 h-full opacity-10 pointer-events-none">
<LazyMotion features={domAnimation}>
<svg viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<motion.circle
<m.circle
animate={{ r: [400, 410, 400], opacity: [0.1, 0.2, 0.1] }}
transition={{ duration: 5, repeat: Infinity, ease: "easeInOut" }}
cx="400" cy="0" r="400" stroke="white" strokeWidth="2"
cx="400" cy="0" r="400" stroke="white" strokeWidth="2"
/>
<motion.circle
<m.circle
animate={{ r: [300, 310, 300], opacity: [0.1, 0.2, 0.1] }}
transition={{ duration: 4, repeat: Infinity, ease: "easeInOut", delay: 0.5 }}
cx="400" cy="0" r="300" stroke="white" strokeWidth="2"
cx="400" cy="0" r="300" stroke="white" strokeWidth="2"
/>
<motion.circle
<m.circle
animate={{ r: [200, 210, 200], opacity: [0.1, 0.2, 0.1] }}
transition={{ duration: 3, repeat: Infinity, ease: "easeInOut", delay: 1 }}
cx="400" cy="0" r="200" stroke="white" strokeWidth="2"
cx="400" cy="0" r="200" stroke="white" strokeWidth="2"
/>
</svg>
</LazyMotion>
</div>
<div className="relative z-10">

View File

@@ -1,7 +1,8 @@
'use client';
import { AnimatePresence, motion } from 'framer-motion';
import { AnimatePresence, m, LazyMotion, domAnimation } from 'framer-motion';
import { ArrowUp, Home, Info, Menu, X } from 'lucide-react';
import Image from 'next/image';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import React, { useEffect, useState } from 'react';
@@ -55,12 +56,15 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
className="relative z-10 flex items-center group"
aria-label="MB Grid Solutions - Zur Startseite"
>
<img
src="/assets/logo.png"
alt="MB Grid Solutions"
className={`transition-all duration-300 object-contain ${isScrolled ? 'h-[50px] md:h-[80px] my-[-5px]' : 'h-[80px] md:h-[140px] my-[-10px] md:my-[-20px]'}`}
loading="eager"
/>
<div className={`relative transition-all duration-300 ${isScrolled ? 'h-[50px] md:h-[80px] w-[120px] md:w-[200px] my-[-5px]' : 'h-[80px] md:h-[140px] w-[180px] md:w-[320px] my-[-10px] md:my-[-20px]'}`}>
<Image
src="/assets/logo.png"
alt="MB Grid Solutions"
fill
className="object-contain"
priority
/>
</div>
</Link>
{/* Desktop Navigation */}
@@ -100,9 +104,10 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
</Reveal>
{/* Mobile Menu Overlay */}
<LazyMotion features={domAnimation}>
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
<m.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
@@ -130,9 +135,10 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
Projekt anfragen
</Button>
</nav>
</motion.div>
</m.div>
)}
</AnimatePresence>
</LazyMotion>
<main className="flex-grow">
{children}
@@ -153,16 +159,18 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
<div className="absolute inset-0 grid-pattern opacity-[0.08] pointer-events-none" />
{/* Animated Tech Lines */}
<motion.div
<LazyMotion features={domAnimation}>
<m.div
animate={{ x: ['-100%', '100%'] }}
transition={{ duration: 15, repeat: Infinity, ease: "linear" }}
className="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-accent/30 to-transparent"
/>
<motion.div
<m.div
animate={{ x: ['100%', '-100%'] }}
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
className="absolute bottom-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-accent/20 to-transparent"
/>
</LazyMotion>
{/* Corner Accents */}
<div className="tech-corner top-8 left-8 border-t border-l border-white/10 group-hover:border-accent/30 transition-colors duration-700" />
@@ -172,12 +180,14 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10 md:gap-12 mb-12 md:mb-16">
<div className="lg:col-span-2">
<Link href="/" className="inline-block mb-6 md:mb-8 group">
<img
src="/assets/logo.png"
alt="MB Grid Solutions"
className="h-16 md:h-20 brightness-0 invert opacity-80 group-hover:opacity-100 transition-opacity"
loading="lazy"
/>
<div className="relative h-16 md:h-20 w-48 brightness-0 invert opacity-80 group-hover:opacity-100 transition-opacity">
<Image
src="/assets/logo.png"
alt="MB Grid Solutions"
fill
className="object-contain object-left"
/>
</div>
</Link>
<p className="text-slate-400 max-w-md leading-relaxed mb-8">
Ihr spezialisierter Partner für herstellerneutrale technische Beratung und Projektbegleitung bei Energiekabelprojekten bis 110 kV.

View File

@@ -1,7 +1,7 @@
'use client';
import React from 'react';
import { motion } from 'framer-motion';
import { m, LazyMotion, domAnimation } from 'framer-motion';
interface RevealProps {
children: React.ReactNode;
@@ -26,9 +26,10 @@ export const Reveal = ({
};
return (
<motion.div
initial={{
opacity: 0,
<LazyMotion features={domAnimation}>
<m.div
initial={{
opacity: 0,
...directions[direction]
}}
whileInView={{
@@ -47,7 +48,8 @@ export const Reveal = ({
className={`${fullWidth ? 'w-full' : ''} ${className} motion-fix`}
>
{children}
</motion.div>
</m.div>
</LazyMotion>
);
};
@@ -63,7 +65,8 @@ export const Stagger = ({
staggerDelay = 0.1
}: StaggerProps) => {
return (
<motion.div
<LazyMotion features={domAnimation}>
<m.div
initial="initial"
whileInView="animate"
viewport={{ once: true, margin: "-50px" }}
@@ -77,6 +80,7 @@ export const Stagger = ({
className={className}
>
{children}
</motion.div>
</m.div>
</LazyMotion>
);
};

View File

@@ -1,7 +1,7 @@
'use client';
import React, { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { m, LazyMotion, domAnimation } from 'framer-motion';
export const TileGrid = () => {
const [mounted, setMounted] = useState(false);
@@ -17,26 +17,27 @@ export const TileGrid = () => {
return (
<div className="absolute inset-0 pointer-events-none overflow-hidden z-[1]">
<LazyMotion features={domAnimation}>
<div className="flex flex-col gap-3 min-w-[120%] min-h-[120%] -left-[10%] -top-[10%] absolute">
{[...Array(rows)].map((_, rowIndex) => (
<div
key={rowIndex}
<div
key={rowIndex}
className="flex gap-3 justify-center"
style={{
style={{
transform: rowIndex % 2 === 0 ? 'translateX(0)' : 'translateX(80px)',
}}
>
{[...Array(cols)].map((_, colIndex) => (
<motion.div
<m.div
key={`${rowIndex}-${colIndex}`}
initial={{ opacity: 0.05 }}
animate={{
animate={{
opacity: [0.05, Math.random() > 0.9 ? 0.25 : 0.05, 0.05],
scale: [1, Math.random() > 0.9 ? 1.05 : 1, 1]
}}
transition={{
duration: 5 + Math.random() * 5,
repeat: Infinity,
transition={{
duration: 5 + Math.random() * 5,
repeat: Infinity,
delay: Math.random() * 20,
ease: "easeInOut"
}}
@@ -46,6 +47,7 @@ export const TileGrid = () => {
</div>
))}
</div>
</LazyMotion>
</div>
);
};

View File

@@ -0,0 +1,2 @@
import { domAnimation } from "framer-motion"
export default domAnimation

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 MiB