design
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Award, Clock, Lightbulb, Linkedin, MessageSquare, ShieldCheck, Truck, ArrowRight } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { Award, Clock, Lightbulb, Linkedin, MessageSquare, ShieldCheck, Truck } from 'lucide-react';
|
||||
import { Reveal } from './Reveal';
|
||||
import { TechBackground } from './TechBackground';
|
||||
import { Counter } from './Counter';
|
||||
import { Button } from './Button';
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
@@ -47,7 +47,7 @@ export default function About() {
|
||||
<section className="bg-white relative overflow-hidden">
|
||||
<TechBackground />
|
||||
<div className="container-custom relative z-10">
|
||||
<Counter value={2} className="section-number" />
|
||||
<div className="section-number">02</div>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
|
||||
<Reveal direction="right">
|
||||
<div className="space-y-6 text-lg text-slate-600 leading-relaxed relative">
|
||||
@@ -83,14 +83,14 @@ export default function About() {
|
||||
</section>
|
||||
|
||||
{/* Manifest Section */}
|
||||
<section className="bg-slate-50 relative overflow-hidden">
|
||||
<section className="bg-slate-950 text-accent relative overflow-hidden">
|
||||
<TechBackground />
|
||||
<div className="container-custom relative z-10">
|
||||
<Counter value={3} className="section-number" />
|
||||
<Counter value={3} className="section-number !text-white/5" />
|
||||
<Reveal className="mb-20">
|
||||
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">Werte</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-primary mb-6">Unser Manifest</h2>
|
||||
<p className="text-slate-600 text-lg">Werte, die unsere tägliche Arbeit leiten und den Erfolg Ihrer Projekte sichern.</p>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">Unser Manifest</h2>
|
||||
<p className="text-slate-400 text-lg">Werte, die unsere tägliche Arbeit leiten und den Erfolg Ihrer Projekte sichern.</p>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
@@ -103,13 +103,13 @@ export default function About() {
|
||||
{ icon: ShieldCheck, title: 'Zuverlässigkeit', desc: 'Wir halten, was wir versprechen – ohne Ausnahme. Verbindlichkeit ist unser Fundament.' }
|
||||
].map((item, i) => (
|
||||
<Reveal key={i} delay={i * 0.1}>
|
||||
<div className="bg-white p-10 rounded-3xl border border-slate-100 shadow-sm hover:shadow-md hover:-translate-y-1 transition-[box-shadow,transform] duration-300 h-full motion-fix relative overflow-hidden group">
|
||||
<div className="bg-white/5 p-10 rounded-3xl border border-white/10 group hover:-translate-y-1 transition-[box-shadow,transform] duration-300 h-full motion-fix relative overflow-hidden">
|
||||
<div className="absolute top-0 left-0 w-full h-1 bg-accent/0 group-hover:bg-accent/50 transition-all duration-500" />
|
||||
<div className="text-accent mb-6">
|
||||
<item.icon size={32} />
|
||||
</div>
|
||||
<h4 className="text-xl font-bold text-primary mb-4">{i + 1}. {item.title}</h4>
|
||||
<p className="text-slate-600 leading-relaxed">{item.desc}</p>
|
||||
<h4 className="text-xl font-bold text-white mb-4">{i + 1}. {item.title}</h4>
|
||||
<p className="text-slate-400 leading-relaxed">{item.desc}</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
@@ -121,7 +121,7 @@ export default function About() {
|
||||
<section className="bg-white relative overflow-hidden">
|
||||
<TechBackground />
|
||||
<div className="container-custom relative z-10">
|
||||
<Counter value={4} className="section-number" />
|
||||
<div className="section-number">04</div>
|
||||
<Reveal>
|
||||
<div className="relative rounded-[2.5rem] bg-slate-900 p-12 md:p-24 overflow-hidden group">
|
||||
<div className="tech-corner top-8 left-8 border-t-2 border-l-2" />
|
||||
@@ -133,10 +133,9 @@ export default function About() {
|
||||
<p className="text-slate-400 text-xl mb-12">
|
||||
Lassen Sie uns gemeinsam die optimale Lösung für Ihre Energieinfrastruktur finden.
|
||||
</p>
|
||||
<Link href="/kontakt" className="btn-accent !px-10 !py-5 text-lg group">
|
||||
<Button href="/kontakt" variant="accent" showArrow className="!px-10 !py-5 text-lg">
|
||||
Jetzt Kontakt aufnehmen
|
||||
<ArrowRight className="ml-3 transition-transform group-hover:translate-x-2" size={24} />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
78
components/Button.tsx
Normal file
78
components/Button.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import Link from 'next/link';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
interface ButtonProps {
|
||||
children: React.ReactNode;
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
variant?: 'primary' | 'accent' | 'outline' | 'ghost';
|
||||
className?: string;
|
||||
showArrow?: boolean;
|
||||
type?: 'button' | 'submit' | 'reset';
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const Button = ({
|
||||
children,
|
||||
href,
|
||||
onClick,
|
||||
variant = 'primary',
|
||||
className = '',
|
||||
showArrow = false,
|
||||
type = 'button',
|
||||
disabled = false
|
||||
}: ButtonProps) => {
|
||||
const baseStyles = "inline-flex items-center justify-center px-8 py-4 rounded-xl font-bold uppercase tracking-widest text-xs transition-all duration-300 relative overflow-hidden group disabled:opacity-50 disabled:cursor-not-allowed";
|
||||
|
||||
const variants = {
|
||||
primary: "bg-primary text-white hover:bg-primary-light hover:shadow-[0_0_20px_rgba(15,23,42,0.3)]",
|
||||
accent: "bg-accent text-white hover:bg-accent-hover hover:shadow-[0_0_20px_rgba(16,185,129,0.3)]",
|
||||
outline: "border-2 border-primary text-primary hover:bg-primary hover:text-white",
|
||||
ghost: "bg-slate-100 text-primary hover:bg-slate-200"
|
||||
};
|
||||
|
||||
const content = (
|
||||
<>
|
||||
<span className="relative z-10 flex items-center gap-2">
|
||||
{children}
|
||||
{showArrow && (
|
||||
<motion.span
|
||||
animate={{ x: [0, 4, 0] }}
|
||||
transition={{ duration: 1.5, repeat: Infinity, ease: "easeInOut" }}
|
||||
>
|
||||
<ArrowRight size={16} strokeWidth={3} />
|
||||
</motion.span>
|
||||
)}
|
||||
</span>
|
||||
<motion.div
|
||||
initial={{ x: '-100%' }}
|
||||
whileHover={{ x: '100%' }}
|
||||
transition={{ duration: 0.6, ease: "easeInOut" }}
|
||||
className="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent skew-x-12 pointer-events-none"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<Link href={href} className={`${baseStyles} ${variants[variant]} ${className}`}>
|
||||
{content}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type={type}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
className={`${baseStyles} ${variants[variant]} ${className}`}
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client';
|
||||
|
||||
import { CheckCircle, Mail, MapPin, Send, ArrowRight } from 'lucide-react';
|
||||
import { CheckCircle, Mail, MapPin, Send } from 'lucide-react';
|
||||
import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Reveal } from './Reveal';
|
||||
import { TechBackground } from './TechBackground';
|
||||
import { Counter } from './Counter';
|
||||
import { Button } from './Button';
|
||||
|
||||
export default function Contact() {
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
@@ -51,7 +51,7 @@ export default function Contact() {
|
||||
|
||||
<div className="container-custom relative z-10">
|
||||
<div className="text-left relative">
|
||||
<Counter value={1} className="section-number" />
|
||||
<div className="section-number">01</div>
|
||||
<Reveal delay={0.1}>
|
||||
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">Kontakt</span>
|
||||
</Reveal>
|
||||
@@ -69,20 +69,20 @@ export default function Contact() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-slate-50 relative overflow-hidden">
|
||||
<section className="bg-slate-950 text-accent relative overflow-hidden">
|
||||
<TechBackground />
|
||||
<div className="container-custom relative z-10">
|
||||
<Counter value={2} className="section-number" />
|
||||
<Counter value={2} className="section-number !text-white/5" />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 md:gap-24">
|
||||
<div className="space-y-8">
|
||||
<Reveal delay={0.1}>
|
||||
<div className="card-modern !p-8 flex gap-6 items-start hover:translate-x-1 transition-transform duration-300 relative overflow-hidden tech-card-border">
|
||||
<div className="bg-white/5 p-8 rounded-2xl border border-white/10 flex gap-6 items-start hover:translate-x-1 transition-transform duration-300 relative overflow-hidden">
|
||||
<div className="w-14 h-14 rounded-2xl bg-accent/10 text-accent flex items-center justify-center shrink-0 relative z-10">
|
||||
<Mail size={24} />
|
||||
</div>
|
||||
<div className="relative z-10">
|
||||
<h4 className="text-slate-500 font-bold text-xs uppercase tracking-widest mb-2">E-Mail</h4>
|
||||
<a href="mailto:info@mb-grid-solutions.com" className="text-primary text-xl font-bold hover:text-accent transition-colors">
|
||||
<h4 className="text-slate-400 font-bold text-xs uppercase tracking-widest mb-2">E-Mail</h4>
|
||||
<a href="mailto:info@mb-grid-solutions.com" className="text-white text-xl font-bold hover:text-accent transition-colors">
|
||||
info@mb-grid-solutions.com
|
||||
</a>
|
||||
</div>
|
||||
@@ -90,13 +90,13 @@ export default function Contact() {
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.2}>
|
||||
<div className="card-modern !p-8 flex gap-6 items-start hover:translate-x-1 transition-transform duration-300 relative overflow-hidden tech-card-border">
|
||||
<div className="bg-white/5 p-8 rounded-2xl border border-white/10 flex gap-6 items-start hover:translate-x-1 transition-transform duration-300 relative overflow-hidden">
|
||||
<div className="w-14 h-14 rounded-2xl bg-accent/10 text-accent flex items-center justify-center shrink-0 relative z-10">
|
||||
<MapPin size={24} />
|
||||
</div>
|
||||
<div className="relative z-10">
|
||||
<h4 className="text-slate-500 font-bold text-xs uppercase tracking-widest mb-2">Anschrift</h4>
|
||||
<p className="text-primary text-xl font-bold leading-relaxed">
|
||||
<h4 className="text-slate-400 font-bold text-xs uppercase tracking-widest mb-2">Anschrift</h4>
|
||||
<p className="text-white text-xl font-bold leading-relaxed">
|
||||
MB Grid Solutions GmbH<br />
|
||||
Raiffeisenstraße 22<br />
|
||||
73630 Remshalden
|
||||
@@ -106,7 +106,7 @@ export default function Contact() {
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.3}>
|
||||
<div className="w-full h-[300px] rounded-[2.5rem] overflow-hidden border border-slate-100 shadow-sm grayscale hover:grayscale-0 transition-all duration-700 relative group">
|
||||
<div className="w-full h-[300px] rounded-[2.5rem] overflow-hidden border border-white/10 shadow-sm grayscale hover:grayscale-0 transition-all duration-700 relative group">
|
||||
<div className="absolute inset-0 border-2 border-accent/0 group-hover:border-accent/20 transition-all duration-500 z-10 pointer-events-none rounded-[2.5rem]" />
|
||||
<iframe
|
||||
width="100%"
|
||||
@@ -135,12 +135,9 @@ export default function Contact() {
|
||||
<p className="text-slate-600 text-lg mb-10">
|
||||
Vielen Dank für Ihre Anfrage. Wir werden uns in Kürze bei Ihnen melden.
|
||||
</p>
|
||||
<button
|
||||
onClick={() => setSubmitted(false)}
|
||||
className="btn-primary"
|
||||
>
|
||||
<Button onClick={() => setSubmitted(false)}>
|
||||
Weitere Nachricht
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6 relative z-10">
|
||||
@@ -192,20 +189,15 @@ export default function Contact() {
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading}
|
||||
className="btn-accent w-full py-5 text-lg group"
|
||||
>
|
||||
<Button type="submit" variant="accent" disabled={loading} className="w-full py-5 text-lg" showArrow>
|
||||
{loading ? 'Wird gesendet...' : 'Nachricht senden'}
|
||||
<Send className="ml-3 transition-transform group-hover:translate-x-1 group-hover:-translate-y-1" size={20} />
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
<p className="text-xs text-slate-400 text-center">
|
||||
* Pflichtfelder. Mit dem Absenden erklären Sie sich mit unserer{' '}
|
||||
<Link href="/datenschutz" className="text-accent hover:underline font-semibold">
|
||||
<a href="/datenschutz" className="text-accent hover:underline font-semibold">
|
||||
Datenschutzerklärung
|
||||
</Link>{' '}
|
||||
</a>{' '}
|
||||
einverstanden.
|
||||
</p>
|
||||
</form>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { ArrowRight, Shield, Zap, BarChart3, CheckCircle2, ChevronRight } from 'lucide-react';
|
||||
import { Shield, Zap, BarChart3, CheckCircle2, ChevronRight } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Reveal, Stagger } from './Reveal';
|
||||
import { TechBackground } from './TechBackground';
|
||||
import { Counter } from './Counter';
|
||||
import { Button } from './Button';
|
||||
import { TileGrid } from './TileGrid';
|
||||
|
||||
export default function Home() {
|
||||
const serviceJsonLd = {
|
||||
@@ -62,6 +64,7 @@ export default function Home() {
|
||||
style={{ backgroundImage: 'url("/media/business/iStock-1068752548.jpg")' }}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-white via-white/95 to-white/40 md:to-transparent" />
|
||||
<TileGrid />
|
||||
<TechBackground />
|
||||
</div>
|
||||
|
||||
@@ -92,13 +95,12 @@ export default function Home() {
|
||||
|
||||
<Reveal delay={0.4}>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Link href="/kontakt" className="btn-accent group">
|
||||
Projekt anfragen
|
||||
<ArrowRight className="ml-2 transition-transform group-hover:translate-x-1" size={20} />
|
||||
</Link>
|
||||
<Link href="/ueber-uns" className="btn-primary bg-slate-100 !text-primary hover:bg-slate-200">
|
||||
<Button href="/kontakt" variant="accent" showArrow>
|
||||
Projekt anfragen
|
||||
</Button>
|
||||
<Button href="/ueber-uns" variant="ghost">
|
||||
Mehr erfahren
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
@@ -106,19 +108,19 @@ export default function Home() {
|
||||
</section>
|
||||
|
||||
{/* Portfolio Section */}
|
||||
<section className="bg-slate-50 relative overflow-hidden">
|
||||
<section className="bg-slate-950 text-accent relative overflow-hidden">
|
||||
<TechBackground />
|
||||
<div className="container-custom relative z-10">
|
||||
<Counter value={2} className="section-number" />
|
||||
<Counter value={2} className="section-number !text-white/5" />
|
||||
<Reveal className="flex flex-col md:flex-row md:items-end justify-between gap-8 mb-16">
|
||||
<div>
|
||||
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">Portfolio</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-primary mb-6">Unsere Leistungen</h2>
|
||||
<p className="text-slate-600 text-lg md:text-xl">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-white mb-6">Unsere Leistungen</h2>
|
||||
<p className="text-slate-400 text-lg md:text-xl">
|
||||
Beratung durch unabhängige Experten mit jahrzehntelanger Erfahrung aus Engineering, Normengremien, Planung und Produktion.
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/ueber-uns" className="text-primary font-bold flex items-center gap-2 hover:text-accent transition-colors group">
|
||||
<Link href="/ueber-uns" className="text-accent font-bold flex items-center gap-2 hover:text-white transition-colors group">
|
||||
Alle Details ansehen <ChevronRight className="transition-transform group-hover:translate-x-1" size={20} />
|
||||
</Link>
|
||||
</Reveal>
|
||||
@@ -142,13 +144,13 @@ export default function Home() {
|
||||
}
|
||||
].map((item, i) => (
|
||||
<Reveal key={i} delay={i * 0.1}>
|
||||
<div className="card-modern group hover:-translate-y-2 transition-[box-shadow,transform] duration-300 h-full relative overflow-hidden tech-card-border">
|
||||
<div className="bg-white/5 p-8 rounded-2xl border border-white/10 group hover:-translate-y-2 transition-[box-shadow,transform] duration-300 h-full relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-16 h-16 bg-accent/5 -mr-8 -mt-8 rounded-full group-hover:bg-accent/10 transition-colors" />
|
||||
<div className="w-16 h-16 rounded-2xl bg-accent/10 text-accent flex items-center justify-center mb-8 group-hover:bg-accent group-hover:text-white transition-colors relative z-10">
|
||||
{item.icon}
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-primary mb-4 relative z-10">{item.title}</h3>
|
||||
<p className="text-slate-600 leading-relaxed relative z-10">
|
||||
<h3 className="text-2xl font-bold text-white mb-4 relative z-10">{item.title}</h3>
|
||||
<p className="text-slate-400 leading-relaxed relative z-10">
|
||||
{item.desc}
|
||||
</p>
|
||||
</div>
|
||||
@@ -276,9 +278,21 @@ export default function Home() {
|
||||
|
||||
<div className="absolute top-0 right-0 w-1/2 h-full opacity-10 pointer-events-none">
|
||||
<svg viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="400" cy="0" r="400" stroke="white" strokeWidth="2" />
|
||||
<circle cx="400" cy="0" r="300" stroke="white" strokeWidth="2" />
|
||||
<circle cx="400" cy="0" r="200" stroke="white" strokeWidth="2" />
|
||||
<motion.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"
|
||||
/>
|
||||
<motion.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"
|
||||
/>
|
||||
<motion.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"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
@@ -289,10 +303,9 @@ export default function Home() {
|
||||
<p className="text-slate-300 text-xl mb-12 leading-relaxed">
|
||||
Lassen Sie uns gemeinsam die optimale Lösung für Ihre Energieinfrastruktur finden. Wir beraten Sie herstellerneutral und kompetent.
|
||||
</p>
|
||||
<Link href="/kontakt" className="btn-accent !px-10 !py-5 text-lg group">
|
||||
<Button href="/kontakt" variant="accent" showArrow className="!px-10 !py-5 text-lg">
|
||||
Jetzt Kontakt aufnehmen
|
||||
<ArrowRight className="ml-3 transition-transform group-hover:translate-x-2" size={24} />
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
@@ -148,8 +148,26 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
|
||||
</button>
|
||||
|
||||
<Reveal fullWidth>
|
||||
<footer className="bg-slate-900 text-slate-300 py-16 md:py-24">
|
||||
<div className="container-custom">
|
||||
<footer className="bg-slate-900 text-slate-300 py-16 md:py-24 relative overflow-hidden group">
|
||||
<div className="absolute inset-0 grid-pattern opacity-[0.08] pointer-events-none" />
|
||||
|
||||
{/* Animated Tech Lines */}
|
||||
<motion.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
|
||||
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"
|
||||
/>
|
||||
|
||||
{/* 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" />
|
||||
<div className="tech-corner bottom-8 right-8 border-b border-r border-white/10 group-hover:border-accent/30 transition-colors duration-700" />
|
||||
|
||||
<div className="container-custom relative z-10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12 mb-16">
|
||||
<div className="lg:col-span-2">
|
||||
<Link href="/" className="inline-block mb-8 group">
|
||||
@@ -190,9 +208,14 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-8 border-t border-slate-800 flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-slate-500">
|
||||
<div className="pt-8 border-t border-slate-800 flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-slate-500 relative">
|
||||
<div className="absolute -top-px left-0 w-12 h-px bg-accent/50" />
|
||||
<p>© {new Date().getFullYear()} MB Grid Solutions GmbH. Alle Rechte vorbehalten.</p>
|
||||
<p className="flex items-center gap-2">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-accent opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-2 w-2 bg-accent"></span>
|
||||
</span>
|
||||
Made with <span className="text-accent">precision</span> in Germany
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,91 +1,21 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import React from 'react';
|
||||
|
||||
export const TechBackground = () => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return (
|
||||
<div className="absolute inset-0 pointer-events-none overflow-hidden z-0">
|
||||
<div className="absolute inset-0 grid-pattern opacity-[0.15]" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 pointer-events-none overflow-hidden z-0">
|
||||
<div className="absolute inset-0 grid-pattern opacity-[0.15]" />
|
||||
|
||||
{/* Animated Tech Lines */}
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<motion.div
|
||||
key={`line-${i}`}
|
||||
initial={{ x: '-100%', opacity: 0 }}
|
||||
animate={{ x: '100%', opacity: [0, 0.4, 0] }}
|
||||
transition={{
|
||||
duration: 8 + i * 2,
|
||||
repeat: Infinity,
|
||||
ease: "linear",
|
||||
delay: i * 2
|
||||
}}
|
||||
className="absolute h-[2px] bg-gradient-to-r from-transparent via-accent/40 to-transparent w-full"
|
||||
style={{ top: `${20 * (i + 1)}%` }}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Floating Tech Squares */}
|
||||
{[...Array(8)].map((_, i) => (
|
||||
<motion.div
|
||||
key={`square-${i}`}
|
||||
initial={{ opacity: 0, scale: 0 }}
|
||||
animate={{
|
||||
opacity: [0, 0.2, 0],
|
||||
scale: [0, 1, 0],
|
||||
rotate: [0, 90, 180],
|
||||
x: [0, Math.random() * 200 - 100, 0],
|
||||
y: [0, Math.random() * 200 - 100, 0]
|
||||
}}
|
||||
transition={{
|
||||
duration: 8 + Math.random() * 4,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: i * 2
|
||||
}}
|
||||
className="absolute w-8 h-8 border border-accent/10 rounded-sm"
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Pulsing Dots */}
|
||||
{[...Array(15)].map((_, i) => (
|
||||
<motion.div
|
||||
key={`dot-${i}`}
|
||||
animate={{
|
||||
opacity: [0.1, 0.4, 0.1],
|
||||
scale: [1, 1.5, 1]
|
||||
}}
|
||||
transition={{
|
||||
duration: 3 + Math.random() * 2,
|
||||
repeat: Infinity,
|
||||
ease: "easeInOut",
|
||||
delay: i * 0.5
|
||||
}}
|
||||
className="tech-dot"
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{/* Very subtle large grid */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.05]"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(to right, var(--color-accent) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, var(--color-accent) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '120px 120px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
38
components/TileGrid.tsx
Normal file
38
components/TileGrid.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export const TileGrid = () => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
if (!mounted) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 pointer-events-none overflow-hidden z-[5]">
|
||||
{/* The lighting tiles (actual squares) */}
|
||||
<div className="absolute inset-0 grid grid-cols-8 md:grid-cols-12 grid-rows-8 md:grid-rows-12">
|
||||
{[...Array(144)].map((_, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{
|
||||
opacity: [0, Math.random() > 0.92 ? 0.4 : 0, 0],
|
||||
}}
|
||||
transition={{
|
||||
duration: 3 + Math.random() * 4,
|
||||
repeat: Infinity,
|
||||
delay: Math.random() * 10,
|
||||
ease: "easeInOut"
|
||||
}}
|
||||
className="w-full h-full bg-accent/20 border border-accent/5"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user