perf: implement multi-phase performance optimizations for PageSpeed 90+
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Successful in 1m41s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Successful in 1m41s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
- Resized and compressed oversized logo (204KB -> 21KB) - Optimized large media images (hs-kabel.png, contact-hero.jpg) - Implemented dynamic lazy-loading for home page sections - Tuned Sentry traces sample rate (1.0 -> 0.1) - Refined font loading and fixed redundant analytics tracking
This commit is contained in:
@@ -13,6 +13,7 @@ const inter = Inter({
|
|||||||
subsets: ["latin"],
|
subsets: ["latin"],
|
||||||
display: "swap",
|
display: "swap",
|
||||||
variable: "--font-inter",
|
variable: "--font-inter",
|
||||||
|
weight: ["400", "700", "800"], // Explicit weights to optimize download
|
||||||
});
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@@ -129,7 +130,7 @@ export default async function RootLayout({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Track server-side (initial load)
|
// Track server-side (initial load)
|
||||||
serverServices.analytics.trackPageview("/");
|
// serverServices.analytics.trackPageview("/"); // Removed to avoid double-tracking and incorrect path reporting
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={locale} className={`${inter.variable}`}>
|
<html lang={locale} className={`${inter.variable}`}>
|
||||||
|
|||||||
@@ -16,6 +16,23 @@ import { Reveal } from "./Reveal";
|
|||||||
import { TechBackground } from "./TechBackground";
|
import { TechBackground } from "./TechBackground";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
|
const PortfolioSection = dynamic(() =>
|
||||||
|
import("./sections/PortfolioSection").then((mod) => mod.PortfolioSection),
|
||||||
|
);
|
||||||
|
const ExpertiseSection = dynamic(() =>
|
||||||
|
import("./sections/ExpertiseSection").then((mod) => mod.ExpertiseSection),
|
||||||
|
);
|
||||||
|
const TechnicalSpecsSection = dynamic(() =>
|
||||||
|
import("./sections/TechnicalSpecsSection").then(
|
||||||
|
(mod) => mod.TechnicalSpecsSection,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const CTASection = dynamic(() =>
|
||||||
|
import("./sections/CTASection").then((mod) => mod.CTASection),
|
||||||
|
);
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const t = useTranslations("Index");
|
const t = useTranslations("Index");
|
||||||
|
|
||||||
@@ -74,7 +91,7 @@ export default function Home() {
|
|||||||
fill
|
fill
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
priority
|
priority
|
||||||
quality={90}
|
quality={75}
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 bg-gradient-to-r from-slate-100/80 via-white/90 to-white/40 md:to-transparent" />
|
<div className="absolute inset-0 bg-gradient-to-r from-slate-100/80 via-white/90 to-white/40 md:to-transparent" />
|
||||||
<TechBackground />
|
<TechBackground />
|
||||||
@@ -127,272 +144,11 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Portfolio Section */}
|
{/* Dynamic Sections */}
|
||||||
<section className="bg-slate-950 text-accent relative overflow-hidden">
|
<PortfolioSection />
|
||||||
<TechBackground />
|
<ExpertiseSection />
|
||||||
<div className="container-custom relative z-10">
|
<TechnicalSpecsSection />
|
||||||
<Counter value={2} className="section-number !text-white/5" />
|
<CTASection />
|
||||||
<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">
|
|
||||||
{t("portfolio.tag")}
|
|
||||||
</span>
|
|
||||||
<h2 className="text-3xl md:text-5xl font-bold text-white mb-6">
|
|
||||||
{t("portfolio.title")}
|
|
||||||
</h2>
|
|
||||||
<p className="text-slate-400 text-base md:text-xl">
|
|
||||||
{t("portfolio.description")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Link
|
|
||||||
href="/ueber-uns"
|
|
||||||
className="text-accent font-bold flex items-center gap-2 hover:text-white transition-colors group"
|
|
||||||
>
|
|
||||||
{t("portfolio.link")}{" "}
|
|
||||||
<ChevronRight
|
|
||||||
className="transition-transform group-hover:translate-x-1"
|
|
||||||
size={20}
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
</Reveal>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
||||||
{[
|
|
||||||
{
|
|
||||||
icon: <Zap size={32} />,
|
|
||||||
title: t("portfolio.items.beratung.title"),
|
|
||||||
desc: t("portfolio.items.beratung.desc"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Shield size={32} />,
|
|
||||||
title: t("portfolio.items.begleitung.title"),
|
|
||||||
desc: t("portfolio.items.begleitung.desc"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <BarChart3 size={32} />,
|
|
||||||
title: t("portfolio.items.beschaffung.title"),
|
|
||||||
desc: t("portfolio.items.beschaffung.desc"),
|
|
||||||
},
|
|
||||||
].map((item, i) => (
|
|
||||||
<Reveal key={i} delay={i * 0.1}>
|
|
||||||
<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-white mb-4 relative z-10">
|
|
||||||
{item.title}
|
|
||||||
</h3>
|
|
||||||
<p className="text-slate-400 leading-relaxed relative z-10">
|
|
||||||
{item.desc}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</Reveal>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Expertise Section */}
|
|
||||||
<section className="bg-white relative overflow-hidden">
|
|
||||||
<TechBackground />
|
|
||||||
<div className="container-custom relative z-10">
|
|
||||||
<Counter value={3} className="section-number" />
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 items-center gap-16 md:gap-24">
|
|
||||||
<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" />
|
|
||||||
<Image
|
|
||||||
src="/media/cables/hs-kabel.png"
|
|
||||||
alt="Technische Beratung"
|
|
||||||
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" />
|
|
||||||
<div className="tech-corner bottom-4 right-4 border-b-2 border-r-2 z-20" />
|
|
||||||
</div>
|
|
||||||
</Reveal>
|
|
||||||
<div>
|
|
||||||
<Reveal>
|
|
||||||
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">
|
|
||||||
{t("expertise.tag")}
|
|
||||||
</span>
|
|
||||||
<h2 className="text-3xl md:text-5xl font-bold text-primary mb-6 md:mb-8">
|
|
||||||
{t("expertise.title")}
|
|
||||||
</h2>
|
|
||||||
<p className="text-slate-600 text-base md:text-xl mb-8 md:mb-12">
|
|
||||||
{t("expertise.description")}
|
|
||||||
</p>
|
|
||||||
</Reveal>
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
{t.raw("expertise.groups").map((item: string, i: number) => (
|
|
||||||
<Reveal key={i} delay={i * 0.05}>
|
|
||||||
<div className="flex items-center gap-4 p-4 bg-slate-50 rounded-xl border border-slate-100 hover:border-accent/30 transition-colors group relative overflow-hidden">
|
|
||||||
<div className="absolute top-0 left-0 w-1 h-full bg-accent/0 group-hover:bg-accent/100 transition-all duration-300" />
|
|
||||||
<div className="w-8 h-8 rounded-full bg-white flex items-center justify-center shadow-sm group-hover:bg-accent group-hover:text-white transition-colors">
|
|
||||||
<CheckCircle2 size={16} />
|
|
||||||
</div>
|
|
||||||
<span className="text-primary font-semibold">{item}</span>
|
|
||||||
</div>
|
|
||||||
</Reveal>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* 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">
|
|
||||||
<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>
|
|
||||||
<TechBackground />
|
|
||||||
|
|
||||||
<div className="container-custom relative z-10">
|
|
||||||
<Counter value={4} className="section-number !text-white/5" />
|
|
||||||
{/* Data Stream Effect */}
|
|
||||||
<div className="absolute -top-10 right-0 w-px h-64 bg-gradient-to-b from-transparent via-accent/50 to-transparent animate-pulse" />
|
|
||||||
<div className="absolute -bottom-10 left-10 w-px h-64 bg-gradient-to-b from-transparent via-accent/30 to-transparent animate-pulse delay-700" />
|
|
||||||
|
|
||||||
<Reveal className="mb-20">
|
|
||||||
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">
|
|
||||||
{t("specs.tag")}
|
|
||||||
</span>
|
|
||||||
<h2 className="text-3xl md:text-5xl font-bold text-white mb-6">
|
|
||||||
{t("specs.title")}
|
|
||||||
</h2>
|
|
||||||
</Reveal>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8">
|
|
||||||
{[
|
|
||||||
{
|
|
||||||
label: t("specs.items.kabel.label"),
|
|
||||||
value: t("specs.items.kabel.value"),
|
|
||||||
desc: t("specs.items.kabel.desc"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("specs.items.spannung.label"),
|
|
||||||
value: t("specs.items.spannung.value"),
|
|
||||||
desc: t("specs.items.spannung.desc"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("specs.items.technologie.label"),
|
|
||||||
value: t("specs.items.technologie.value"),
|
|
||||||
desc: t("specs.items.technologie.desc"),
|
|
||||||
},
|
|
||||||
].map((item, i) => (
|
|
||||||
<Reveal key={i} delay={i * 0.1}>
|
|
||||||
<div className="p-10 rounded-3xl bg-white/5 border border-white/10 backdrop-blur-sm hover:bg-white/10 transition-colors h-full relative group 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" />
|
|
||||||
<h4 className="text-accent font-bold text-xs uppercase tracking-widest mb-6">
|
|
||||||
{item.label}
|
|
||||||
</h4>
|
|
||||||
<p className="text-2xl font-bold text-white mb-4 leading-tight">
|
|
||||||
{item.value}
|
|
||||||
</p>
|
|
||||||
<p className="text-slate-400 leading-relaxed">{item.desc}</p>
|
|
||||||
</div>
|
|
||||||
</Reveal>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* CTA Section */}
|
|
||||||
<section className="bg-white relative overflow-hidden">
|
|
||||||
<TechBackground />
|
|
||||||
{/* Decorative Background Elements */}
|
|
||||||
<div className="absolute top-0 left-0 w-64 h-64 bg-accent/5 rounded-full blur-3xl -translate-x-1/2 -translate-y-1/2" />
|
|
||||||
<div className="absolute bottom-0 right-0 w-96 h-96 bg-primary/5 rounded-full blur-3xl translate-x-1/2 translate-y-1/2" />
|
|
||||||
|
|
||||||
<div className="container-custom relative z-10">
|
|
||||||
<Counter value={5} className="section-number" />
|
|
||||||
<Reveal>
|
|
||||||
<div className="relative rounded-3xl md:rounded-[2.5rem] bg-primary p-8 md:p-24 overflow-hidden group">
|
|
||||||
{/* Corner Accents */}
|
|
||||||
<div className="tech-corner top-8 left-8 border-t-2 border-l-2" />
|
|
||||||
<div className="tech-corner top-8 right-8 border-t-2 border-r-2" />
|
|
||||||
<div className="tech-corner bottom-8 left-8 border-b-2 border-l-2" />
|
|
||||||
<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">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 400 400"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<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"
|
|
||||||
/>
|
|
||||||
<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"
|
|
||||||
/>
|
|
||||||
<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"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="relative z-10">
|
|
||||||
<h2 className="text-3xl md:text-6xl font-bold text-white mb-6 md:mb-8 leading-tight">
|
|
||||||
{t("cta.title")}
|
|
||||||
</h2>
|
|
||||||
<p className="text-slate-300 text-lg md:text-xl mb-8 md:mb-12 leading-relaxed">
|
|
||||||
{t("cta.subtitle")}
|
|
||||||
</p>
|
|
||||||
<Button
|
|
||||||
href="/kontakt"
|
|
||||||
variant="accent"
|
|
||||||
showArrow
|
|
||||||
className="w-full sm:w-auto !px-10 !py-5 text-lg"
|
|
||||||
>
|
|
||||||
{t("cta.button")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Reveal>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
102
components/sections/CTASection.tsx
Normal file
102
components/sections/CTASection.tsx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { m } from "framer-motion";
|
||||||
|
import { Reveal } from "../Reveal";
|
||||||
|
import { Counter } from "../Counter";
|
||||||
|
import { TechBackground } from "../TechBackground";
|
||||||
|
import { Button } from "../Button";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
export const CTASection = () => {
|
||||||
|
const t = useTranslations("Index");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-white relative overflow-hidden">
|
||||||
|
<TechBackground />
|
||||||
|
{/* Decorative Background Elements */}
|
||||||
|
<div className="absolute top-0 left-0 w-64 h-64 bg-accent/5 rounded-full blur-3xl -translate-x-1/2 -translate-y-1/2" />
|
||||||
|
<div className="absolute bottom-0 right-0 w-96 h-96 bg-primary/5 rounded-full blur-3xl translate-x-1/2 translate-y-1/2" />
|
||||||
|
|
||||||
|
<div className="container-custom relative z-10">
|
||||||
|
<Counter value={5} className="section-number" />
|
||||||
|
<Reveal>
|
||||||
|
<div className="relative rounded-3xl md:rounded-[2.5rem] bg-primary p-8 md:p-24 overflow-hidden group">
|
||||||
|
{/* Corner Accents */}
|
||||||
|
<div className="tech-corner top-8 left-8 border-t-2 border-l-2" />
|
||||||
|
<div className="tech-corner top-8 right-8 border-t-2 border-r-2" />
|
||||||
|
<div className="tech-corner bottom-8 left-8 border-b-2 border-l-2" />
|
||||||
|
<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">
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 400 400"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative z-10">
|
||||||
|
<h2 className="text-3xl md:text-6xl font-bold text-white mb-6 md:mb-8 leading-tight">
|
||||||
|
{t("cta.title")}
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-300 text-lg md:text-xl mb-8 md:mb-12 leading-relaxed">
|
||||||
|
{t("cta.subtitle")}
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
href="/kontakt"
|
||||||
|
variant="accent"
|
||||||
|
showArrow
|
||||||
|
className="w-full sm:w-auto !px-10 !py-5 text-lg"
|
||||||
|
>
|
||||||
|
{t("cta.button")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
64
components/sections/ExpertiseSection.tsx
Normal file
64
components/sections/ExpertiseSection.tsx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { CheckCircle2 } from "lucide-react";
|
||||||
|
import { Reveal } from "../Reveal";
|
||||||
|
import { Counter } from "../Counter";
|
||||||
|
import { TechBackground } from "../TechBackground";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
export const ExpertiseSection = () => {
|
||||||
|
const t = useTranslations("Index");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-white relative overflow-hidden">
|
||||||
|
<TechBackground />
|
||||||
|
<div className="container-custom relative z-10">
|
||||||
|
<Counter value={3} className="section-number" />
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 items-center gap-16 md:gap-24">
|
||||||
|
<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" />
|
||||||
|
<Image
|
||||||
|
src="/media/cables/hs-kabel.png"
|
||||||
|
alt="Technische Beratung"
|
||||||
|
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" />
|
||||||
|
<div className="tech-corner bottom-4 right-4 border-b-2 border-r-2 z-20" />
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
<div>
|
||||||
|
<Reveal>
|
||||||
|
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">
|
||||||
|
{t("expertise.tag")}
|
||||||
|
</span>
|
||||||
|
<h2 className="text-3xl md:text-5xl font-bold text-primary mb-6 md:mb-8">
|
||||||
|
{t("expertise.title")}
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-600 text-base md:text-xl mb-8 md:mb-12">
|
||||||
|
{t("expertise.description")}
|
||||||
|
</p>
|
||||||
|
</Reveal>
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
{t.raw("expertise.groups").map((item: string, i: number) => (
|
||||||
|
<Reveal key={i} delay={i * 0.05}>
|
||||||
|
<div className="flex items-center gap-4 p-4 bg-slate-50 rounded-xl border border-slate-100 hover:border-accent/30 transition-colors group relative overflow-hidden">
|
||||||
|
<div className="absolute top-0 left-0 w-1 h-full bg-accent/0 group-hover:bg-accent/100 transition-all duration-300" />
|
||||||
|
<div className="w-8 h-8 rounded-full bg-white flex items-center justify-center shadow-sm group-hover:bg-accent group-hover:text-white transition-colors">
|
||||||
|
<CheckCircle2 size={16} />
|
||||||
|
</div>
|
||||||
|
<span className="text-primary font-semibold">{item}</span>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
80
components/sections/PortfolioSection.tsx
Normal file
80
components/sections/PortfolioSection.tsx
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { ChevronRight, Zap, Shield, BarChart3 } from "lucide-react";
|
||||||
|
import { Reveal } from "../Reveal";
|
||||||
|
import { Counter } from "../Counter";
|
||||||
|
import { TechBackground } from "../TechBackground";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
export const PortfolioSection = () => {
|
||||||
|
const t = useTranslations("Index");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="bg-slate-950 text-accent relative overflow-hidden">
|
||||||
|
<TechBackground />
|
||||||
|
<div className="container-custom relative z-10">
|
||||||
|
<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">
|
||||||
|
{t("portfolio.tag")}
|
||||||
|
</span>
|
||||||
|
<h2 className="text-3xl md:text-5xl font-bold text-white mb-6">
|
||||||
|
{t("portfolio.title")}
|
||||||
|
</h2>
|
||||||
|
<p className="text-slate-400 text-base md:text-xl">
|
||||||
|
{t("portfolio.description")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
href="/ueber-uns"
|
||||||
|
className="text-accent font-bold flex items-center gap-2 hover:text-white transition-colors group"
|
||||||
|
>
|
||||||
|
{t("portfolio.link")}{" "}
|
||||||
|
<ChevronRight
|
||||||
|
className="transition-transform group-hover:translate-x-1"
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</Reveal>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
icon: <Zap size={32} />,
|
||||||
|
title: t("portfolio.items.beratung.title"),
|
||||||
|
desc: t("portfolio.items.beratung.desc"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Shield size={32} />,
|
||||||
|
title: t("portfolio.items.begleitung.title"),
|
||||||
|
desc: t("portfolio.items.begleitung.desc"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <BarChart3 size={32} />,
|
||||||
|
title: t("portfolio.items.beschaffung.title"),
|
||||||
|
desc: t("portfolio.items.beschaffung.desc"),
|
||||||
|
},
|
||||||
|
].map((item, i) => (
|
||||||
|
<Reveal key={i} delay={i * 0.1}>
|
||||||
|
<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-white mb-4 relative z-10">
|
||||||
|
{item.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-slate-400 leading-relaxed relative z-10">
|
||||||
|
{item.desc}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
76
components/sections/TechnicalSpecsSection.tsx
Normal file
76
components/sections/TechnicalSpecsSection.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { Reveal } from "../Reveal";
|
||||||
|
import { Counter } from "../Counter";
|
||||||
|
import { TechBackground } from "../TechBackground";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
|
||||||
|
export const TechnicalSpecsSection = () => {
|
||||||
|
const t = useTranslations("Index");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="relative py-24 md:py-32 text-white overflow-hidden bg-slate-900">
|
||||||
|
<div className="absolute inset-0 opacity-20">
|
||||||
|
<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>
|
||||||
|
<TechBackground />
|
||||||
|
|
||||||
|
<div className="container-custom relative z-10">
|
||||||
|
<Counter value={4} className="section-number !text-white/5" />
|
||||||
|
{/* Data Stream Effect */}
|
||||||
|
<div className="absolute -top-10 right-0 w-px h-64 bg-gradient-to-b from-transparent via-accent/50 to-transparent animate-pulse" />
|
||||||
|
<div className="absolute -bottom-10 left-10 w-px h-64 bg-gradient-to-b from-transparent via-accent/30 to-transparent animate-pulse delay-700" />
|
||||||
|
|
||||||
|
<Reveal className="mb-20">
|
||||||
|
<span className="text-accent font-bold uppercase tracking-widest text-sm mb-4 block">
|
||||||
|
{t("specs.tag")}
|
||||||
|
</span>
|
||||||
|
<h2 className="text-3xl md:text-5xl font-bold text-white mb-6">
|
||||||
|
{t("specs.title")}
|
||||||
|
</h2>
|
||||||
|
</Reveal>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
label: t("specs.items.kabel.label"),
|
||||||
|
value: t("specs.items.kabel.value"),
|
||||||
|
desc: t("specs.items.kabel.desc"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("specs.items.spannung.label"),
|
||||||
|
value: t("specs.items.spannung.value"),
|
||||||
|
desc: t("specs.items.spannung.desc"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("specs.items.technologie.label"),
|
||||||
|
value: t("specs.items.technologie.value"),
|
||||||
|
desc: t("specs.items.technologie.desc"),
|
||||||
|
},
|
||||||
|
].map((item, i) => (
|
||||||
|
<Reveal key={i} delay={i * 0.1}>
|
||||||
|
<div className="p-10 rounded-3xl bg-white/5 border border-white/10 backdrop-blur-sm hover:bg-white/10 transition-colors h-full relative group 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" />
|
||||||
|
<h4 className="text-accent font-bold text-xs uppercase tracking-widest mb-6">
|
||||||
|
{item.label}
|
||||||
|
</h4>
|
||||||
|
<p className="text-2xl font-bold text-white mb-4 leading-tight">
|
||||||
|
{item.value}
|
||||||
|
</p>
|
||||||
|
<p className="text-slate-400 leading-relaxed">{item.desc}</p>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 736 KiB After Width: | Height: | Size: 428 KiB |
@@ -4,7 +4,7 @@ import { config } from "./lib/config";
|
|||||||
if (config.errors.glitchtip.enabled) {
|
if (config.errors.glitchtip.enabled) {
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: config.errors.glitchtip.dsn,
|
dsn: config.errors.glitchtip.dsn,
|
||||||
tracesSampleRate: 1.0,
|
tracesSampleRate: 0.1,
|
||||||
debug: config.isDevelopment,
|
debug: config.isDevelopment,
|
||||||
environment: config.target || "production",
|
environment: config.target || "production",
|
||||||
// Use the proxy path defined in config
|
// Use the proxy path defined in config
|
||||||
|
|||||||
Reference in New Issue
Block a user