This commit is contained in:
2026-01-29 19:06:45 +01:00
parent 2b56f317f7
commit 1cc583c976
7 changed files with 675 additions and 176 deletions

View File

@@ -1,191 +1,301 @@
'use client';
import React, { useState, useEffect } from 'react';
import { MediumCard } from '../src/components/MediumCard';
import { SearchBar } from '../src/components/SearchBar';
import { Tag } from '../src/components/Tag';
import { blogPosts } from '../src/data/blogPosts';
export default function HomePage() {
const [searchQuery, setSearchQuery] = useState('');
const [filteredPosts, setFilteredPosts] = useState(blogPosts);
// Sort posts by date
const allPosts = [...blogPosts].sort((a, b) =>
new Date(b.date).getTime() - new Date(a.date).getTime()
);
// Get unique tags
const allTags = Array.from(new Set(allPosts.flatMap(post => post.tags || [])));
useEffect(() => {
const query = searchQuery.toLowerCase().trim();
if (query.startsWith('#')) {
const tag = query.slice(1);
setFilteredPosts(allPosts.filter(post =>
post.tags?.some(t => t.toLowerCase() === tag.toLowerCase())
));
} else {
setFilteredPosts(allPosts.filter(post => {
const title = post.title.toLowerCase();
const description = post.description.toLowerCase();
const tags = (post.tags || []).join(' ').toLowerCase();
return title.includes(query) || description.includes(query) || tags.includes(query);
}));
}
}, [searchQuery]);
const filterByTag = (tag: string) => {
setSearchQuery(`#${tag}`);
};
import React from 'react';
import Link from 'next/link';
import { Check, ArrowRight, MessageSquare } from 'lucide-react';
export default function LandingPage() {
return (
<>
{/* Clean Hero Section */}
<section className="pt-10 pb-8 md:pt-12 md:pb-10 relative overflow-hidden">
{/* Animated Background */}
<div className="absolute inset-0 bg-gradient-to-br from-white via-slate-50/30 to-blue-50/20 animate-gradient-shift"></div>
{/* Morphing Blob */}
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
<div className="w-48 h-48 bg-gradient-to-br from-blue-200/15 via-purple-200/10 to-indigo-200/15 animate-morph"></div>
<div className="flex flex-col gap-32 py-20 md:py-32">
{/* Hero Section */}
<section className="narrow-container animate-fade-in">
<h1 className="text-4xl md:text-6xl font-bold text-slate-900 tracking-tight mb-10 leading-[1.1]">
Digitale Systeme für Unternehmen, die keinen Overhead wollen
</h1>
<div className="space-y-4 text-xl md:text-2xl text-slate-500 font-serif italic leading-relaxed">
<p>Agenturen sind zu langsam.</p>
<p>CMS will keiner pflegen.</p>
<p>Digitale Themen bleiben liegen.</p>
</div>
<p className="mt-12 text-2xl font-semibold text-slate-900">
Ich mache das anders.
</p>
</section>
{/* Animated Drawing Paths */}
<svg className="absolute inset-0 w-full h-full pointer-events-none" viewBox="0 0 100 100">
<path d="M10,50 Q50,10 90,50 T90,90" stroke="rgba(59,130,246,0.1)" strokeWidth="0.5" fill="none" className="animate-draw"></path>
<path d="M10,70 Q50,30 90,70" stroke="rgba(147,51,234,0.1)" strokeWidth="0.5" fill="none" className="animate-draw-delay"></path>
<path d="M20,20 Q50,80 80,20" stroke="rgba(16,185,129,0.1)" strokeWidth="0.5" fill="none" className="animate-draw-reverse"></path>
</svg>
{/* Was ich mache */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Was ich mache</h2>
</div>
<div className="md:col-span-8">
<div className="prose prose-slate font-serif text-xl leading-relaxed text-slate-700">
<p>
Ich setze digitale Systeme für Unternehmen um direkt, sauber und ohne Agentur-Zirkus.
</p>
<p className="font-sans font-bold text-slate-900 mt-8 text-2xl">
Websites, Funktionen, Systeme, interne Tools.
</p>
<p className="mt-4">
Keine Workshops. Keine Tickets. Kein Tech-Blabla.
</p>
<p className="mt-10 text-slate-900">
Sie erklären mir, was Sie brauchen. <br />
Ich sorge dafür, dass es funktioniert.
</p>
</div>
</div>
</div>
</section>
{/* Floating Shapes */}
<div className="absolute top-10 left-10 w-20 h-20 bg-blue-100/20 rounded-full animate-float-1"></div>
<div className="absolute top-20 right-20 w-16 h-16 bg-indigo-100/20 rotate-45 animate-float-2"></div>
<div className="absolute bottom-20 left-1/4 w-12 h-12 bg-purple-100/20 rounded-full animate-float-3"></div>
<div className="absolute bottom-10 right-1/3 w-24 h-24 bg-cyan-100/20 animate-float-4"></div>
{/* Für wen das ist */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Für wen das ist</h2>
</div>
<div className="md:col-span-8">
<p className="text-xl text-slate-900 font-bold mb-8">Für Unternehmen, die:</p>
<ul className="space-y-4 mb-12">
{[
'regelmäßig Änderungen an Website oder Systemen brauchen',
'keine Lust auf Agenturen haben',
'kein CMS anfassen wollen',
'keine Tickets schreiben möchten',
'keinen Entwickler einstellen wollen',
'und wollen, dass Dinge einfach erledigt werden',
].map((item, i) => (
<li key={i} className="flex items-start gap-4">
<Check className="w-5 h-5 text-slate-900 shrink-0 mt-1" />
<span className="text-lg text-slate-600 font-serif">{item}</span>
</li>
))}
</ul>
<div className="p-8 bg-slate-50 rounded-sm border-l-4 border-slate-900">
<p className="text-xl font-serif italic text-slate-700 leading-relaxed">
Wenn bei Ihnen öfter der Satz fällt: <br />
<span className="font-bold not-italic text-slate-900">Das müsste man mal machen </span>
</p>
<p className="mt-4 text-slate-500">
aber es passiert nie dann sind Sie hier richtig.
</p>
</div>
</div>
</div>
</section>
<div className="max-w-3xl mx-auto px-6 relative z-10">
<div className="text-center animate-fade-in">
<h1 className="text-3xl md:text-4xl font-serif font-light text-slate-900 tracking-tight mb-3">
Marc Mintel
</h1>
<p className="text-base md:text-lg text-slate-600 leading-relaxed font-serif italic">
"A public notebook of things I figured out, mistakes I made, and tools I tested."
{/* Das eigentliche Problem */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Das Problem</h2>
</div>
<div className="md:col-span-8">
<div className="prose prose-slate font-serif text-xl leading-relaxed text-slate-700">
<p>
Digitale Arbeit scheitert nicht an Technik. <br />
Sie scheitert an <span className="text-slate-900 font-bold underline decoration-slate-200 underline-offset-4">Zuständigkeit</span>.
</p>
<div className="space-y-4 mt-10 font-sans text-base not-italic text-slate-500">
<p className="pb-4 border-b border-slate-100">Agenturen wollen Projekte.</p>
<p className="pb-4 border-b border-slate-100">Mitarbeiter haben Wichtigeres zu tun.</p>
<p className="pb-4 border-b border-slate-100">IT ist ausgelastet.</p>
<p>Kleine Aufgaben sind zu klein für große Angebote.</p>
</div>
<p className="mt-10 font-bold text-slate-900 text-2xl">Also bleibt alles liegen.</p>
</div>
</div>
</div>
</section>
{/* Warum keine Agentur */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Warum keine Agentur</h2>
</div>
<div className="md:col-span-8">
<p className="text-xl font-serif text-slate-600 mb-16 leading-relaxed">
Ich habe über 15 Jahre in Agenturen gearbeitet. Ich kenne das Spiel. Und ich weiß, warum es nervt.
</p>
<div className="flex items-center justify-center gap-3 text-[13px] text-slate-500 font-sans mt-3">
<span className="inline-flex items-center gap-1">
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true"><path d="M10 2a8 8 0 100 16 8 8 0 000-16zm0 12a4 4 0 110-8 4 4 0 010 8z"/></svg>
Vulkaneifel, Germany
</span>
<span aria-hidden="true"></span>
<span>Digital problem solver</span>
<div className="space-y-20">
<div className="group">
<h3 className="text-2xl font-bold text-slate-900 mb-6">Agenturen machen einfache Dinge kompliziert</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 items-start">
<div className="space-y-2 text-slate-400 text-sm font-mono">
<p>Ein Button ändern?</p>
<p> Konzeptcall</p>
<p> Abstimmung</p>
<p> internes Meeting</p>
<p> Angebot</p>
<p> Warten</p>
<p> Rechnung</p>
</div>
<div className="pt-4 border-t-2 border-slate-900">
<p className="font-bold text-slate-900 mb-2 uppercase tracking-wider text-xs">Mein Ansatz</p>
<p className="text-2xl font-bold text-slate-900">Ich mache es einfach fertig.</p>
</div>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-16">
<div>
<h4 className="font-bold text-slate-900 mb-3 text-lg">Prozesse statt Ergebnisse</h4>
<p className="text-slate-500 font-serif leading-relaxed">
Workshops, Slides, Roadmaps. Klingt nach Fortschritt, ist oft nur Beschäftigungstherapie. Bei mir zählt nur Umsetzung.
</p>
</div>
<div>
<h4 className="font-bold text-slate-900 mb-3 text-lg">Stundenabrechnung</h4>
<p className="text-slate-500 font-serif leading-relaxed">
Das dauert nur kurz Überraschung auf der Rechnung. Ich arbeite mit Fixpreisen. Sie wissen vorher, was es kostet.
</p>
</div>
<div>
<h4 className="font-bold text-slate-900 mb-3 text-lg">Aufgaben-Ping-Pong</h4>
<p className="text-slate-500 font-serif leading-relaxed">
Heute Projektmanager, morgen Entwickler, übermorgen niemand. Bei mir: Eine Person. Eine Verantwortung.
</p>
</div>
<div>
<h4 className="font-bold text-slate-900 mb-3 text-lg">Verschwinden nach dem Projekt</h4>
<p className="text-slate-500 font-serif leading-relaxed">
Kleine Änderung? Neues Angebot. Dringend? Warteschleife. Ich bleibe, solange Sie Dinge brauchen.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Search */}
<section className="mb-8 mt-8">
<div id="search-container">
<SearchBar value={searchQuery} onChange={setSearchQuery} />
</div>
</section>
{/* Topics */}
{allTags.length > 0 && (
<section className="mb-8">
<h2 className="text-lg font-semibold text-slate-800 mb-4">Topics</h2>
<div className="tag-cloud flex flex-wrap gap-2">
{allTags.map((tag, index) => (
<button
key={tag}
onClick={() => filterByTag(tag)}
className="inline-block"
>
<Tag tag={tag} index={index} />
</button>
))}
{/* Wie ich arbeite */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Arbeitsweise</h2>
</div>
</section>
)}
{/* All Posts */}
<section>
<div id="posts-container" className="not-prose grid grid-cols-1 md:grid-cols-2 gap-3 md:gap-4">
{filteredPosts.length === 0 ? (
<div className="empty-state col-span-full">
<p>No posts found matching your criteria.</p>
<div className="md:col-span-8">
<p className="text-2xl font-bold text-slate-900 mb-8">
Ich baue zuerst. Dann reden wir drüber.
</p>
<div className="prose prose-slate font-serif text-xl leading-relaxed text-slate-700">
<p>
Sie erklären mir Ihre Vorstellung. Ich setze den ersten echten Stand um.
</p>
<div className="flex flex-wrap gap-x-8 gap-y-2 my-10 not-prose border-y border-slate-100 py-6">
<span className="text-sm font-bold text-slate-400 uppercase tracking-widest">Keine Slides</span>
<span className="text-sm font-bold text-slate-400 uppercase tracking-widest">Kein Konzept-PDF</span>
<span className="text-sm font-bold text-slate-400 uppercase tracking-widest">Kein Ratespiel</span>
</div>
<p>
Dann arbeiten wir direkt am Ergebnis, bis es passt. Ohne jedes Mal ein neues Angebot. Ohne Scope-Diskussionen. Ohne Theater.
</p>
</div>
) : (
filteredPosts.map(post => (
<MediumCard key={post.slug} post={post} />
))
)}
</div>
</div>
</section>
<style jsx global>{`
@keyframes gradient-shift {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.animate-gradient-shift {
background-size: 200% 200%;
animation: gradient-shift 20s ease infinite;
}
@keyframes morph {
0%, 100% { border-radius: 50%; transform: scale(1) rotate(0deg); }
25% { border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; transform: scale(1.1) rotate(90deg); }
50% { border-radius: 20% 80% 20% 80% / 80% 20% 80% 20%; transform: scale(0.9) rotate(180deg); }
75% { border-radius: 70% 30% 50% 50% / 50% 70% 30% 50%; transform: scale(1.05) rotate(270deg); }
}
.animate-morph {
animation: morph 25s ease-in-out infinite;
}
@keyframes draw {
to { stroke-dashoffset: 0; }
}
.animate-draw {
stroke-dasharray: 200;
stroke-dashoffset: 200;
animation: draw 8s ease-in-out infinite alternate;
}
.animate-draw-delay {
stroke-dasharray: 200;
stroke-dashoffset: 200;
animation: draw 8s ease-in-out infinite alternate 4s;
}
.animate-draw-reverse {
stroke-dasharray: 200;
stroke-dashoffset: 200;
animation: draw 8s ease-in-out infinite alternate-reverse 2s;
}
@keyframes float-1 {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-20px) rotate(180deg); }
}
.animate-float-1 { animation: float-1 15s ease-in-out infinite; }
@keyframes float-2 {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-15px) rotate(90deg); }
}
.animate-float-2 { animation: float-2 18s ease-in-out infinite; }
@keyframes float-3 {
0%, 100% { transform: translateY(0px) scale(1); }
50% { transform: translateY(-10px) scale(1.1); }
}
.animate-float-3 { animation: float-3 12s ease-in-out infinite; }
@keyframes float-4 {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-25px) rotate(-90deg); }
}
.animate-float-4 { animation: float-4 20s ease-in-out infinite; }
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-in { animation: fadeIn 0.6s ease-out both; }
`}</style>
</>
{/* Was ich konkret umsetze */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Leistungen</h2>
</div>
<div className="md:col-span-8">
<div className="space-y-20">
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-6">Websites</h3>
<ul className="space-y-3 text-slate-600 font-serif text-lg">
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> neue Websites (klarer Standard)</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> bestehende Websites übernehmen</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Seiten ändern oder ergänzen</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Performance & SEO</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Hosting & Betrieb (inklusive)</li>
</ul>
<div className="mt-8">
<Link href="/websites" className="inline-flex items-center gap-2 text-slate-900 font-bold border-b-2 border-slate-900 pb-1 hover:text-slate-600 hover:border-slate-300 transition-all">
Details zu Websites & Preisen <ArrowRight className="w-4 h-4" />
</Link>
</div>
</div>
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-6">Funktionen & Systeme</h3>
<ul className="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-3 text-slate-600 font-serif text-lg">
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Produktbereiche</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Blogs, News, Jobs</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Formulare</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Suche & Filter</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> PDF-Generatoren</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> API-Ausgaben & Daten-Sync</li>
</ul>
</div>
<div>
<h3 className="text-2xl font-bold text-slate-900 mb-6">Interne Tools</h3>
<ul className="space-y-3 text-slate-600 font-serif text-lg">
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> kleine Inhouse-Tools</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Excel ersetzen</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Automatisierung</li>
<li className="flex items-center gap-3"><Check className="w-4 h-4 text-slate-300" /> Importe & Exporte</li>
</ul>
</div>
</div>
</div>
</div>
</section>
{/* Warum Kunden bleiben */}
<section className="narrow-container">
<div className="grid grid-cols-1 md:grid-cols-12 gap-8">
<div className="md:col-span-4">
<h2 className="text-sm font-bold uppercase tracking-widest text-slate-400 mt-0">Vorteile</h2>
</div>
<div className="md:col-span-8">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-10">
{[
{ label: 'Schnelligkeit', desc: 'Dinge passieren schnell' },
{ label: 'Erledigt', desc: 'Aufgaben verschwinden wirklich' },
{ label: 'Kein Erklären', desc: 'Ich verstehe, was Sie brauchen' },
{ label: 'Kein Nachfassen', desc: 'Ich melde mich, wenn es fertig ist' },
{ label: 'Kein Stress', desc: 'Kein Projektstress' },
{ label: 'Ruhe', desc: 'Kein Agentur-Zirkus' },
].map((item, i) => (
<div key={i} className="border-l border-slate-100 pl-6">
<div className="font-bold text-slate-900 mb-1 text-lg">{item.label}</div>
<div className="text-slate-500 font-serif">{item.desc}</div>
</div>
))}
</div>
<p className="mt-20 text-4xl font-serif italic text-slate-900">
Kurz: Ruhe.
</p>
</div>
</div>
</section>
{/* CTA */}
<section className="narrow-container">
<div className="bg-slate-900 text-white p-12 md:p-20 rounded-sm text-center">
<h2 className="text-3xl md:text-5xl font-bold mb-8 tracking-tight">Interesse?</h2>
<p className="text-xl md:text-2xl mb-12 text-slate-400 font-serif leading-relaxed">
Schreiben Sie mir einfach, was Sie brauchen. <br />
Ich sage Ihnen ehrlich, ob ich es mache und was es kostet.
</p>
<a
href="mailto:marc@mintel.me"
className="inline-flex items-center gap-3 bg-white text-slate-900 px-10 py-5 rounded-sm font-bold text-lg hover:bg-slate-100 transition-colors"
>
<MessageSquare className="w-5 h-5" />
Projekt anfragen
</a>
<div className="mt-12">
<Link href="/blog" className="text-slate-500 hover:text-white text-sm font-mono uppercase tracking-widest transition-colors">
Zum Blog
</Link>
</div>
</div>
</section>
</div>
);
}