fix(web): correct relative imports in opengraph-image routes
Some checks failed
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🏗️ Build (push) Failing after 8m32s
Build & Deploy / 🔍 Prepare (push) Successful in 18s
Build & Deploy / 🧪 QA (push) Failing after 1m33s
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s

This commit is contained in:
2026-02-23 01:14:16 +01:00
parent 43564d1bba
commit 95a8b702fe
35 changed files with 387 additions and 366 deletions

View File

@@ -0,0 +1,23 @@
import { ImageResponse } from "next/og";
import { OGImageTemplate } from "../../../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../../../src/lib/og-helper";
export const size = OG_IMAGE_SIZE;
export const contentType = "image/png";
export const runtime = "nodejs";
export default async function Image() {
const fonts = await getOgFonts();
return new ImageResponse(
<OGImageTemplate
title="Über mich."
description="15 Jahre Erfahrung. Ein Ziel: Websites, die ihre Versprechen halten."
label="Marc Mintel"
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -0,0 +1,338 @@
"use client";
import Image from "next/image";
import { Section } from "@/src/components/Section";
import { Reveal } from "@/src/components/Reveal";
import {
ExperienceIllustration,
ResponsibilityIllustration,
ResultIllustration,
ContactIllustration,
HeroLines,
ParticleNetwork,
GridLines,
} from "@/src/components/Landing";
import { Signature } from "@/src/components/Signature";
import { Check } from "lucide-react";
import {
H1,
H3,
H4,
LeadText,
BodyText,
Label,
MonoLabel,
} from "@/src/components/Typography";
import { Card, Container } from "@/src/components/Layout";
import { Button } from "@/src/components/Button";
import { IconList, IconListItem } from "@/src/components/IconList";
import {
GradientMesh,
CodeSnippet,
AbstractCircuit,
} from "@/src/components/Effects";
import { getImgproxyUrl } from "@/src/utils/imgproxy";
import { Marker } from "@/src/components/Marker";
export default function AboutPage() {
return (
<div className="flex flex-col bg-white overflow-hidden relative">
{/* Background decoration removed per user request */}
{/* Hero Section */}
<section className="relative pt-12 md:pt-32 pb-8 md:pb-24 overflow-hidden border-b border-slate-50">
<Container variant="narrow" className="relative z-10">
<div className="flex flex-col items-center text-center space-y-6 md:space-y-12">
<Reveal width="fit-content">
<div className="relative">
{/* Structural rings around avatar */}
{/* Structural rings removed per user request */}
<div className="relative w-32 h-32 md:w-40 md:h-40 rounded-full overflow-hidden border border-slate-200 shadow-xl bg-white p-1 group">
<div className="w-full h-full rounded-full overflow-hidden relative aspect-square">
<img
src={getImgproxyUrl("/marc-mintel.png", {
width: 400,
height: 400,
resizing_type: "fill",
gravity: "sm",
})}
alt="Marc Mintel"
className="object-cover grayscale transition-all duration-1000 ease-in-out scale-110 group-hover:scale-100 group-hover:grayscale-0 w-full h-full"
/>
</div>
</div>
</div>
</Reveal>
<div className="space-y-3 md:space-y-6 max-w-3xl">
<Reveal delay={0.1}>
<div className="flex items-center justify-center gap-2 md:gap-4 mb-1 md:mb-4">
<div className="h-px w-6 md:w-8 bg-slate-900"></div>
<MonoLabel className="text-slate-900 text-[10px] md:text-sm">
Digital Architect
</MonoLabel>
<div className="h-px w-6 md:w-8 bg-slate-900"></div>
</div>
</Reveal>
<Reveal delay={0.2}>
<H1 className="text-4xl md:text-8xl leading-none tracking-tighter">
Über <span className="text-slate-400">mich.</span>
</H1>
</Reveal>
<Reveal delay={0.3}>
<p className="text-slate-400 font-medium max-w-xl mx-auto text-sm md:text-xl">
15 Jahre Erfahrung. Ein Ziel: Websites, die ihre Versprechen
halten.
</p>
</Reveal>
</div>
</div>
</Container>
{/* Connector to first section */}
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-px h-12 md:h-16 bg-gradient-to-b from-transparent to-slate-200" />
</section>
{/* Section 01: Story */}
<Section
number="01"
title="Erfahrung"
borderTop
illustration={<ExperienceIllustration className="w-24 h-24" />}
>
<div className="space-y-8 md:space-y-12">
<Reveal>
<H3 className="text-2xl md:text-5xl leading-tight max-w-3xl">
Vom Designer <br />
<span className="text-slate-400">zum Architekten.</span>
</H3>
</Reveal>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12">
<Reveal delay={0.1}>
<div className="space-y-6 md:space-y-8">
<LeadText className="text-xl md:text-2xl text-slate-400">
Agenturen, Konzerne, Startups ich habe die Branche von allen
Seiten kennengelernt. Was hängen geblieben ist:{" "}
<span className="text-slate-900">
<Marker delay={0.2}>Ergebnisse</Marker> zählen. Nicht der
Weg dorthin.
</span>
</LeadText>
<IconList className="space-y-4">
{[
"Frontend, Backend, Infrastruktur Fullstack",
"Komplexe Systeme auf das Wesentliche reduziert",
"Performance-Probleme systematisch gelöst",
].map((item, i) => (
<IconListItem key={i} bullet>
<BodyText className="text-lg">{item}</BodyText>
</IconListItem>
))}
</IconList>
</div>
</Reveal>
<Reveal delay={0.2}>
<Card
variant="gray"
hover={false}
padding="normal"
className="group"
>
<H4 className="text-xl mb-6">
Heute: Direkte Zusammenarbeit ohne Reibungsverluste.
</H4>
<div className="flex flex-wrap gap-3">
{["Effizient", "Pragmatisch", "Verlässlich"].map((tag, i) => (
<span
key={i}
className="px-4 py-2 bg-white border border-slate-200 rounded-full shadow-sm"
>
<Label className="text-slate-900">{tag}</Label>
</span>
))}
</div>
</Card>
</Reveal>
</div>
</div>
</Section>
{/* Section 02: Arbeitsweise HOW I work */}
<Section
number="02"
title="Arbeitsweise"
variant="gray"
borderTop
illustration={<ResponsibilityIllustration className="w-24 h-24" />}
effects={<GradientMesh variant="subtle" className="opacity-60" />}
>
<div className="space-y-12">
<Reveal>
<H3 className="text-2xl md:text-5xl leading-tight max-w-3xl">
So läuft ein Projekt <br />
<span className="text-slate-400">bei mir ab.</span>
</H3>
</Reveal>
{/* Timeline Steps */}
<div className="space-y-1 relative">
{/* Connecting line */}
<div className="absolute left-[15px] top-8 bottom-8 w-px bg-slate-200 hidden md:block" />
{[
{
step: "01",
title: "Briefing",
desc: "Sie beschreiben Ihr Vorhaben. Ich höre zu und stelle die richtigen Fragen.",
},
{
step: "02",
title: "Angebot",
desc: "Ein Fixpreis-Angebot mit klarem Leistungsumfang. Keine Überraschungen.",
},
{
step: "03",
title: "Umsetzung",
desc: "Schnelle Iterationen. Sie sehen regelmäßig den Fortschritt und geben Feedback.",
},
{
step: "04",
title: "Launch",
desc: "Go-Live mit automatisiertem Deployment. Dokumentiert und übergabereif.",
},
].map((item, i) => (
<Reveal key={i} delay={0.1 + i * 0.1}>
<div className="flex gap-4 md:gap-6 py-2 md:py-6 group">
<div className="relative z-10 shrink-0">
<div className="w-8 h-8 rounded-full bg-white border border-slate-200 flex items-center justify-center group-hover:border-slate-400 group-hover:shadow-md transition-all duration-500">
<span className="text-[9px] font-mono font-bold text-slate-400 group-hover:text-slate-900 transition-colors">
{item.step}
</span>
</div>
</div>
<div className="space-y-1 md:space-y-2 pt-1">
<H4 className="text-base md:text-xl font-bold">
{item.title}
</H4>
<BodyText className="text-slate-500 text-sm md:text-base">
{item.desc}
</BodyText>
</div>
</div>
</Reveal>
))}
</div>
</div>
</Section>
{/* Section 03: Garantie The Pledge */}
<Section number="03" title="Garantie" borderTop>
<div className="relative">
<Reveal>
<div className="max-w-4xl text-left space-y-12 md:space-y-16 py-8 md:py-16">
<H3 className="text-3xl md:text-6xl leading-tight">
Ich stehe für <br />
<span className="text-slate-400">meine Arbeit gerade.</span>
</H3>
<div className="prose prose-lg md:prose-2xl text-slate-500 leading-relaxed">
<p>
Keine Hierarchien. Keine Ausreden. Wenn etwas nicht passt,
liegt die Verantwortung bei mir.
</p>
<p>
Ich liefere nicht nur Code, sondern{" "}
<span className="text-slate-900 font-medium relative inline-block">
Ergebnisse
<svg
className="absolute -bottom-2 left-0 w-full h-3 text-blue-500/30"
viewBox="0 0 100 10"
preserveAspectRatio="none"
>
<path
d="M0 5 Q 50 10 100 5"
stroke="currentColor"
strokeWidth="2"
fill="none"
/>
</svg>
</span>
, auf die Sie bauen können.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-2xl text-left">
<div className="p-6 bg-slate-50 rounded-2xl border border-slate-100">
<h4 className="font-bold text-slate-900 mb-2">
Fixpreis-Garantie
</h4>
<p className="text-slate-500 text-sm">
Keine versteckten Kosten. Der vereinbarte Preis ist final.
</p>
</div>
<div className="p-6 bg-slate-50 rounded-2xl border border-slate-100">
<h4 className="font-bold text-slate-900 mb-2">
Satisfaction Guarantee
</h4>
<p className="text-slate-500 text-sm">
Wir gehen erst live, wenn Sie zu 100% zufrieden sind.
</p>
</div>
</div>
<div className="pt-8 md:pt-12 flex flex-col items-start">
<div className="w-64 md:w-80">
<Signature delay={0.5} />
</div>
</div>
</div>
</Reveal>
</div>
</Section>
{/* Section 04: CTA */}
<Section
number="04"
title="Kontakt"
variant="gray"
borderTop
illustration={<ContactIllustration className="w-24 h-24" />}
effects={<GradientMesh variant="metallic" className="opacity-60" />}
>
<div className="space-y-10 md:space-y-12">
<Reveal>
<H3 className="text-2xl md:text-5xl leading-tight max-w-3xl">
Bereit für eine <br />
<span className="text-slate-400">Zusammenarbeit?</span>
</H3>
</Reveal>
<Card
variant="glass"
hover={false}
padding="normal"
techBorder
className="rounded-3xl shadow-xl relative overflow-hidden group"
>
<div className="relative z-10 space-y-6 md:space-y-8">
<LeadText className="text-lg md:text-4xl leading-tight max-w-2xl text-slate-400">
Lassen Sie uns gemeinsam etwas bauen, das{" "}
<span className="text-slate-900">
wirklich <Marker delay={0.3}>funktioniert.</Marker>
</span>
</LeadText>
<div className="pt-2 md:pt-4">
<Button href="/contact" className="w-full md:w-auto">
Projekt anfragen
</Button>
</div>
</div>
</Card>
</div>
</Section>
</div>
);
}