This commit is contained in:
@@ -10,28 +10,24 @@ import {
|
||||
ConceptSystem,
|
||||
ConceptTarget,
|
||||
ContactIllustration,
|
||||
ConnectorBranch,
|
||||
ConnectorStart,
|
||||
ConnectorEnd,
|
||||
ConnectorSplit,
|
||||
HeroLines,
|
||||
ParticleNetwork,
|
||||
GridLines
|
||||
} from '../../src/components/Landing';
|
||||
import { Check, ArrowRight } from 'lucide-react';
|
||||
import { Check } from 'lucide-react';
|
||||
import { H3, H4, LeadText, BodyText, Label, MonoLabel } from '../../src/components/Typography';
|
||||
import { BackgroundGrid, Card, Container } from '../../src/components/Layout';
|
||||
import { Button } from '../../src/components/Button';
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<div className="flex flex-col bg-white overflow-hidden relative">
|
||||
{/* Background Elements */}
|
||||
<ParticleNetwork className="opacity-20" />
|
||||
<div className="fixed inset-0 pointer-events-none -z-20 opacity-[0.015]" style={{
|
||||
backgroundImage: 'linear-gradient(#0f172a 1px, transparent 1px), linear-gradient(90deg, #0f172a 1px, transparent 1px)',
|
||||
backgroundSize: '80px 80px'
|
||||
}} />
|
||||
<BackgroundGrid />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="relative pt-40 pb-32 overflow-hidden border-b border-slate-50">
|
||||
<section className="relative pt-32 pb-24 overflow-hidden border-b border-slate-50">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full opacity-10 pointer-events-none">
|
||||
<HeroLines className="w-full h-full" />
|
||||
</div>
|
||||
@@ -39,41 +35,42 @@ export default function AboutPage() {
|
||||
<GridLines />
|
||||
</div>
|
||||
|
||||
<div className="narrow-container relative z-10">
|
||||
<Container variant="narrow" className="relative z-10">
|
||||
<div className="flex flex-col items-center text-center space-y-12">
|
||||
<Reveal>
|
||||
<div className="relative">
|
||||
{/* Structural rings around avatar */}
|
||||
<div className="absolute inset-0 -m-8 border border-slate-100 rounded-full animate-[spin_20s_linear_infinite] opacity-50" />
|
||||
<div className="absolute inset-0 -m-4 border border-slate-200 rounded-full animate-[spin_15s_linear_infinite_reverse] opacity-30" />
|
||||
<div className="absolute inset-0 -m-8 border border-slate-100 rounded-full animate-[spin_30s_linear_infinite] opacity-50" />
|
||||
<div className="absolute inset-0 -m-4 border border-slate-200 rounded-full animate-[spin_20s_linear_infinite_reverse] opacity-30" />
|
||||
|
||||
<div className="relative w-32 h-32 md:w-40 md:h-40 rounded-full overflow-hidden border border-slate-200 shadow-2xl shadow-slate-200/50 bg-white p-1">
|
||||
<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">
|
||||
<img
|
||||
src="/header.webp"
|
||||
alt="Marc Mintel"
|
||||
className="w-full h-full object-cover grayscale transition-all duration-1000 ease-in-out scale-110 hover:scale-100"
|
||||
className="w-full h-full object-cover grayscale transition-all duration-1000 ease-in-out scale-110 group-hover:scale-100 group-hover:grayscale-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
<div className="space-y-6 max-w-2xl">
|
||||
<div className="space-y-6 max-w-3xl">
|
||||
<Reveal delay={0.1}>
|
||||
<div className="flex items-center justify-center gap-3 mb-4">
|
||||
<div className="flex items-center justify-center gap-4 mb-4">
|
||||
<div className="h-px w-8 bg-slate-900"></div>
|
||||
<span className="text-[10px] font-bold uppercase tracking-[0.4em] text-slate-900">Digital Architect</span>
|
||||
<MonoLabel className="text-slate-900">Digital Architect</MonoLabel>
|
||||
<div className="h-px w-8 bg-slate-900"></div>
|
||||
</div>
|
||||
</Reveal>
|
||||
<PageHeader
|
||||
title={<>Über <span className="text-slate-300">mich.</span></>}
|
||||
description="(oder: Warum das hier kein Agentur-Zirkus ist)"
|
||||
title={<>Über <span className="text-slate-200">mich.</span></>}
|
||||
description="Warum ich tue, was ich tue – und wie Sie davon profitieren."
|
||||
className="pt-0 md:pt-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
{/* Connector to first section */}
|
||||
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 w-px h-16 bg-gradient-to-b from-transparent to-slate-200" />
|
||||
@@ -84,48 +81,47 @@ export default function AboutPage() {
|
||||
number="01"
|
||||
title="Erfahrung"
|
||||
borderTop
|
||||
connector={<ConnectorStart className="h-full" />}
|
||||
illustration={<ExperienceIllustration className="w-32 h-32" />}
|
||||
illustration={<ExperienceIllustration className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Ich baue Websites und Systeme seit über 15 Jahren. <br />
|
||||
<span className="text-slate-300">Weil ich es hasse, wenn Dinge nicht funktionieren.</span>
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
15 Jahre Web-Entwicklung. <br />
|
||||
<span className="text-slate-200">Vom Designer zum Architekten.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
|
||||
<Reveal delay={0.1}>
|
||||
<div className="space-y-6">
|
||||
<p className="text-xl text-slate-600 font-serif italic">
|
||||
In diesen 15 Jahren habe ich Agenturen von innen gesehen, Konzerne erlebt und Startups aufgebaut.
|
||||
</p>
|
||||
<div className="space-y-8">
|
||||
<LeadText className="text-xl md:text-2xl text-slate-400">
|
||||
Ich habe Agenturen, Konzerne und Startups von innen gesehen. Dabei habe ich gelernt, what really counts: <span className="text-slate-900">Ergebnisse, nicht Prozesse.</span>
|
||||
</LeadText>
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
'Marketingversprechen zerlegt',
|
||||
'Systeme repariert, die „fertig“ waren',
|
||||
'Gelernt, wie man Dinge baut, die einfach laufen'
|
||||
'Komplexe Systeme vereinfacht',
|
||||
'Performance-Probleme gelöst',
|
||||
'Nachhaltige Software-Architekturen gebaut'
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-center gap-3 text-slate-500">
|
||||
<div className="w-1.5 h-1.5 bg-slate-300 rounded-full shrink-0" />
|
||||
{item}
|
||||
<li key={i} className="flex items-center gap-4 group">
|
||||
<div className="w-1.5 h-1.5 bg-slate-900 rounded-full group-hover:scale-150 transition-transform" />
|
||||
<BodyText className="text-lg">{item}</BodyText>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<div className="p-8 bg-slate-50 rounded-3xl border border-slate-100">
|
||||
<p className="text-slate-900 font-bold text-lg mb-4">Heute mache ich das ohne Agentur-Zwischenschichten.</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
{['Direkt', 'Sauber', 'Verantwortlich'].map((tag, i) => (
|
||||
<span key={i} className="px-4 py-2 bg-white border border-slate-200 rounded-full text-xs font-bold uppercase tracking-widest text-slate-400">
|
||||
{tag}
|
||||
<Card variant="gray" hover={false} padding="normal" className="group">
|
||||
<H4 className="text-2xl mb-6">Mein Fokus 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>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,31 +133,30 @@ export default function AboutPage() {
|
||||
title="Verantwortung"
|
||||
variant="gray"
|
||||
borderTop
|
||||
connector={<ConnectorBranch className="h-full" />}
|
||||
illustration={<ResponsibilityIllustration className="w-32 h-32" />}
|
||||
illustration={<ResponsibilityIllustration className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Ich habe fast alle Fehler schon für Sie gemacht. <br />
|
||||
<span className="text-slate-300">(Damit Sie sie nicht machen müssen)</span>
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Ich stehe für meine <br />
|
||||
<span className="text-slate-200">Arbeit gerade.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 items-center">
|
||||
<div className="md:col-span-7 space-y-8">
|
||||
<div className="md:col-span-8 space-y-8">
|
||||
<Reveal delay={0.1}>
|
||||
<p className="text-xl text-slate-600 font-serif italic">
|
||||
Ich habe als Designer angefangen, bin dann Entwickler geworden, und habe irgendwann gemerkt: Das Problem ist selten Technik. Es ist immer Zuständigkeit.
|
||||
</p>
|
||||
<LeadText className="text-xl md:text-2xl text-slate-400">
|
||||
In der klassischen Agenturwelt verschwindet Verantwortung oft hinter Hierarchien. Bei mir gibt es nur <span className="text-slate-900">einen Ansprechpartner:</span> Mich.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<div className="flex items-start gap-6 p-6 bg-white rounded-2xl border border-slate-100 shadow-sm">
|
||||
<div className="w-12 h-12 bg-slate-900 text-white rounded-xl flex items-center justify-center shrink-0 font-bold">!</div>
|
||||
<p className="text-slate-900 font-medium">
|
||||
Wenn keiner verantwortlich ist, passiert nichts. Also habe ich mir angewöhnt, Verantwortung zu übernehmen.
|
||||
</p>
|
||||
</div>
|
||||
<Card variant="white" padding="normal" className="flex flex-row items-start gap-6 group">
|
||||
<div className="w-12 h-12 bg-slate-900 text-white rounded-xl flex items-center justify-center shrink-0 font-bold text-xl group-hover:rotate-12 transition-transform duration-500">!</div>
|
||||
<BodyText className="text-slate-900 font-medium text-lg md:text-xl leading-relaxed">
|
||||
Ich übernehme die volle Verantwortung für die technische Umsetzung und Qualität Ihres Projekts. Ohne Ausreden.
|
||||
</BodyText>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -173,129 +168,94 @@ export default function AboutPage() {
|
||||
number="03"
|
||||
title="Philosophie"
|
||||
borderTop
|
||||
connector={<ConnectorSplit className="h-full" />}
|
||||
illustration={<ConceptSystem className="w-32 h-32" />}
|
||||
illustration={<ConceptSystem className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-16">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Warum ich Websites wie Systeme baue.
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Nachhaltigkeit durch <br />
|
||||
<span className="text-slate-200">sauberen Code.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
|
||||
<div className="space-y-8">
|
||||
<Reveal delay={0.1}>
|
||||
<p className="text-slate-500 font-serif italic text-lg">
|
||||
Ich war viele Jahre Senior Developer in Firmen, in denen Millionenumsätze dranhingen, Fehler teuer waren und Performance nicht optional war.
|
||||
</p>
|
||||
<LeadText className="text-xl text-slate-400">
|
||||
Ich baue keine Wegwerf-Produkte. Meine Systeme sind so konzipiert, dass sie mit Ihrem Unternehmen <span className="text-slate-900">wachsen können.</span>
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
{['Schnell', 'Stabil', 'Boring', 'Erweiterbar', 'Wartungsarm', 'Unabhängig'].map((item, i) => (
|
||||
{['Skalierbar', 'Wartbar', 'Performant', 'Sicher', 'Unabhängig', 'Zukunftssicher'].map((item, i) => (
|
||||
<Reveal key={i} delay={0.2 + i * 0.05}>
|
||||
<div className="flex items-center gap-2 text-slate-900 font-bold text-sm uppercase tracking-widest">
|
||||
<Check className="w-4 h-4 text-slate-400" />
|
||||
{item}
|
||||
<div className="flex items-center gap-3 group">
|
||||
<div className="w-5 h-5 rounded-full bg-slate-50 flex items-center justify-center group-hover:bg-slate-900 transition-colors duration-500">
|
||||
<Check className="w-2.5 h-2.5 text-slate-400 group-hover:text-white" />
|
||||
</div>
|
||||
<Label className="text-slate-900">{item}</Label>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<Reveal delay={0.3}>
|
||||
<div className="relative p-10 bg-slate-900 text-white rounded-3xl overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-white/5 -translate-y-16 translate-x-16 rounded-full blur-3xl group-hover:bg-white/10 transition-colors" />
|
||||
<h4 className="text-2xl font-bold mb-6 relative z-10">Das prägt.</h4>
|
||||
<p className="text-slate-400 font-serif italic text-lg relative z-10">
|
||||
Meine Websites sind nicht abhängig von Plugins oder Agenturen. Sie sind gebaut, um zu bleiben.
|
||||
</p>
|
||||
</div>
|
||||
<Card variant="dark" padding="normal" className="relative rounded-2xl overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-48 h-48 bg-white/5 -translate-y-24 translate-x-24 rounded-full blur-3xl group-hover:bg-white/10 transition-colors duration-1000" />
|
||||
<H4 className="text-white text-2xl mb-6 relative z-10">Kein Vendor Lock-in.</H4>
|
||||
<LeadText className="text-slate-400 text-lg relative z-10 leading-relaxed">
|
||||
Sie behalten die volle Kontrolle über Ihren Code und Ihre Daten. Keine Abhängigkeit von proprietären Systemen.
|
||||
</LeadText>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Section 04: Roles */}
|
||||
{/* Section 04: Result */}
|
||||
<Section
|
||||
number="04"
|
||||
title="Perspektive"
|
||||
variant="gray"
|
||||
borderTop
|
||||
connector={<ConnectorBranch className="h-full" />}
|
||||
illustration={<ConceptTarget className="w-32 h-32" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Ich habe beide Seiten gesehen.
|
||||
</h3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{[
|
||||
'Webdesigner', 'Entwickler', 'Marketing', 'Vertrieb',
|
||||
'Agentur', 'Inhouse', 'Dienstleister', 'Unternehmer'
|
||||
].map((role, i) => (
|
||||
<Reveal key={i} delay={i * 0.05}>
|
||||
<div className="p-4 bg-white border border-slate-100 rounded-xl text-center hover:border-slate-300 transition-colors group">
|
||||
<span className="text-xs font-bold uppercase tracking-widest text-slate-400 group-hover:text-slate-900 transition-colors">{role}</span>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Reveal delay={0.4}>
|
||||
<p className="text-2xl text-slate-600 font-serif italic max-w-2xl">
|
||||
Ich weiß, was Unternehmen brauchen – und was sie nicht brauchen. (Meetings, Tickets, Workshops, PowerPoint.)
|
||||
</p>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Section 05: Result */}
|
||||
<Section
|
||||
number="05"
|
||||
title="Ergebnis"
|
||||
borderTop
|
||||
connector={<ConnectorBranch className="h-full" />}
|
||||
illustration={<ResultIllustration className="w-32 h-32" />}
|
||||
illustration={<ResultIllustration className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-16">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Was Kunden davon haben.
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Was Sie von mir <br />
|
||||
<span className="text-slate-200">erwarten können.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-16">
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-4">
|
||||
<span className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-400">Sie bekommen kein:</span>
|
||||
<div className="space-y-6">
|
||||
<Label>Kein:</Label>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
{['Projektmanager', 'Prozess', 'Team', 'Ticket', 'CMS-Drama'].map((item, i) => (
|
||||
<span key={i} className="px-4 py-2 border border-slate-100 rounded-full text-slate-400 line-through text-sm italic font-serif">
|
||||
{item}
|
||||
{['Agentur-Zirkus', 'Meeting-Marathon', 'Ticket-Wahnsinn', 'CMS-Frust'].map((item, i) => (
|
||||
<span key={i} className="px-4 py-2 border border-slate-100 rounded-full bg-slate-50/50">
|
||||
<BodyText className="text-slate-400 line-through text-base mb-0">{item}</BodyText>
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-4">
|
||||
<span className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-900">Sie bekommen:</span>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-6">
|
||||
<Label className="text-slate-900">Sondern:</Label>
|
||||
<div className="space-y-8">
|
||||
{[
|
||||
{ label: 'Eine Person', desc: 'Direkter Kontakt, keine Stille Post.' },
|
||||
{ label: 'Eine Verantwortung', desc: 'Ich stehe für das Ergebnis gerade.' },
|
||||
{ label: 'Ein Ergebnis', desc: 'Funktionierende Systeme, keine Ausreden.' }
|
||||
{ label: 'Direkte Kommunikation', desc: 'Kurze Wege, schnelle Entscheidungen.' },
|
||||
{ label: 'Echte Expertise', desc: 'Fundiertes Wissen aus 15 Jahren Praxis.' },
|
||||
{ label: 'Messbare Qualität', desc: 'Code, der hält, was er verspricht.' }
|
||||
].map((item, i) => (
|
||||
<Reveal key={i} delay={0.2 + i * 0.1}>
|
||||
<div className="flex gap-4 items-start">
|
||||
<div className="w-6 h-6 rounded-full bg-slate-900 flex items-center justify-center shrink-0 mt-1">
|
||||
<Check className="w-3 h-3 text-white" />
|
||||
<div className="flex gap-6 items-start group">
|
||||
<div className="w-8 h-8 rounded-full bg-slate-900 flex items-center justify-center shrink-0 mt-1 group-hover:scale-110 transition-transform">
|
||||
<Check className="w-4 h-4 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="font-bold text-slate-900">{item.label}</div>
|
||||
<div className="text-slate-500 text-sm font-serif italic">{item.desc}</div>
|
||||
<div className="space-y-1">
|
||||
<H4 className="text-xl">{item.label}</H4>
|
||||
<BodyText className="text-base text-slate-400">{item.desc}</BodyText>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
@@ -307,41 +267,37 @@ export default function AboutPage() {
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Section 06: Today */}
|
||||
{/* Section 05: Today */}
|
||||
<Section
|
||||
number="06"
|
||||
title="Heute"
|
||||
number="05"
|
||||
title="Kontakt"
|
||||
variant="gray"
|
||||
borderTop
|
||||
connector={<ConnectorEnd className="h-full" />}
|
||||
illustration={<ContactIllustration className="w-32 h-32" />}
|
||||
illustration={<ContactIllustration className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Heute baue ich Websites für Unternehmen, die keine Lust mehr auf Chaos haben.
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Bereit für eine <br />
|
||||
<span className="text-slate-200">Zusammenarbeit?</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="p-12 bg-white rounded-[3rem] border border-slate-100 shadow-2xl shadow-slate-200/50 relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-64 h-64 bg-slate-50 -translate-y-32 translate-x-32 rounded-full blur-3xl group-hover:bg-slate-100 transition-colors" />
|
||||
<Card variant="white" hover={false} padding="large" className="rounded-3xl shadow-xl relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-96 h-96 bg-slate-50 -translate-y-1/2 translate-x-1/2 rounded-full blur-[80px] group-hover:bg-slate-100 transition-colors duration-1000" />
|
||||
|
||||
<div className="relative z-10 space-y-8">
|
||||
<p className="text-2xl text-slate-600 font-serif italic leading-relaxed max-w-2xl">
|
||||
Ich übernehme das Thema komplett – damit es für Sie kein Thema mehr ist.
|
||||
</p>
|
||||
<LeadText className="text-2xl md:text-4xl leading-tight max-w-2xl text-slate-400">
|
||||
Lassen Sie uns gemeinsam etwas bauen, das <span className="text-slate-900">wirklich funktioniert.</span>
|
||||
</LeadText>
|
||||
|
||||
<div className="pt-8">
|
||||
<a
|
||||
href="/contact"
|
||||
className="inline-flex items-center gap-4 px-10 py-5 bg-slate-900 text-white rounded-full font-bold text-sm uppercase tracking-widest hover:bg-slate-800 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-1 hover:shadow-2xl hover:shadow-slate-900/20 group"
|
||||
>
|
||||
<div className="pt-4">
|
||||
<Button href="/contact">
|
||||
Projekt anfragen
|
||||
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Section>
|
||||
</div>
|
||||
|
||||
@@ -10,28 +10,28 @@
|
||||
|
||||
body {
|
||||
@apply bg-white text-slate-800 font-serif antialiased selection:bg-slate-900 selection:text-white;
|
||||
line-height: 1.8;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
@apply font-sans font-bold text-slate-900;
|
||||
@apply font-sans font-bold text-slate-900 tracking-tighter;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-4xl md:text-5xl leading-[1.1] mb-8 tracking-tight;
|
||||
@apply text-6xl md:text-8xl leading-[0.95] mb-12;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-3xl md:text-4xl leading-[1.2] mb-6 mt-12 tracking-tight;
|
||||
@apply text-4xl md:text-6xl leading-tight mb-8 mt-16;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply text-2xl md:text-3xl leading-[1.3] mb-4 mt-8 tracking-tight;
|
||||
@apply text-3xl md:text-5xl leading-tight mb-6 mt-12;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@apply text-xl md:text-2xl leading-[1.4] mb-3 mt-6 tracking-tight;
|
||||
@apply text-2xl md:text-3xl leading-tight mb-4 mt-8;
|
||||
}
|
||||
|
||||
p {
|
||||
|
||||
363
app/page.tsx
363
app/page.tsx
@@ -1,6 +1,4 @@
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import {
|
||||
CirclePattern,
|
||||
ComparisonRow,
|
||||
ConceptAutomation,
|
||||
ConceptCode,
|
||||
@@ -10,80 +8,61 @@ import {
|
||||
ConceptPrototyping,
|
||||
ConceptSystem,
|
||||
ConceptWebsite,
|
||||
ConnectorBranch,
|
||||
ConnectorEnd,
|
||||
ConnectorSplit,
|
||||
ConnectorStart,
|
||||
ContactIllustration,
|
||||
DifferenceIllustration,
|
||||
FlowLines,
|
||||
GridLines,
|
||||
HeroArchitecture,
|
||||
HeroMainIllustration,
|
||||
ServicesFlow
|
||||
HeroMainIllustration
|
||||
} from '../src/components/Landing';
|
||||
import { Reveal } from '../src/components/Reveal';
|
||||
import { Section } from '../src/components/Section';
|
||||
import { H1, H3, LeadText, BodyText, MonoLabel, Label } from '../src/components/Typography';
|
||||
import { BackgroundGrid, Card, Container } from '../src/components/Layout';
|
||||
import { Button } from '../src/components/Button';
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="flex flex-col bg-white overflow-hidden relative">
|
||||
|
||||
{/* Subtle Grid Pattern Overlay */}
|
||||
<div className="fixed inset-0 pointer-events-none -z-20 opacity-[0.015]" style={{
|
||||
backgroundImage: 'linear-gradient(#0f172a 1px, transparent 1px), linear-gradient(90deg, #0f172a 1px, transparent 1px)',
|
||||
backgroundSize: '80px 80px'
|
||||
}} />
|
||||
<BackgroundGrid />
|
||||
|
||||
{/* Hero Section - Split Layout */}
|
||||
<section className="relative min-h-[80vh] flex items-center pt-12 md:pt-0 pb-24 md:pb-0">
|
||||
<div className="narrow-container w-full relative">
|
||||
{/* Connector Start for Hero */}
|
||||
<div className="absolute left-[2.5rem] top-32 bottom-0 w-24 hidden md:block -z-10 pointer-events-none">
|
||||
<ConnectorStart className="h-full" />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 md:gap-16 items-center min-h-[600px]">
|
||||
{/* Left Column: Brand & Number */}
|
||||
<div className="md:col-span-4 relative z-10 bg-white/50 backdrop-blur-[2px]">
|
||||
{/* Hero Section */}
|
||||
<section className="relative min-h-[80vh] flex items-center pt-24 md:pt-0">
|
||||
<Container variant="narrow" className="relative">
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 md:gap-24 items-center">
|
||||
{/* Left Column */}
|
||||
<div className="md:col-span-6 relative z-10">
|
||||
<Reveal>
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-center gap-3 text-slate-400 font-mono text-[10px] uppercase tracking-[0.3em]">
|
||||
<span className="w-6 h-px bg-slate-900"></span>
|
||||
Digital Architect
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-8 h-px bg-slate-900"></div>
|
||||
<MonoLabel className="text-slate-900">Digital Architect</MonoLabel>
|
||||
</div>
|
||||
<h1 className="text-6xl md:text-8xl font-bold text-slate-900 tracking-tighter leading-[0.9]">
|
||||
<H1 className="text-6xl md:text-8xl">
|
||||
Websites <br />
|
||||
<span className="text-slate-300">ohne <br />Overhead.</span>
|
||||
</h1>
|
||||
<div className="pt-8">
|
||||
<a
|
||||
href="#contact"
|
||||
className="inline-flex items-center gap-4 px-8 py-4 border border-slate-200 bg-white text-slate-900 rounded-full font-bold text-sm uppercase tracking-widest hover:border-slate-400 hover:bg-slate-50 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-0.5 hover:shadow-xl hover:shadow-slate-100 group"
|
||||
>
|
||||
<span className="text-slate-200">ohne Overhead.</span>
|
||||
</H1>
|
||||
<div className="pt-4">
|
||||
<Button href="#contact" variant="outline">
|
||||
Projekt anfragen
|
||||
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
{/* Right Column: Visual & Context */}
|
||||
<div className="md:col-span-8 relative h-[600px] md:h-[900px] flex items-center justify-center">
|
||||
{/* Hero Architecture Illustration - Background Layer */}
|
||||
<div className="absolute inset-0 -z-10 opacity-5 pointer-events-none flex items-center justify-center scale-[2]">
|
||||
{/* Right Column */}
|
||||
<div className="md:col-span-6 relative h-[400px] md:h-[600px] flex items-center justify-center">
|
||||
<div className="absolute inset-0 -z-10 opacity-[0.03] pointer-events-none flex items-center justify-center scale-150">
|
||||
<HeroArchitecture className="w-full h-full" />
|
||||
</div>
|
||||
|
||||
<Reveal delay={0.2} className="w-full h-full flex items-center justify-center">
|
||||
<div className="relative w-full h-full flex items-center justify-center pointer-events-none">
|
||||
<HeroMainIllustration className="w-full h-full scale-150 md:scale-[1.6] translate-x-12 md:translate-x-16 origin-center" />
|
||||
<HeroMainIllustration className="w-full h-full scale-110 md:scale-125 origin-center" />
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</section>
|
||||
|
||||
{/* Section 02: The Promise */}
|
||||
@@ -91,41 +70,33 @@ export default function LandingPage() {
|
||||
number="02"
|
||||
title="Das Versprechen"
|
||||
borderTop
|
||||
connector={<ConnectorBranch className="h-full" />}
|
||||
>
|
||||
<div className="space-y-16 relative">
|
||||
<div className="absolute right-0 top-0 w-64 h-64 -z-10 opacity-30 pointer-events-none">
|
||||
<GridLines />
|
||||
</div>
|
||||
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
<H3 className="max-w-3xl">
|
||||
Schluss mit aufgeblähten Prozessen. <br />
|
||||
<span className="text-slate-300">Ich reduziere auf das Wesentliche.</span>
|
||||
</h3>
|
||||
<span className="text-slate-200">Ich reduziere auf das Wesentliche.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 relative z-10">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-16 relative z-10">
|
||||
<Reveal delay={0.1}>
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-center gap-4 text-slate-900 font-bold text-lg">
|
||||
<div className="w-12 h-12 rounded-xl bg-slate-50 flex items-center justify-center border border-slate-100">
|
||||
<ConceptCode className="w-8 h-8" />
|
||||
</div>
|
||||
Was ich biete
|
||||
<div className="flex items-center gap-4">
|
||||
<Label className="text-slate-900">Was ich biete</Label>
|
||||
</div>
|
||||
<ul className="space-y-8">
|
||||
<ul className="space-y-6">
|
||||
{[
|
||||
{ text: 'Direkte Kommunikation ohne Account Manager', icon: <ConceptCommunication className="w-16 h-16" /> },
|
||||
{ text: 'Schnelle Prototypen statt langer Konzepte', icon: <ConceptPrototyping className="w-16 h-16" /> },
|
||||
{ text: 'Sauberer Code, der auch morgen noch läuft', icon: <ConceptCode className="w-16 h-16" /> },
|
||||
{ text: 'Fixpreise für klare Budgetsicherheit', icon: <ConceptPrice className="w-16 h-16" /> }
|
||||
{ text: 'Direkte Kommunikation ohne Umwege', icon: <ConceptCommunication className="w-12 h-12" /> },
|
||||
{ text: 'Schnelle Prototypen statt langer Konzepte', icon: <ConceptPrototyping className="w-12 h-12" /> },
|
||||
{ text: 'Sauberer Code, der auch morgen noch läuft', icon: <ConceptCode className="w-12 h-12" /> },
|
||||
{ text: 'Fixpreise für volle Budgetsicherheit', icon: <ConceptPrice className="w-12 h-12" /> }
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-center gap-6 text-slate-600 font-serif italic text-lg group">
|
||||
<div className="shrink-0 opacity-100 transition-all duration-500 group-hover:scale-110">
|
||||
<li key={i} className="flex items-center gap-6 group">
|
||||
<div className="shrink-0 transition-transform duration-500 group-hover:scale-110">
|
||||
{item.icon}
|
||||
</div>
|
||||
{item.text}
|
||||
<LeadText className="text-xl">{item.text}</LeadText>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@@ -133,12 +104,9 @@ export default function LandingPage() {
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.2}>
|
||||
<div className="space-y-8 opacity-50 hover:opacity-100 transition-opacity duration-500">
|
||||
<div className="flex items-center gap-4 text-slate-400 font-bold text-lg">
|
||||
<div className="w-12 h-12 rounded-xl bg-slate-50 flex items-center justify-center border border-slate-100 grayscale">
|
||||
<ConceptMessy className="w-8 h-8" />
|
||||
</div>
|
||||
Was ich nicht mache
|
||||
<div className="space-y-8 opacity-40 hover:opacity-100 transition-opacity duration-700">
|
||||
<div className="flex items-center gap-4">
|
||||
<Label>Was ich nicht mache</Label>
|
||||
</div>
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
@@ -147,9 +115,9 @@ export default function LandingPage() {
|
||||
'Outsourcing an Billig-Anbieter',
|
||||
'Wartungsverträge mit versteckten Kosten'
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-start gap-3 text-slate-400 font-serif italic text-lg decoration-slate-400 line-through">
|
||||
<span className="w-1.5 h-1.5 bg-slate-300 rounded-full mt-2.5 shrink-0"></span>
|
||||
{item}
|
||||
<li key={i} className="flex items-start gap-3 decoration-slate-200 line-through">
|
||||
<span className="w-1.5 h-1.5 bg-slate-200 rounded-full mt-2.5 shrink-0"></span>
|
||||
<LeadText className="text-slate-400 text-lg">{item}</LeadText>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@@ -165,43 +133,37 @@ export default function LandingPage() {
|
||||
title="Der Unterschied"
|
||||
variant="white"
|
||||
borderTop
|
||||
connector={<ConnectorStart className="h-full" />}
|
||||
>
|
||||
<div className="space-y-12 relative">
|
||||
<div className="space-y-16 relative">
|
||||
<div className="flex flex-col md:flex-row gap-12 items-center">
|
||||
<Reveal className="flex-1">
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl relative z-10">
|
||||
Der klassische Agentur-Weg ist oft langsam und teuer. Mein Ansatz ist radikal anders: Ich baue zuerst, dann reden wir über Details.
|
||||
</p>
|
||||
<LeadText className="text-2xl md:text-3xl leading-tight max-w-2xl relative z-10 text-slate-400">
|
||||
Ich arbeite nicht gegen die Zeit, sondern <span className="text-slate-900">für das Ergebnis.</span> Mein Fokus liegt auf der Umsetzung, nicht auf der Verwaltung von Prozessen.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2} className="w-full md:w-80 shrink-0">
|
||||
<DifferenceIllustration className="w-full h-auto" />
|
||||
<Reveal delay={0.2} className="w-full md:w-72 shrink-0">
|
||||
<div className="p-6 bg-slate-50 rounded-2xl border border-slate-100">
|
||||
<DifferenceIllustration className="w-full h-auto grayscale opacity-50" />
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6 relative z-20">
|
||||
<div className="grid grid-cols-1 gap-8 relative z-20">
|
||||
<ComparisonRow
|
||||
negativeLabel="Agentur"
|
||||
negativeText="Konzeptcalls, Meetings, Slides, Warten auf das Angebot."
|
||||
positiveLabel="Ich"
|
||||
positiveText="Ich baue einen Prototypen. Sie sehen sofort, was Sie bekommen."
|
||||
negativeLabel="Klassisch"
|
||||
negativeText="Lange Planungsphasen und abstrakte Konzepte."
|
||||
positiveLabel="Mein Weg"
|
||||
positiveText="Schnelle Prototypen. Sie sehen Fortschritt in Tagen."
|
||||
delay={0.1}
|
||||
/>
|
||||
<ComparisonRow
|
||||
negativeLabel="Agentur"
|
||||
negativeText="Stundensätze, Nachberechnungen, Budget-Überraschungen."
|
||||
positiveLabel="Ich"
|
||||
positiveText="Fixpreise. Ein Preis, ein Ergebnis. Keine Diskussionen."
|
||||
negativeLabel="Klassisch"
|
||||
negativeText="Komplexe Preisstrukturen und versteckte Kosten."
|
||||
positiveLabel="Mein Weg"
|
||||
positiveText="Klare Fixpreise. Volle Kostentransparenz."
|
||||
reverse
|
||||
delay={0.2}
|
||||
/>
|
||||
<ComparisonRow
|
||||
negativeLabel="Agentur"
|
||||
negativeText="Wechselnde Ansprechpartner, Stille Post."
|
||||
positiveLabel="Ich"
|
||||
positiveText="Ein Ansprechpartner. Ich setze um, was wir besprechen."
|
||||
delay={0.3}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
@@ -211,103 +173,97 @@ export default function LandingPage() {
|
||||
number="04"
|
||||
title="Zielgruppe"
|
||||
borderTop
|
||||
connector={<ConnectorSplit className="h-full" />}
|
||||
>
|
||||
<div className="relative">
|
||||
<div className="absolute left-0 top-0 w-full h-full -z-10 opacity-30 pointer-events-none">
|
||||
<CirclePattern />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 relative z-10">
|
||||
<Reveal>
|
||||
<div className="p-10 bg-slate-900 text-white rounded-3xl h-full flex flex-col justify-between group hover:scale-[1.02] transition-transform duration-500 shadow-2xl shadow-slate-900/20">
|
||||
<div className="space-y-6 relative overflow-hidden">
|
||||
<div className="w-16 h-16 bg-white/10 rounded-2xl flex items-center justify-center">
|
||||
<ConceptPrice className="w-10 h-10" />
|
||||
</div>
|
||||
<h3 className="text-3xl font-bold tracking-tight text-white">Unternehmer & <br/>Geschäftsführer</h3>
|
||||
<p className="text-slate-300 font-serif italic text-lg leading-relaxed">
|
||||
"Ich brauche eine Lösung, die funktioniert. Ich habe keine Zeit für technische Details oder lange Meetings."
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-8 border-t border-white/10 mt-8">
|
||||
<span className="text-xs font-bold uppercase tracking-widest text-slate-400 group-hover:text-white transition-colors">Perfekt für Sie</span>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 relative z-10">
|
||||
<Reveal>
|
||||
<Card variant="dark" padding="normal" className="group">
|
||||
<div className="space-y-6 relative overflow-hidden">
|
||||
<div className="w-16 h-16 bg-white/5 rounded-xl flex items-center justify-center border border-white/10">
|
||||
<ConceptPrice className="w-8 h-8" />
|
||||
</div>
|
||||
<H3 className="text-white text-3xl">Unternehmer & <br/>Geschäftsführer</H3>
|
||||
<LeadText className="text-slate-400 text-lg">
|
||||
"Ich brauche eine Lösung, die funktioniert. Ich habe keine Zeit für technische Details."
|
||||
</LeadText>
|
||||
</div>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<div className="p-10 bg-white border border-slate-100 rounded-3xl h-full flex flex-col justify-between group hover:border-slate-300 transition-colors duration-500 shadow-xl shadow-slate-100/50">
|
||||
<div className="space-y-6 relative overflow-hidden">
|
||||
<div className="w-16 h-16 bg-slate-50 border border-slate-200 rounded-2xl flex items-center justify-center">
|
||||
<ConceptWebsite className="w-10 h-10" />
|
||||
</div>
|
||||
<h3 className="text-3xl font-bold tracking-tight text-slate-900">Marketing & <br/>Vertrieb</h3>
|
||||
<p className="text-slate-600 font-serif italic text-lg leading-relaxed">
|
||||
"Wir brauchen Landingpages, Tools und Automatisierungen, um unsere Ziele zu erreichen. Schnell und zuverlässig."
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-8 border-t border-slate-200 mt-8">
|
||||
<span className="text-xs font-bold uppercase tracking-widest text-slate-400 group-hover:text-slate-900 transition-colors">Perfekt für Sie</span>
|
||||
</div>
|
||||
<div className="pt-8 border-t border-white/5 mt-8">
|
||||
<Label className="group-hover:text-white transition-colors">Perfekt für Sie</Label>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<Card variant="white" padding="normal" className="group">
|
||||
<div className="space-y-6 relative overflow-hidden">
|
||||
<div className="w-16 h-16 bg-slate-50 border border-slate-100 rounded-xl flex items-center justify-center">
|
||||
<ConceptWebsite className="w-8 h-8" />
|
||||
</div>
|
||||
<H3 className="text-3xl">Marketing & <br/>Vertrieb</H3>
|
||||
<LeadText className="text-slate-400 text-lg">
|
||||
"Wir brauchen Landingpages und Tools, um unsere Ziele zu erreichen. Schnell und zuverlässig."
|
||||
</LeadText>
|
||||
</div>
|
||||
<div className="pt-8 border-t border-slate-50 mt-8">
|
||||
<Label className="group-hover:text-slate-900 transition-colors">Perfekt für Sie</Label>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Section 05: Services - Visual Flow */}
|
||||
{/* Section 05: Services */}
|
||||
<Section
|
||||
number="05"
|
||||
title="Leistungen"
|
||||
variant="gray"
|
||||
borderTop
|
||||
connector={<ConnectorBranch className="h-full" />}
|
||||
>
|
||||
<div className="relative py-12">
|
||||
{/* Connecting Line Illustration */}
|
||||
<div className="absolute top-1/2 left-0 w-full -translate-y-1/2 hidden md:block">
|
||||
<ServicesFlow />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 relative z-20">
|
||||
<Reveal delay={0.1}>
|
||||
<div className="bg-white p-8 rounded-2xl border border-slate-100 shadow-lg hover:shadow-xl transition-all duration-300 group h-full relative overflow-hidden">
|
||||
<div className="w-20 h-20 bg-slate-50 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptWebsite className="w-12 h-12" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-slate-900 mb-4">Websites</h3>
|
||||
<p className="text-slate-500 font-serif italic mb-6">
|
||||
High-Performance Websites. Kein Baukasten, sondern maßgeschneiderte Architektur.
|
||||
</p>
|
||||
<a href="/websites" className="text-xs font-bold uppercase tracking-widest text-slate-900 border-b border-slate-200 pb-1 hover:border-slate-900 transition-colors">
|
||||
Preise ansehen
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 relative z-20">
|
||||
<Reveal delay={0.1}>
|
||||
<Card variant="white" padding="small" className="group">
|
||||
<div className="w-16 h-16 bg-slate-50 rounded-xl flex items-center justify-center mb-8 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptWebsite className="w-8 h-8" />
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<H3 className="text-2xl">Websites</H3>
|
||||
<BodyText>
|
||||
High-Performance Websites. Maßgeschneiderte Architektur statt Baukasten.
|
||||
</BodyText>
|
||||
<div className="pt-4">
|
||||
<a href="/websites" className="text-[10px] font-bold uppercase tracking-[0.4em] text-slate-900 border-b border-slate-100 pb-1 hover:border-slate-900 transition-all">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</Card>
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.3}>
|
||||
<div className="bg-white p-8 rounded-2xl border border-slate-100 shadow-lg hover:shadow-xl transition-all duration-300 group h-full mt-8 md:mt-0 relative overflow-hidden">
|
||||
<div className="w-20 h-20 bg-slate-50 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptSystem className="w-12 h-12" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-slate-900 mb-4">Systeme</h3>
|
||||
<p className="text-slate-500 font-serif italic">
|
||||
Web-Applikationen, Kundenportale, interne Tools. Wenn Standard-Software an ihre Grenzen stößt.
|
||||
</p>
|
||||
<Reveal delay={0.3}>
|
||||
<Card variant="white" padding="small" className="group mt-8 md:mt-0">
|
||||
<div className="w-16 h-16 bg-slate-50 rounded-xl flex items-center justify-center mb-8 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptSystem className="w-8 h-8" />
|
||||
</div>
|
||||
</Reveal>
|
||||
<div className="space-y-4">
|
||||
<H3 className="text-2xl">Systeme</H3>
|
||||
<BodyText>
|
||||
Web-Applikationen, Portale, interne Tools. Wenn Standard an Grenzen stößt.
|
||||
</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
|
||||
<Reveal delay={0.5}>
|
||||
<div className="bg-white p-8 rounded-2xl border border-slate-100 shadow-lg hover:shadow-xl transition-all duration-300 group h-full relative overflow-hidden">
|
||||
<div className="w-20 h-20 bg-slate-50 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptAutomation className="w-12 h-12" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-slate-900 mb-4">Automatisierung</h3>
|
||||
<p className="text-slate-500 font-serif italic">
|
||||
Verbindung von Tools, automatische PDF-Erstellung, Daten-Synchronisation.
|
||||
</p>
|
||||
<Reveal delay={0.5}>
|
||||
<Card variant="white" padding="small" className="group">
|
||||
<div className="w-16 h-16 bg-slate-50 rounded-xl flex items-center justify-center mb-8 group-hover:scale-110 transition-transform duration-500">
|
||||
<ConceptAutomation className="w-8 h-8" />
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<H3 className="text-2xl">Automatisierung</H3>
|
||||
<BodyText>
|
||||
Verbindung von Tools, automatische Prozesse, Daten-Synchronisation.
|
||||
</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@@ -316,43 +272,38 @@ export default function LandingPage() {
|
||||
number="06"
|
||||
title="Kontakt"
|
||||
borderTop
|
||||
connector={<ConnectorEnd className="h-full" />}
|
||||
>
|
||||
<div className="relative py-12" id="contact">
|
||||
<div className="absolute right-0 top-1/2 -translate-y-1/2 w-[400px] h-[200px] -z-10 opacity-40 pointer-events-none">
|
||||
<FlowLines />
|
||||
</div>
|
||||
<div className="absolute left-1/2 top-0 -translate-x-1/2 w-32 h-32 opacity-10 -z-10">
|
||||
<ContactIllustration />
|
||||
</div>
|
||||
<Reveal>
|
||||
<div className="space-y-12">
|
||||
<h2 className="text-5xl md:text-7xl font-bold text-slate-900 tracking-tighter leading-[0.9]">
|
||||
<div className="space-y-16">
|
||||
<H1 className="text-6xl md:text-8xl">
|
||||
Lassen Sie uns <br />
|
||||
<span className="text-slate-300">starten.</span>
|
||||
</h2>
|
||||
<span className="text-slate-200">starten.</span>
|
||||
</H1>
|
||||
|
||||
<div className="flex flex-col md:flex-row gap-12 items-start relative z-10">
|
||||
<div className="space-y-6 flex-1">
|
||||
<p className="text-xl text-slate-600 font-serif italic">
|
||||
Schreiben Sie mir kurz, worum es geht. Ich melde mich innerhalb von 24 Stunden mit einer ersten Einschätzung.
|
||||
</p>
|
||||
<a
|
||||
href="/contact"
|
||||
className="inline-block text-3xl md:text-4xl font-bold text-slate-900 hover:text-slate-600 transition-colors border-b-2 border-slate-900 hover:border-slate-600 pb-2"
|
||||
>
|
||||
Projekt anfragen
|
||||
</a>
|
||||
<div className="flex flex-col md:flex-row gap-16 items-start relative z-10">
|
||||
<div className="space-y-8 flex-1">
|
||||
<LeadText className="text-2xl md:text-3xl text-slate-400">
|
||||
Schreiben Sie mir kurz, worum es geht. Ich melde mich innerhalb von <span className="text-slate-900">24 Stunden</span>.
|
||||
</LeadText>
|
||||
<div className="pt-4">
|
||||
<a
|
||||
href="/contact"
|
||||
className="inline-block text-3xl md:text-5xl font-bold text-slate-900 hover:text-slate-400 transition-all duration-700 border-b-2 border-slate-900 hover:border-slate-200 pb-2"
|
||||
>
|
||||
Projekt anfragen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 space-y-4">
|
||||
<div className="flex items-center gap-4 text-sm font-bold uppercase tracking-widest text-slate-400">
|
||||
<div className="w-full md:w-72 space-y-6 p-6 bg-slate-50 rounded-2xl border border-slate-100">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
|
||||
Verfügbar für neue Projekte
|
||||
<Label className="text-slate-900">Verfügbarkeit</Label>
|
||||
</div>
|
||||
<p className="text-slate-500 text-sm">
|
||||
Aktuell nehme ich Projekte für Q2 2026 an.
|
||||
</p>
|
||||
<BodyText className="text-base leading-snug">
|
||||
Aktuell nehme ich Projekte für <span className="font-bold text-slate-900">Q2 2026</span> an.
|
||||
</BodyText>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { Info, Check, Zap, Shield, Code, MessageSquare, RefreshCw, Layout, ArrowRight } from 'lucide-react';
|
||||
import { PageHeader } from '../../src/components/PageHeader';
|
||||
import { Reveal } from '../../src/components/Reveal';
|
||||
import { Section } from '../../src/components/Section';
|
||||
@@ -10,23 +9,28 @@ import {
|
||||
SolidFoundation,
|
||||
LayerSeparation,
|
||||
DirectService,
|
||||
AgencyChaos,
|
||||
TaskDone
|
||||
} from '../../src/components/Landing/Illustrations/WebsitesDescriptive';
|
||||
import { motion } from 'framer-motion';
|
||||
TaskDone,
|
||||
ConceptAutomation,
|
||||
ConceptCode,
|
||||
ConceptCommunication,
|
||||
ConceptPrototyping,
|
||||
ConceptSystem,
|
||||
ConceptTarget
|
||||
} from '../../src/components/Landing';
|
||||
import { Check } from 'lucide-react';
|
||||
import { H2, H3, H4, LeadText, BodyText, Label } from '../../src/components/Typography';
|
||||
import { BackgroundGrid, Card } from '../../src/components/Layout';
|
||||
import { MotionButton } from '../../src/components/Button';
|
||||
|
||||
export default function WebsitesPage() {
|
||||
return (
|
||||
<div className="flex flex-col bg-white overflow-hidden relative">
|
||||
{/* Subtle Grid Pattern Overlay */}
|
||||
<div className="fixed inset-0 pointer-events-none -z-20 opacity-[0.015]" style={{
|
||||
backgroundImage: 'linear-gradient(#0f172a 1px, transparent 1px), linear-gradient(90deg, #0f172a 1px, transparent 1px)',
|
||||
backgroundSize: '80px 80px'
|
||||
}} />
|
||||
|
||||
<BackgroundGrid />
|
||||
|
||||
<PageHeader
|
||||
title={<>Websites, die <br /><span className="text-slate-300">einfach funktionieren.</span></>}
|
||||
description="Die meisten Websites funktionieren. Bis jemand sie anfasst. Ich baue Websites so, dass das alles egal ist."
|
||||
title={<>Websites, die <br /><span className="text-slate-200">einfach funktionieren.</span></>}
|
||||
description="Keine Baukästen, keine Plugins, kein Overhead. Nur sauberer Code und maximale Performance."
|
||||
backLink={{ href: '/', label: 'Zurück' }}
|
||||
backgroundSymbol="W"
|
||||
/>
|
||||
@@ -36,32 +40,34 @@ export default function WebsitesPage() {
|
||||
number="01"
|
||||
title="Der Ansatz"
|
||||
borderTop
|
||||
illustration={<SystemArchitecture className="w-32 h-32" />}
|
||||
illustration={<SystemArchitecture className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Ich baue Websites wie Systeme – <br />
|
||||
<span className="text-slate-300">nicht wie Broschüren.</span>
|
||||
</h3>
|
||||
<span className="text-slate-200">nicht wie Broschüren.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Eine Website ist kein Flyer. Sie ist ein System, das jeden Tag arbeitet.
|
||||
Deshalb baue ich sie stabil, schnell und vorhersehbar.
|
||||
</p>
|
||||
<LeadText className="text-xl md:text-2xl max-w-2xl text-slate-400">
|
||||
Eine Website ist kein Flyer. Sie ist ein <span className="text-slate-900">Werkzeug</span>, das jeden Tag arbeitet.
|
||||
Deshalb baue ich sie stabil, schnell und wartungsfrei.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.4}>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 pt-8">
|
||||
{[
|
||||
{ label: 'Stabil', icon: Shield },
|
||||
{ label: 'Schnell', icon: Zap },
|
||||
{ label: 'Vorhersehbar', icon: Layout },
|
||||
{ label: 'Sicher', icon: Info },
|
||||
{ label: 'Stabil', icon: ConceptSystem },
|
||||
{ label: 'Schnell', icon: ConceptAutomation },
|
||||
{ label: 'Wartungsfrei', icon: ConceptCode },
|
||||
{ label: 'Sicher', icon: ConceptTarget },
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex flex-col gap-3">
|
||||
<item.icon className="w-5 h-5 text-slate-300" />
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-slate-900">{item.label}</span>
|
||||
<div key={i} className="flex flex-col gap-3 group">
|
||||
<div className="w-12 h-12 rounded-xl bg-slate-50 flex items-center justify-center border border-slate-100 group-hover:scale-110 transition-transform duration-500">
|
||||
<item.icon className="w-6 h-6" />
|
||||
</div>
|
||||
<Label className="text-slate-900">{item.label}</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -74,42 +80,47 @@ export default function WebsitesPage() {
|
||||
number="02"
|
||||
title="Performance"
|
||||
borderTop
|
||||
illustration={<SpeedPerformance className="w-32 h-32" />}
|
||||
variant="gray"
|
||||
illustration={<SpeedPerformance className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Geschwindigkeit ist <br />
|
||||
<span className="text-slate-300">kein Extra. Sie ist Standard.</span>
|
||||
</h3>
|
||||
<span className="text-slate-200">kein Extra. Sie ist Standard.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Viele Websites sind langsam, weil sie zusammengeklickt sind. Meine sind schnell, weil sie gebaut sind.
|
||||
</p>
|
||||
</Reveal>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 pt-8">
|
||||
<Reveal delay={0.4}>
|
||||
<ul className="space-y-6">
|
||||
{[
|
||||
'Seiten laden sofort',
|
||||
'Google mag sie (SEO)',
|
||||
'Besucher bleiben länger',
|
||||
'Bessere Sichtbarkeit',
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-center gap-4 text-lg text-slate-600 font-serif italic">
|
||||
<div className="w-1.5 h-1.5 bg-slate-900 rounded-full" />
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Reveal>
|
||||
<Reveal delay={0.6}>
|
||||
<div className="p-10 bg-slate-50 rounded-3xl border border-slate-100 flex flex-col justify-center items-center text-center group">
|
||||
<div className="text-7xl md:text-9xl font-bold text-slate-900 tracking-tighter group-hover:scale-110 transition-transform duration-500">90+</div>
|
||||
<div className="text-slate-400 font-serif italic text-lg mt-4">Pagespeed Normalzustand</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 items-center">
|
||||
<div className="md:col-span-7 space-y-8">
|
||||
<Reveal delay={0.2}>
|
||||
<LeadText className="text-xl text-slate-400">
|
||||
Viele Websites sind langsam, weil sie zusammengeklickt sind. Meine sind schnell, weil sie <span className="text-slate-900">von Grund auf</span> entwickelt wurden.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.4}>
|
||||
<ul className="space-y-4">
|
||||
{[
|
||||
'Seiten laden ohne Verzögerung',
|
||||
'Optimiert für Suchmaschinen (SEO)',
|
||||
'Bessere Nutzererfahrung',
|
||||
'Höhere Conversion-Rates',
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-center gap-4 group">
|
||||
<div className="w-1.5 h-1.5 bg-slate-900 rounded-full group-hover:scale-150 transition-transform" />
|
||||
<LeadText className="text-lg md:text-xl">{item}</LeadText>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Reveal>
|
||||
</div>
|
||||
<div className="md:col-span-5">
|
||||
<Reveal delay={0.6}>
|
||||
<Card variant="white" padding="normal" className="text-center group">
|
||||
<div className="text-7xl md:text-8xl font-bold text-slate-900 tracking-tighter group-hover:scale-110 transition-transform duration-700">90+</div>
|
||||
<Label className="mt-4">Pagespeed Score</Label>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
@@ -117,33 +128,39 @@ export default function WebsitesPage() {
|
||||
{/* No Maintenance */}
|
||||
<Section
|
||||
number="03"
|
||||
title="Wartungsfrei"
|
||||
title="Technik"
|
||||
borderTop
|
||||
illustration={<SolidFoundation className="w-32 h-32" />}
|
||||
illustration={<SolidFoundation className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Keine Plugins. <br />
|
||||
<span className="text-slate-300">Keine Wartungshölle.</span>
|
||||
</h3>
|
||||
<span className="text-slate-200">Keine Abhängigkeiten.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Ich nutze keine Baukästen oder Plugin-Sammlungen, die sich selbst zerstören.
|
||||
Ihre Website besteht aus sauberem Code und einer klaren Struktur.
|
||||
</p>
|
||||
<LeadText className="text-xl md:text-2xl max-w-2xl text-slate-400">
|
||||
Ich nutze keine Baukästen, die sich selbst zerstören.
|
||||
Ihre Website besteht aus <span className="text-slate-900">sauberem Code</span>, der Ihnen gehört.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.4}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-8">
|
||||
<div className="p-8 bg-white border border-slate-100 rounded-2xl shadow-sm hover:border-slate-300 transition-colors">
|
||||
<div className="font-bold text-slate-900 mb-2 uppercase tracking-widest text-[10px]">Technik</div>
|
||||
<p className="text-slate-500 font-serif italic">Sauberer Code & feste Bausteine.</p>
|
||||
</div>
|
||||
<div className="p-8 bg-white border border-slate-100 rounded-2xl shadow-sm hover:border-slate-300 transition-colors">
|
||||
<div className="font-bold text-slate-900 mb-2 uppercase tracking-widest text-[10px]">Sicherheit</div>
|
||||
<p className="text-slate-500 font-serif italic">Wenn etwas geändert wird, geht nichts kaputt.</p>
|
||||
</div>
|
||||
<Card variant="white" padding="normal" className="group">
|
||||
<div className="space-y-4">
|
||||
<Label className="text-slate-900 mb-2">Code Qualität</Label>
|
||||
<H4 className="text-2xl">Langlebigkeit</H4>
|
||||
<BodyText>Modernste Web-Technologien für maximale Performance und Wartbarkeit.</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
<Card variant="white" padding="normal" className="group">
|
||||
<div className="space-y-4">
|
||||
<Label className="text-slate-900 mb-2">Sicherheit</Label>
|
||||
<H4 className="text-2xl">Resilienz</H4>
|
||||
<BodyText>Minimale Angriffsfläche durch Verzicht auf unnötige Drittanbieter-Software.</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
@@ -154,40 +171,48 @@ export default function WebsitesPage() {
|
||||
number="04"
|
||||
title="Inhalte"
|
||||
borderTop
|
||||
illustration={<LayerSeparation className="w-32 h-32" />}
|
||||
variant="gray"
|
||||
illustration={<LayerSeparation className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
Inhalte & Technik <br />
|
||||
<span className="text-slate-300">sind getrennt. Absichtlich.</span>
|
||||
</h3>
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Inhalte pflegen <br />
|
||||
<span className="text-slate-200">ohne Angst.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Sie können Inhalte selbst pflegen, ohne das Design oder die Technik zu gefährden.
|
||||
Sie können nichts kaputt machen. Ich verspreche es.
|
||||
</p>
|
||||
</Reveal>
|
||||
<Reveal delay={0.4}>
|
||||
<div className="flex flex-wrap gap-12 pt-8">
|
||||
<div className="space-y-4">
|
||||
<div className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-400">Was Sie tun</div>
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900">
|
||||
<Check className="w-5 h-5" />
|
||||
Inhalte pflegen
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4 opacity-30">
|
||||
<div className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-400">Was Sie ignorieren</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900 line-through">Design</div>
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900 line-through">Struktur</div>
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900 line-through">Technik</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 items-start">
|
||||
<div className="md:col-span-7">
|
||||
<Reveal delay={0.2}>
|
||||
<LeadText className="text-xl md:text-2xl text-slate-400">
|
||||
Sie können Texte und Bilder selbst anpassen, ohne das Design oder die Technik zu gefährden.
|
||||
Ein <span className="text-slate-900">intuitives System</span> sorgt dafür, dass alles an seinem Platz bleibt.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Reveal>
|
||||
<div className="md:col-span-5">
|
||||
<Reveal delay={0.4}>
|
||||
<Card variant="white" padding="normal" className="space-y-8">
|
||||
<div className="space-y-4">
|
||||
<Label>Ihre Freiheit</Label>
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900">
|
||||
<div className="w-8 h-8 rounded-full bg-slate-900 flex items-center justify-center">
|
||||
<Check className="w-3 h-3 text-white" />
|
||||
</div>
|
||||
Inhalte flexibel verwalten
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4 opacity-30">
|
||||
<Label>Mein Schutz</Label>
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900 line-through">Design-Chaos</div>
|
||||
<div className="flex items-center gap-3 text-xl font-bold text-slate-900 line-through">Technische Fehler</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@@ -196,87 +221,69 @@ export default function WebsitesPage() {
|
||||
number="05"
|
||||
title="Service"
|
||||
borderTop
|
||||
illustration={<DirectService className="w-32 h-32" />}
|
||||
illustration={<DirectService className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
<H3 className="text-3xl md:text-5xl leading-tight max-w-3xl">
|
||||
Änderungen sind <br />
|
||||
<span className="text-slate-300">einfach. Wirklich.</span>
|
||||
</h3>
|
||||
<span className="text-slate-200">Teil des Konzepts.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Neue Seite? Neue Funktion? Neue Idee? <br />
|
||||
Kein Ticket. Kein Formular. Kein Projektplan.
|
||||
</p>
|
||||
<LeadText className="text-xl md:text-2xl max-w-2xl text-slate-400">
|
||||
Ihr Business entwickelt sich weiter, Ihre Website auch. <br />
|
||||
Keine komplizierten Prozesse, sondern <span className="text-slate-900">direkte Umsetzung</span> Ihrer Ideen.
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
<Reveal delay={0.4}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 pt-8">
|
||||
<div className="p-10 bg-white border border-slate-100 rounded-3xl hover:border-slate-900 transition-all duration-500 group">
|
||||
<MessageSquare className="w-10 h-10 text-slate-200 group-hover:text-slate-900 transition-colors mb-6" />
|
||||
<h4 className="text-2xl font-bold text-slate-900 mb-2">Kurze Wege</h4>
|
||||
<p className="text-slate-500 font-serif italic">Sie schreiben mir, was Sie brauchen.</p>
|
||||
</div>
|
||||
<div className="p-10 bg-white border border-slate-100 rounded-3xl hover:border-slate-900 transition-all duration-500 group">
|
||||
<RefreshCw className="w-10 h-10 text-slate-200 group-hover:text-slate-900 transition-colors mb-6" />
|
||||
<h4 className="text-2xl font-bold text-slate-900 mb-2">Schnelle Umsetzung</h4>
|
||||
<p className="text-slate-500 font-serif italic">Ich setze es um. Fertig.</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 pt-8">
|
||||
<Card variant="white" padding="normal" className="group hover:border-slate-900">
|
||||
<ConceptCommunication className="w-12 h-12 mb-8 group-hover:scale-110 transition-all duration-700" />
|
||||
<div className="space-y-2">
|
||||
<H4 className="text-2xl">Direkter Draht</H4>
|
||||
<BodyText>Sie sprechen direkt mit dem Entwickler. Keine Stille Post.</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
<Card variant="white" padding="normal" className="group hover:border-slate-900">
|
||||
<ConceptPrototyping className="w-12 h-12 mb-8 group-hover:scale-110 transition-all duration-700" />
|
||||
<div className="space-y-2">
|
||||
<H4 className="text-2xl">Agile Anpassung</H4>
|
||||
<BodyText>Schnelle Iterationen statt langer Wartezeiten.</BodyText>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Why */}
|
||||
<Section
|
||||
number="06"
|
||||
title="Warum"
|
||||
borderTop
|
||||
illustration={<AgencyChaos className="w-32 h-32" />}
|
||||
>
|
||||
<div className="space-y-12">
|
||||
<Reveal>
|
||||
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
|
||||
15 Jahre Agenturen <br />
|
||||
<span className="text-slate-300">waren genug.</span>
|
||||
</h3>
|
||||
</Reveal>
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-xl md:text-2xl font-serif italic text-slate-600 max-w-2xl">
|
||||
Zu viele Meetings. Zu viele Konzepte. Zu viele Übergaben. Zu viele „eigentlich müsste man mal“.
|
||||
Meine Websites sind dafür gebaut, dass Dinge einfach passieren.
|
||||
</p>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
{/* Result */}
|
||||
<Section
|
||||
number="07"
|
||||
number="06"
|
||||
title="Ergebnis"
|
||||
borderTop
|
||||
variant="gray"
|
||||
illustration={<TaskDone className="w-32 h-32" />}
|
||||
illustration={<TaskDone className="w-24 h-24" />}
|
||||
>
|
||||
<div className="space-y-16">
|
||||
<Reveal>
|
||||
<h2 className="text-5xl md:text-8xl font-bold text-slate-900 tracking-tighter leading-[0.9]">
|
||||
Eine Website, die sich wie eine <br />
|
||||
<span className="text-slate-300">erledigte Aufgabe</span> anfühlt.
|
||||
</h2>
|
||||
<H3 className="text-4xl md:text-6xl tracking-tighter">
|
||||
Eine Website, die <br />
|
||||
<span className="text-slate-200">einfach läuft.</span>
|
||||
</H3>
|
||||
</Reveal>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12">
|
||||
{[
|
||||
{ title: 'Kein Stress', desc: 'Keine Wartungspflicht, keine Überraschungen.' },
|
||||
{ title: 'Keine Abhängigkeit', desc: 'Sauberer Code, der Ihnen gehört.' },
|
||||
{ title: 'Keine Agentur', desc: 'Direkter Kontakt, schnelle Ergebnisse.' },
|
||||
{ title: 'Kein Overhead', desc: 'Fokus auf das, was Ihre Kunden wirklich brauchen.' },
|
||||
{ title: 'Volle Kontrolle', desc: 'Der Code gehört Ihnen, ohne Vendor Lock-in.' },
|
||||
{ title: 'Echte Performance', desc: 'Messbare Geschwindigkeit für bessere Ergebnisse.' },
|
||||
].map((item, i) => (
|
||||
<Reveal key={i} delay={i * 0.1}>
|
||||
<div className="space-y-4">
|
||||
<div className="text-2xl font-bold tracking-tight text-slate-900">{item.title}</div>
|
||||
<p className="text-slate-500 font-serif italic text-lg">{item.desc}</p>
|
||||
<div className="space-y-4 group">
|
||||
<div className="w-8 h-px bg-slate-200 group-hover:w-full transition-all duration-1000" />
|
||||
<H4 className="text-2xl">{item.title}</H4>
|
||||
<LeadText className="text-lg text-slate-400">{item.desc}</LeadText>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
@@ -285,20 +292,14 @@ export default function WebsitesPage() {
|
||||
<Reveal delay={0.4}>
|
||||
<div className="pt-16 border-t border-slate-200 flex flex-col md:flex-row justify-between items-start md:items-center gap-8">
|
||||
<div className="space-y-2">
|
||||
<div className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-400">Technik</div>
|
||||
<p className="text-slate-500 font-serif italic text-lg">
|
||||
Modern, sicher, schnell. Aber das ist mein Problem, nicht Ihres.
|
||||
</p>
|
||||
<Label>Bereit für mehr?</Label>
|
||||
<LeadText className="text-2xl">
|
||||
Lassen Sie uns über Ihr nächstes Projekt sprechen.
|
||||
</LeadText>
|
||||
</div>
|
||||
<motion.a
|
||||
href="/contact"
|
||||
whileHover={{ scale: 1.05 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="inline-flex items-center gap-4 px-12 py-6 bg-slate-900 text-white rounded-full font-bold uppercase tracking-widest text-xs hover:bg-slate-800 transition-colors group"
|
||||
>
|
||||
<MotionButton href="/contact">
|
||||
Projekt anfragen
|
||||
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
|
||||
</motion.a>
|
||||
</MotionButton>
|
||||
</div>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
21
package-lock.json
generated
21
package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vercel/og": "^0.8.6",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.29.2",
|
||||
"ioredis": "^5.9.1",
|
||||
"lucide-react": "^0.468.0",
|
||||
@@ -25,6 +26,7 @@
|
||||
"react": "^19.2.3",
|
||||
"react-dom": "^19.2.3",
|
||||
"shiki": "^1.24.2",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"tailwindcss": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -1889,6 +1891,15 @@
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cluster-key-slot": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
|
||||
@@ -4575,6 +4586,16 @@
|
||||
"integrity": "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz",
|
||||
"integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.19",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vercel/og": "^0.8.6",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.29.2",
|
||||
"ioredis": "^5.9.1",
|
||||
"lucide-react": "^0.468.0",
|
||||
@@ -31,6 +32,7 @@
|
||||
"react": "^19.2.3",
|
||||
"react-dom": "^19.2.3",
|
||||
"shiki": "^1.24.2",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"tailwindcss": "^3.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
67
src/components/Button.tsx
Normal file
67
src/components/Button.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import * as React from 'react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface ButtonProps {
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
variant?: 'primary' | 'outline';
|
||||
className?: string;
|
||||
showArrow?: boolean;
|
||||
}
|
||||
|
||||
export const Button: React.FC<ButtonProps> = ({
|
||||
href,
|
||||
children,
|
||||
variant = 'primary',
|
||||
className = "",
|
||||
showArrow = true
|
||||
}) => {
|
||||
const baseStyles = "inline-flex items-center gap-4 rounded-full font-bold uppercase tracking-widest transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] group";
|
||||
|
||||
const variants = {
|
||||
primary: "px-10 py-5 bg-slate-900 text-white hover:bg-slate-800 hover:-translate-y-1 hover:shadow-2xl hover:shadow-slate-900/20 text-sm",
|
||||
outline: "px-8 py-4 border border-slate-200 bg-white text-slate-900 hover:border-slate-400 hover:bg-slate-50 hover:-translate-y-0.5 hover:shadow-xl hover:shadow-slate-100 text-sm"
|
||||
};
|
||||
|
||||
const content = (
|
||||
<>
|
||||
{children}
|
||||
{showArrow && <ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />}
|
||||
</>
|
||||
);
|
||||
|
||||
if (href.startsWith('#')) {
|
||||
return (
|
||||
<a href={href} className={`${baseStyles} ${variants[variant]} ${className}`}>
|
||||
{content}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={href} className={`${baseStyles} ${variants[variant]} ${className}`}>
|
||||
{content}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const MotionButton: React.FC<ButtonProps> = ({
|
||||
href,
|
||||
children,
|
||||
variant = 'primary',
|
||||
className = "",
|
||||
showArrow = true
|
||||
}) => {
|
||||
return (
|
||||
<motion.div
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
>
|
||||
<Button href={href} variant={variant} className={className} showArrow={showArrow}>
|
||||
{children}
|
||||
</Button>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
@@ -8,7 +8,6 @@ interface LineProps {
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
// ... existing components ...
|
||||
export const HeroLines: React.FC<LineProps> = ({ className = "", delay = 0 }) => {
|
||||
return (
|
||||
<svg className={`absolute pointer-events-none ${className}`} viewBox="0 0 800 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -216,150 +215,7 @@ export const ComparisonLines: React.FC<LineProps> = ({ className = "", delay = 0
|
||||
)
|
||||
}
|
||||
|
||||
// --- New Connector Components ---
|
||||
|
||||
export const ConnectorStart: React.FC<LineProps> = ({ className = "", delay = 0 }) => {
|
||||
return (
|
||||
<svg className={`absolute pointer-events-none ${className}`} viewBox="0 0 100 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<motion.path
|
||||
d="M 50 0 V 400"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay }}
|
||||
/>
|
||||
<circle cx="50" cy="10" r="8" className="fill-slate-900" />
|
||||
|
||||
{/* Multiple Pulses */}
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="4s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 400"
|
||||
/>
|
||||
</motion.circle>
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="4s"
|
||||
begin="2s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 400"
|
||||
/>
|
||||
</motion.circle>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorBranch: React.FC<LineProps> = ({ className = "", delay = 0 }) => {
|
||||
return (
|
||||
<svg className={`absolute pointer-events-none ${className}`} viewBox="0 0 200 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
{/* Main vertical line */}
|
||||
<motion.path
|
||||
d="M 50 0 V 400"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay }}
|
||||
/>
|
||||
{/* Branch */}
|
||||
<motion.path
|
||||
d="M 50 100 C 50 150, 100 150, 150 150 H 200"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay + 0.5 }}
|
||||
/>
|
||||
|
||||
{/* Pulses */}
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="4s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 400"
|
||||
/>
|
||||
</motion.circle>
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="3s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 100 C 50 150, 100 150, 150 150 H 200"
|
||||
/>
|
||||
</motion.circle>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorSplit: React.FC<LineProps> = ({ className = "", delay = 0 }) => {
|
||||
return (
|
||||
<svg className={`absolute pointer-events-none ${className}`} viewBox="0 0 200 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<motion.path
|
||||
d="M 50 0 V 50 C 50 100, 100 100, 150 100 H 200"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay }}
|
||||
/>
|
||||
<motion.path
|
||||
d="M 50 50 V 400"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay }}
|
||||
/>
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="4s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 400"
|
||||
/>
|
||||
</motion.circle>
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="3s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 50 C 50 100, 100 100, 150 100 H 200"
|
||||
/>
|
||||
</motion.circle>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConnectorEnd: React.FC<LineProps> = ({ className = "", delay = 0 }) => {
|
||||
return (
|
||||
<svg className={`absolute pointer-events-none ${className}`} viewBox="0 0 100 400" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<motion.path
|
||||
d="M 50 0 V 200"
|
||||
stroke="currentColor"
|
||||
strokeWidth="3"
|
||||
className="text-slate-300"
|
||||
initial={{ pathLength: 0 }}
|
||||
whileInView={{ pathLength: 1 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 1.5, delay: delay }}
|
||||
/>
|
||||
<circle cx="50" cy="200" r="8" className="fill-slate-900" />
|
||||
<motion.circle r="5" fill="currentColor" className="text-slate-900">
|
||||
<animateMotion
|
||||
dur="2s"
|
||||
repeatCount="indefinite"
|
||||
path="M 50 0 V 200"
|
||||
/>
|
||||
</motion.circle>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
export const ConnectorStart: React.FC<LineProps> = ({ className = "", delay = 0 }) => null;
|
||||
export const ConnectorBranch: React.FC<LineProps> = ({ className = "", delay = 0 }) => null;
|
||||
export const ConnectorSplit: React.FC<LineProps> = ({ className = "", delay = 0 }) => null;
|
||||
export const ConnectorEnd: React.FC<LineProps> = ({ className = "", delay = 0 }) => null;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import { Reveal } from '../Reveal';
|
||||
import { Label, H3, LeadText } from '../Typography';
|
||||
|
||||
interface ComparisonRowProps {
|
||||
negativeLabel: string;
|
||||
@@ -23,12 +24,12 @@ export const ComparisonRow: React.FC<ComparisonRowProps> = ({
|
||||
<Reveal delay={delay}>
|
||||
<div className={`flex flex-col ${reverse ? 'md:flex-row-reverse' : 'md:flex-row'} gap-8 md:gap-12 items-center`}>
|
||||
<div className="flex-1 p-8 md:p-10 bg-slate-50/50 rounded-2xl text-slate-400 border border-transparent w-full">
|
||||
<div className="text-[10px] font-bold uppercase tracking-[0.2em] mb-4 line-through decoration-slate-200">
|
||||
<Label className="mb-4 line-through decoration-slate-200">
|
||||
{negativeLabel}
|
||||
</div>
|
||||
<div className="text-lg md:text-xl font-serif italic line-through decoration-slate-200 leading-snug">
|
||||
</Label>
|
||||
<LeadText className="line-through decoration-slate-200 leading-snug">
|
||||
{negativeText}
|
||||
</div>
|
||||
</LeadText>
|
||||
</div>
|
||||
|
||||
<div className="shrink-0">
|
||||
@@ -36,12 +37,12 @@ export const ComparisonRow: React.FC<ComparisonRowProps> = ({
|
||||
</div>
|
||||
|
||||
<div className="flex-1 p-8 md:p-10 border border-slate-100 rounded-2xl bg-white hover:border-slate-200 transition-all duration-500 hover:shadow-xl hover:shadow-slate-100/50 w-full">
|
||||
<div className="text-[10px] font-bold uppercase tracking-[0.2em] text-slate-900 mb-4">
|
||||
<Label className="text-slate-900 mb-4">
|
||||
{positiveLabel}
|
||||
</div>
|
||||
<div className="text-2xl md:text-3xl font-bold text-slate-900 leading-tight tracking-tight">
|
||||
</Label>
|
||||
<H3 className="text-2xl md:text-3xl">
|
||||
{positiveText}
|
||||
</div>
|
||||
</H3>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
|
||||
@@ -13,3 +13,4 @@ export * from './HeroMainIllustration';
|
||||
export * from './ExperienceIllustration';
|
||||
export * from './ResponsibilityIllustration';
|
||||
export * from './ResultIllustration';
|
||||
export * from './WebsitesDescriptive';
|
||||
|
||||
68
src/components/Layout.tsx
Normal file
68
src/components/Layout.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import * as React from 'react';
|
||||
import { cn } from '../utils/cn';
|
||||
|
||||
export const BackgroundGrid: React.FC = () => (
|
||||
<div className="fixed inset-0 pointer-events-none -z-20 opacity-[0.01]" style={{
|
||||
backgroundImage: 'linear-gradient(#0f172a 1px, transparent 1px), linear-gradient(90deg, #0f172a 1px, transparent 1px)',
|
||||
backgroundSize: '60px 60px'
|
||||
}} />
|
||||
);
|
||||
|
||||
interface CardProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
variant?: 'white' | 'dark' | 'gray';
|
||||
hover?: boolean;
|
||||
padding?: 'none' | 'small' | 'normal' | 'large';
|
||||
}
|
||||
|
||||
export const Card: React.FC<CardProps> = ({
|
||||
children,
|
||||
className = "",
|
||||
variant = 'white',
|
||||
hover = true,
|
||||
padding = 'normal'
|
||||
}) => {
|
||||
const variants = {
|
||||
white: 'bg-white border-slate-100 text-slate-900 shadow-sm',
|
||||
dark: 'bg-slate-900 border-white/5 text-white shadow-xl',
|
||||
gray: 'bg-slate-50/50 border-slate-100 text-slate-900'
|
||||
};
|
||||
|
||||
const paddings = {
|
||||
none: 'p-0',
|
||||
small: 'p-6 md:p-8',
|
||||
normal: 'p-8 md:p-10',
|
||||
large: 'p-10 md:p-12'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn(
|
||||
"rounded-2xl border h-full flex flex-col justify-between transition-all duration-500 ease-out",
|
||||
variants[variant],
|
||||
paddings[padding],
|
||||
hover ? 'hover:border-slate-200 hover:shadow-md' : '',
|
||||
className
|
||||
)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Container: React.FC<{ children: React.ReactNode; className?: string; variant?: 'narrow' | 'normal' | 'wide' }> = ({
|
||||
children,
|
||||
className = "",
|
||||
variant = 'normal'
|
||||
}) => {
|
||||
const variants = {
|
||||
narrow: 'max-w-4xl',
|
||||
normal: 'max-w-6xl',
|
||||
wide: 'max-w-7xl'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn("mx-auto px-6 w-full", variants[variant], className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -2,6 +2,8 @@ import * as React from 'react';
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { Reveal } from './Reveal';
|
||||
import { H1, LeadText } from './Typography';
|
||||
import { cn } from '../utils/cn';
|
||||
|
||||
interface PageHeaderProps {
|
||||
title: React.ReactNode;
|
||||
@@ -11,18 +13,20 @@ interface PageHeaderProps {
|
||||
label: string;
|
||||
};
|
||||
backgroundSymbol?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
title,
|
||||
description,
|
||||
backLink,
|
||||
backgroundSymbol
|
||||
backgroundSymbol,
|
||||
className = ""
|
||||
}) => {
|
||||
return (
|
||||
<section className="narrow-container relative">
|
||||
<section className={cn("narrow-container relative pt-24 pb-16 md:pt-40 md:pb-24", className)}>
|
||||
{backgroundSymbol && (
|
||||
<div className="absolute -left-24 -top-24 text-[20rem] font-bold text-slate-50 select-none -z-10 opacity-50">
|
||||
<div className="absolute -left-24 -top-12 text-[20rem] md:text-[24rem] font-bold text-slate-50 select-none -z-10 opacity-40 tracking-tighter leading-none">
|
||||
{backgroundSymbol}
|
||||
</div>
|
||||
)}
|
||||
@@ -30,24 +34,24 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
|
||||
{backLink && (
|
||||
<Link
|
||||
href={backLink.href}
|
||||
className="inline-flex items-center gap-3 px-4 py-2 border border-slate-200 rounded-full text-slate-400 hover:text-slate-900 hover:border-slate-400 hover:bg-slate-50 mb-12 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-slate-100 font-bold text-[10px] uppercase tracking-[0.3em] group"
|
||||
className="inline-flex items-center gap-2 text-slate-400 hover:text-slate-900 mb-12 transition-colors font-bold text-[10px] uppercase tracking-[0.4em] group"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" /> {backLink.label}
|
||||
<ArrowLeft className="w-3 h-3 group-hover:-translate-x-1 transition-transform" /> {backLink.label}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<div className="space-y-16">
|
||||
<div className="space-y-8 relative">
|
||||
<Reveal>
|
||||
<h1 className="text-6xl md:text-8xl font-bold text-slate-900 tracking-tighter leading-[0.95]">
|
||||
<H1 className="max-w-4xl">
|
||||
{title}
|
||||
</h1>
|
||||
</H1>
|
||||
</Reveal>
|
||||
|
||||
{description && (
|
||||
<Reveal delay={0.2}>
|
||||
<p className="text-2xl md:text-3xl text-slate-500 font-serif italic leading-snug max-w-3xl">
|
||||
<LeadText className="text-xl md:text-2xl text-slate-400 leading-relaxed max-w-2xl font-serif italic">
|
||||
{description}
|
||||
</p>
|
||||
</LeadText>
|
||||
</Reveal>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { Reveal } from './Reveal';
|
||||
import { Label } from './Typography';
|
||||
import { cn } from '../utils/cn';
|
||||
|
||||
interface SectionProps {
|
||||
number?: string;
|
||||
@@ -9,7 +11,7 @@ interface SectionProps {
|
||||
delay?: number;
|
||||
variant?: 'white' | 'gray';
|
||||
borderTop?: boolean;
|
||||
connector?: React.ReactNode;
|
||||
borderBottom?: boolean;
|
||||
containerVariant?: 'narrow' | 'normal' | 'wide';
|
||||
illustration?: React.ReactNode;
|
||||
}
|
||||
@@ -22,93 +24,59 @@ export const Section: React.FC<SectionProps> = ({
|
||||
delay = 0,
|
||||
variant = 'white',
|
||||
borderTop = false,
|
||||
connector,
|
||||
borderBottom = false,
|
||||
containerVariant = 'narrow',
|
||||
illustration,
|
||||
}) => {
|
||||
const bgClass = variant === 'gray' ? 'bg-slate-50' : 'bg-white';
|
||||
const borderClass = borderTop ? 'border-t border-slate-100' : '';
|
||||
const bgClass = variant === 'gray' ? 'bg-slate-50/50' : 'bg-white';
|
||||
const borderTopClass = borderTop ? 'border-t border-slate-100' : '';
|
||||
const borderBottomClass = borderBottom ? 'border-b border-slate-100' : '';
|
||||
const containerClass = containerVariant === 'wide' ? 'wide-container' : containerVariant === 'normal' ? 'container' : 'narrow-container';
|
||||
|
||||
// If no number and title, or if we want to force a simple layout, we could add a prop.
|
||||
// But let's make it smart: if it's wide, maybe we want the title on top anyway?
|
||||
// The user specifically asked to move it above for the configurator.
|
||||
|
||||
const isTopTitle = containerVariant === 'wide';
|
||||
|
||||
return (
|
||||
<section className={`relative py-24 md:py-32 group ${bgClass} ${borderClass} ${className}`}>
|
||||
<div className={containerClass}>
|
||||
{isTopTitle ? (
|
||||
<div className="space-y-16">
|
||||
{(number || title) && (
|
||||
<div className="flex flex-col md:flex-row md:items-end gap-6 md:gap-12">
|
||||
{number && (
|
||||
<Reveal delay={delay}>
|
||||
<span className="block text-6xl md:text-8xl font-bold text-slate-100 leading-none select-none">
|
||||
{number}
|
||||
</span>
|
||||
</Reveal>
|
||||
)}
|
||||
{title && (
|
||||
<Reveal delay={delay + 0.1}>
|
||||
<div className="flex items-center gap-3 mb-2 md:mb-4">
|
||||
<div className="h-px w-6 bg-slate-900"></div>
|
||||
<h2 className="text-xs font-bold uppercase tracking-[0.3em] text-slate-900">
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div>{children}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 md:gap-16">
|
||||
{/* Sidebar: Number & Title */}
|
||||
<div className="md:col-span-3 relative">
|
||||
{/* Connector Line */}
|
||||
{connector && (
|
||||
<div className="absolute left-[2.5rem] top-0 bottom-0 w-24 hidden md:block -z-10 pointer-events-none">
|
||||
{connector}
|
||||
</div>
|
||||
<section className={cn(
|
||||
"relative py-24 md:py-40 group overflow-hidden",
|
||||
bgClass,
|
||||
borderTopClass,
|
||||
borderBottomClass,
|
||||
className
|
||||
)}>
|
||||
<div className={cn("relative z-10", containerClass)}>
|
||||
<div className="grid grid-cols-1 md:grid-cols-12 gap-12 md:gap-24">
|
||||
{/* Sidebar: Number & Title */}
|
||||
<div className="md:col-span-3">
|
||||
<div className="md:sticky md:top-40 space-y-8">
|
||||
{number && (
|
||||
<Reveal delay={delay}>
|
||||
<span className="block text-7xl md:text-8xl font-bold text-slate-100 leading-none select-none tracking-tighter">
|
||||
{number}
|
||||
</span>
|
||||
</Reveal>
|
||||
)}
|
||||
{title && (
|
||||
<Reveal delay={delay + 0.1}>
|
||||
<div className="flex items-center gap-4">
|
||||
<Label className="text-slate-900 text-[10px] tracking-[0.4em]">
|
||||
{title}
|
||||
</Label>
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
{illustration && (
|
||||
<Reveal delay={delay + 0.2}>
|
||||
<div className="pt-8 opacity-100 group-hover:scale-105 transition-transform duration-1000 ease-out origin-left grayscale hover:grayscale-0">
|
||||
{illustration}
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
|
||||
<div className="md:sticky md:top-32 space-y-6">
|
||||
{number && (
|
||||
<Reveal delay={delay}>
|
||||
<span className="block text-6xl md:text-8xl font-bold text-slate-100 leading-none select-none relative bg-white/0 backdrop-blur-[2px]">
|
||||
{number}
|
||||
</span>
|
||||
</Reveal>
|
||||
)}
|
||||
{title && (
|
||||
<Reveal delay={delay + 0.1}>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="h-px w-6 bg-slate-900"></div>
|
||||
<h2 className="text-xs font-bold uppercase tracking-[0.3em] text-slate-900">
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
{illustration && (
|
||||
<Reveal delay={delay + 0.2}>
|
||||
<div className="pt-12 opacity-100 group-hover:scale-110 transition-transform duration-700 origin-left">
|
||||
{illustration}
|
||||
</div>
|
||||
</Reveal>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="md:col-span-9">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="md:col-span-9">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
54
src/components/Typography.tsx
Normal file
54
src/components/Typography.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as React from 'react';
|
||||
|
||||
interface TypographyProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const H1: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<h1 className={`text-5xl md:text-7xl font-bold text-slate-900 tracking-tighter leading-[1.1] ${className}`}>
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
|
||||
export const H2: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<h2 className={`text-3xl md:text-5xl font-bold text-slate-900 tracking-tighter leading-tight ${className}`}>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
|
||||
export const H3: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<h3 className={`text-2xl md:text-4xl font-bold text-slate-900 tracking-tight leading-tight ${className}`}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
|
||||
export const H4: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<h4 className={`text-xl md:text-2xl font-bold text-slate-900 tracking-tight ${className}`}>
|
||||
{children}
|
||||
</h4>
|
||||
);
|
||||
|
||||
export const LeadText: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<p className={`text-lg md:text-xl font-serif italic text-slate-500 leading-relaxed ${className}`}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
|
||||
export const BodyText: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<p className={`text-base text-slate-500 leading-relaxed ${className}`}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
|
||||
export const Label: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<span className={`text-[10px] font-bold uppercase tracking-[0.3em] text-slate-400 block ${className}`}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
|
||||
export const MonoLabel: React.FC<TypographyProps> = ({ children, className = "" }) => (
|
||||
<span className={`text-[10px] font-mono uppercase tracking-[0.2em] text-slate-400 block ${className}`}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
6
src/utils/cn.ts
Normal file
6
src/utils/cn.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Reference in New Issue
Block a user