3 Commits

Author SHA1 Message Date
03fa2ea4a9 about
Some checks failed
Build & Deploy Mintel Blog / build-and-deploy (push) Failing after 57s
2026-01-30 23:08:37 +01:00
6beaf3c0aa websites 2026-01-30 22:33:29 +01:00
615e8b4b4b websites page 2026-01-30 22:28:39 +01:00
15 changed files with 1309 additions and 132 deletions

349
app/about/page.tsx Normal file
View File

@@ -0,0 +1,349 @@
import * as React from 'react';
import Image from 'next/image';
import { PageHeader } from '../../src/components/PageHeader';
import { Section } from '../../src/components/Section';
import { Reveal } from '../../src/components/Reveal';
import {
ExperienceIllustration,
ResponsibilityIllustration,
ResultIllustration,
ConceptSystem,
ConceptTarget,
ContactIllustration,
ConnectorBranch,
ConnectorStart,
ConnectorEnd,
ConnectorSplit,
HeroLines,
ParticleNetwork,
GridLines
} from '../../src/components/Landing';
import { Check, ArrowRight } from 'lucide-react';
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'
}} />
{/* Hero Section */}
<section className="relative pt-40 pb-32 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>
<div className="absolute right-0 top-0 w-96 h-96 opacity-5 pointer-events-none">
<GridLines />
</div>
<div className="narrow-container 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="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="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"
/>
</div>
</div>
</div>
</Reveal>
<div className="space-y-6 max-w-2xl">
<Reveal delay={0.1}>
<div className="flex items-center justify-center gap-3 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>
<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)"
/>
</div>
</div>
</div>
{/* 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" />
</section>
{/* Section 01: Experience */}
<Section
number="01"
title="Erfahrung"
borderTop
connector={<ConnectorStart className="h-full" />}
illustration={<ExperienceIllustration 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 baue Websites und Systeme seit über 15 Jahren. <br />
<span className="text-slate-300">Weil ich es hasse, wenn Dinge nicht funktionieren.</span>
</h3>
</Reveal>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<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>
<ul className="space-y-4">
{[
'Marketingversprechen zerlegt',
'Systeme repariert, die „fertig“ waren',
'Gelernt, wie man Dinge baut, die einfach laufen'
].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>
))}
</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}
</span>
))}
</div>
</div>
</Reveal>
</div>
</div>
</Section>
{/* Section 02: Responsibility */}
<Section
number="02"
title="Verantwortung"
variant="gray"
borderTop
connector={<ConnectorBranch className="h-full" />}
illustration={<ResponsibilityIllustration 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 fast alle Fehler schon für Sie gemacht. <br />
<span className="text-slate-300">(Damit Sie sie nicht machen müssen)</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">
<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>
</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>
</Reveal>
</div>
</div>
</div>
</Section>
{/* Section 03: Systems */}
<Section
number="03"
title="Philosophie"
borderTop
connector={<ConnectorSplit className="h-full" />}
illustration={<ConceptSystem className="w-32 h-32" />}
>
<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>
</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>
</Reveal>
<div className="grid grid-cols-2 gap-4">
{['Schnell', 'Stabil', 'Boring', 'Erweiterbar', 'Wartungsarm', 'Unabhängig'].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>
</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>
</Reveal>
</div>
</div>
</Section>
{/* Section 04: Roles */}
<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" />}
>
<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>
</Reveal>
<div className="grid grid-cols-1 md:grid-cols-2 gap-12">
<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="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}
</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">
{[
{ 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.' }
].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>
<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>
</div>
</Reveal>
))}
</div>
</div>
</div>
</div>
</div>
</Section>
{/* Section 06: Today */}
<Section
number="06"
title="Heute"
variant="gray"
borderTop
connector={<ConnectorEnd className="h-full" />}
illustration={<ContactIllustration 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">
Heute baue ich Websites für Unternehmen, die keine Lust mehr auf Chaos haben.
</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" />
<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>
<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"
>
Projekt anfragen
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
</a>
</div>
</div>
</div>
</div>
</Section>
</div>
);
}

View File

@@ -1,147 +1,307 @@
import { Info, Minus } from 'lucide-react';
'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';
import {
SystemArchitecture,
SpeedPerformance,
SolidFoundation,
LayerSeparation,
DirectService,
AgencyChaos,
TaskDone
} from '../../src/components/Landing/Illustrations/WebsitesDescriptive';
import { motion } from 'framer-motion';
export default function WebsitesPage() {
return (
<div className="flex flex-col gap-48 py-12 md:py-24 overflow-hidden">
<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'
}} />
<PageHeader
title={<>Websites <br /><span className="text-slate-200">& Preise.</span></>}
description="Ich baue Websites mit klaren Preisen und Ergebnissen keine Stunden, keine Überraschungen."
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."
backLink={{ href: '/', label: 'Zurück' }}
backgroundSymbol=""
backgroundSymbol="W"
/>
{/* 1. Website - Designed Pricing */}
<Section number="01" title="Die Basis">
<div className="space-y-20">
{/* Intro / Problem */}
<Section
number="01"
title="Der Ansatz"
borderTop
illustration={<SystemArchitecture className="w-32 h-32" />}
>
<div className="space-y-12">
<Reveal>
<div className="border-l-4 border-slate-900 pl-12 py-6">
<div className="flex flex-col md:flex-row md:items-baseline gap-6 mb-8">
<div className="text-7xl md:text-9xl font-bold text-slate-900 tracking-tighter">6.000 </div>
<div className="text-slate-300 font-serif italic text-2xl">einmalig</div>
</div>
<p className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tighter">
Die Grundlage für jede Website.
</p>
</div>
<h3 className="text-3xl md:text-5xl font-bold text-slate-900 leading-tight tracking-tight max-w-3xl">
Ich baue Websites wie Systeme <br />
<span className="text-slate-300">nicht wie Broschüren.</span>
</h3>
</Reveal>
<Reveal delay={0.2}>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-16 gap-y-8">
{[
'Projekt-Setup & Infrastruktur',
'Hosting-Bereitstellung',
'Grundstruktur & Design-Vorlage',
'technisches SEO-Basics',
'Analytics (mit Mail-Report)',
'Livegang',
].map((item, i) => (
<div key={i} className="flex items-center gap-4 text-xl text-slate-600 font-serif border-b border-slate-100 pb-4">
<div className="w-1.5 h-1.5 bg-slate-900 rounded-full"></div>
<span>{item}</span>
</div>
))}
</div>
</Reveal>
<Reveal delay={0.4}>
<div className="pt-12 flex items-start gap-4 text-sm text-slate-400 italic font-serif max-w-md">
<Info className="w-5 h-5 shrink-0 mt-0.5 text-slate-200" />
<p>Enthält keine Seiten, Inhalte oder Funktionen. Diese werden nach Bedarf ergänzt.</p>
</div>
</Reveal>
</div>
</Section>
{/* 2. Entwicklung - Designed Grid */}
<Section number="02" title="Produktion">
<div className="space-y-32">
{/* Seite */}
<Reveal>
<div className="relative group p-12 border border-slate-200 rounded-[3rem] bg-white hover:border-slate-400 transition-all duration-500">
<div className="absolute -left-12 top-0 text-6xl font-bold text-slate-50 group-hover:text-slate-100 transition-colors opacity-50">S</div>
<div className="flex justify-between items-baseline mb-8 border-b border-slate-100 pb-6">
<h3 className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">Seite</h3>
<div className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">800 </div>
</div>
<p className="text-2xl md:text-3xl text-slate-500 font-serif italic leading-tight max-w-2xl">
Individuell gestaltete Seite mit Layout, Struktur, Textaufteilung, responsivem Design.
</p>
</div>
</Reveal>
{/* Feature */}
<Reveal delay={0.2}>
<div className="relative group p-12 border border-slate-200 rounded-[3rem] bg-white hover:border-slate-400 transition-all duration-500">
<div className="absolute -left-12 top-0 text-6xl font-bold text-slate-50 group-hover:text-slate-100 transition-colors opacity-50">F</div>
<div className="flex justify-between items-baseline mb-8 border-b border-slate-100 pb-6">
<h3 className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">Feature</h3>
<div className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">2.000 </div>
</div>
<p className="text-2xl md:text-3xl text-slate-500 font-serif italic leading-tight max-w-2xl mb-12">
Ein in sich geschlossenes System mit Datenstruktur, Darstellung und Pflegefähigkeit.
</p>
<div className="flex flex-wrap gap-x-8 gap-y-4">
{['Blog', 'News', 'Jobs', 'Referenzen', 'Events', 'Produktbereich'].map(tag => (
<span key={tag} className="text-[10px] font-bold uppercase tracking-[0.3em] text-slate-300 hover:text-slate-900 transition-colors cursor-default">{tag}</span>
))}
</div>
</div>
</Reveal>
{/* Funktion */}
<Reveal delay={0.4}>
<div className="relative group p-12 border border-slate-200 rounded-[3rem] bg-white hover:border-slate-400 transition-all duration-500">
<div className="absolute -left-12 top-0 text-6xl font-bold text-slate-50 group-hover:text-slate-100 transition-colors opacity-50">L</div>
<div className="flex justify-between items-baseline mb-8 border-b border-slate-100 pb-6">
<h3 className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">Funktion</h3>
<div className="text-4xl md:text-5xl font-bold text-slate-900 tracking-tighter">1.000 </div>
</div>
<p className="text-2xl md:text-3xl text-slate-500 font-serif italic leading-tight max-w-2xl mb-12">
Funktionen liefern Logik und Interaktion.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-16 gap-y-6 text-[10px] font-bold uppercase tracking-[0.2em] text-slate-400">
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> Kontaktformular</div>
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> Suche & Filter</div>
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> PDF-Export</div>
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> API-Anbindungen</div>
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> Mailversand</div>
<div className="flex items-center gap-4 border-b border-slate-50 pb-2"><Minus className="w-4 h-4 text-slate-200" /> Automatisierung</div>
</div>
</div>
</Reveal>
</div>
</Section>
{/* 5. Betrieb - Designed Box */}
<Section number="03" title="Betrieb">
<Reveal width="100%">
<div className="bg-white border border-slate-200 rounded-[3rem] p-16 md:p-24 space-y-16 relative overflow-hidden -mx-4 md:-mx-24 hover:border-slate-400 transition-all duration-500">
<div className="absolute top-0 right-0 text-[20rem] font-bold text-slate-50 select-none translate-x-1/4 -translate-y-1/4 opacity-50">B</div>
<div className="flex items-baseline gap-6">
<div className="text-7xl md:text-9xl font-bold tracking-tighter text-slate-900">120 </div>
<div className="text-slate-400 font-serif italic text-2xl">/ Monat</div>
</div>
<p className="text-3xl md:text-4xl font-bold leading-tight tracking-tight text-slate-900">
Hosting, Wartung & Sicherheit. <br />
<span className="text-slate-400">Damit Sie sich um nichts kümmern müssen.</span>
<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>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-16 gap-y-8 pt-12 border-t border-slate-200">
</Reveal>
<Reveal delay={0.4}>
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 pt-8">
{[
'Webhosting & Verfügbarkeit',
'Sicherheitsupdates & Backups',
'Analytics inkl. Reports',
'Medien-Speicher (20 GB)',
{ label: 'Stabil', icon: Shield },
{ label: 'Schnell', icon: Zap },
{ label: 'Vorhersehbar', icon: Layout },
{ label: 'Sicher', icon: Info },
].map((item, i) => (
<div key={i} className="flex items-center gap-4 text-xl text-slate-600 font-serif">
<div className="w-1.5 h-1.5 bg-slate-900 rounded-full"></div>
<span>{item}</span>
<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>
))}
</div>
</Reveal>
</div>
</Section>
{/* Speed */}
<Section
number="02"
title="Performance"
borderTop
illustration={<SpeedPerformance 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">
Geschwindigkeit ist <br />
<span className="text-slate-300">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>
</Reveal>
</div>
</Section>
{/* No Maintenance */}
<Section
number="03"
title="Wartungsfrei"
borderTop
illustration={<SolidFoundation 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">
Keine Plugins. <br />
<span className="text-slate-300">Keine Wartungshölle.</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>
</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>
</div>
</Reveal>
</div>
</Section>
{/* Content/Tech Separation */}
<Section
number="04"
title="Inhalte"
borderTop
illustration={<LayerSeparation 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">
Inhalte & Technik <br />
<span className="text-slate-300">sind getrennt. Absichtlich.</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>
</Reveal>
</div>
</Section>
{/* Simple Changes */}
<Section
number="05"
title="Service"
borderTop
illustration={<DirectService 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">
Änderungen sind <br />
<span className="text-slate-300">einfach. Wirklich.</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>
</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>
</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"
title="Ergebnis"
borderTop
variant="gray"
illustration={<TaskDone className="w-32 h-32" />}
>
<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>
</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.' },
].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>
</Reveal>
))}
</div>
<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>
</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"
>
Projekt anfragen
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
</motion.a>
</div>
</Reveal>
</div>
</Section>
</div>
);

123
docs/ABOUT.md Normal file
View File

@@ -0,0 +1,123 @@
Über mich
Ich baue Websites und Systeme seit über 15 Jahren.
Nicht weil ich Websites so liebe sondern weil ich es hasse, wenn Dinge nicht funktionieren.
In diesen 15 Jahren habe ich:
• Agenturen von innen gesehen
• Konzerne erlebt
• Startups aufgebaut
• Marketingversprechen zerlegt
• Systeme repariert, die „fertig“ waren
• und gelernt, wie man Dinge baut, die einfach laufen
Heute mache ich das ohne Agentur-Zwischenschichten.
Direkt. Sauber. Verantwortlich.
Ich habe fast alle Fehler schon für Sie gemacht
(damit Sie sie nicht machen müssen)
Ich habe als Designer angefangen,
bin dann Entwickler geworden,
und habe irgendwann gemerkt:
Das Problem ist selten Technik.
Es ist immer Zuständigkeit.
Wenn keiner verantwortlich ist, passiert nichts.
Also habe ich mir angewöhnt, Verantwortung zu übernehmen.
Warum ich Websites wie Systeme baue
Ich war viele Jahre Senior Developer in Firmen, in denen:
• Millionenumsätze dranhingen
• Fehler teuer waren
• Performance nicht optional war
• Sicherheit kein Nice-to-Have war
• „kurz mal ändern“ trotzdem passieren musste
Das prägt.
Deshalb sind meine Websites:
• schnell
• stabil
• boring (im besten Sinne)
• erweiterbar
• wartungsarm
• und nicht abhängig von Plugins oder Agenturen
Ich habe beide Seiten gesehen
Ich war:
• Webdesigner
• Entwickler
• Marketing
• Vertrieb
• Agentur
• Inhouse
• Dienstleister
• Unternehmer
Das heißt:
Ich weiß, was Unternehmen brauchen
und was sie nicht brauchen.
(Meetings, Tickets, Workshops, PowerPoint.)
Was Kunden davon haben
Sie bekommen:
• keinen Projektmanager
• keinen Prozess
• kein Team
• kein Ticket
• kein CMS-Drama
Sie bekommen:
• eine Person
• eine Verantwortung
• ein Ergebnis
Ein kurzer Überblick (ohne Lebenslauf-Gefühl)
Ich habe u. a. gearbeitet bei:
• Agenturen
• E-Commerce-Plattformen
• SaaS-Firmen
• Marketing-Teams
• internationalen Unternehmen
• Mittelständlern
• und Konzernen
Als:
• Web Designer
• Frontend Developer
• Software Developer
• Senior Developer
• und später Gründer
Das Ergebnis daraus ist nicht ein Titel.
Sondern eine Arbeitsweise.
Heute
Heute baue ich Websites und Systeme für Unternehmen,
die keine Lust mehr auf Agenturen haben
und keine Zeit für Chaos.
Ich übernehme das Thema komplett
damit es für Sie kein Thema mehr ist.

BIN
public/header.webp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

View File

@@ -23,6 +23,7 @@ export const Footer: React.FC = () => {
<div className="flex flex-col md:items-end gap-4 text-sm font-mono text-slate-300 uppercase tracking-widest">
<span>© {currentYear}</span>
<div className="flex gap-8">
<a href="/about" className="hover:text-slate-900 transition-colors no-underline">Über mich</a>
<a href="/contact" className="hover:text-slate-900 transition-colors no-underline">Kontakt</a>
<a href="https://github.com/marcmintel" className="hover:text-slate-900 transition-colors no-underline">GitHub</a>
</div>

View File

@@ -39,16 +39,24 @@ export const Header: React.FC = () => {
</Link>
<nav className="flex items-center gap-8">
<Link
href="/websites"
<Link
href="/about"
className={`text-xs font-bold uppercase tracking-widest transition-colors ${
isActive('/about') ? 'text-slate-900' : 'text-slate-400 hover:text-slate-900'
}`}
>
Über mich
</Link>
<Link
href="/websites"
className={`text-xs font-bold uppercase tracking-widest transition-colors ${
isActive('/websites') ? 'text-slate-900' : 'text-slate-400 hover:text-slate-900'
}`}
>
Websites
</Link>
<Link
href="/blog"
<Link
href="/blog"
className={`text-xs font-bold uppercase tracking-widest transition-colors ${
isActive('/blog') || pathname?.startsWith('/blog/') ? 'text-slate-900' : 'text-slate-400 hover:text-slate-900'
}`}

View File

@@ -0,0 +1,64 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
import { IllustrationProps } from './types';
export const ExperienceIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Timeline line */}
<motion.path
d="M 20 100 H 100"
stroke="currentColor"
strokeWidth="1"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1.5, delay }}
/>
{/* Experience nodes */}
{[
{ x: 30, y: 80, label: "Agency" },
{ x: 50, y: 60, label: "Corp" },
{ x: 70, y: 40, label: "Startup" },
{ x: 90, y: 20, label: "Now" }
].map((node, i) => (
<React.Fragment key={i}>
<motion.circle
cx={node.x} cy={node.y} r="4"
className={i === 3 ? "fill-slate-900" : "fill-slate-300"}
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.5 + i * 0.2, type: "spring" }}
/>
{i > 0 && (
<motion.path
d={`M ${30 + (i-1)*20} ${80 - (i-1)*20} L ${node.x} ${node.y}`}
stroke="currentColor"
strokeWidth="1"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.5 + (i-1) * 0.2 }}
/>
)}
</React.Fragment>
))}
{/* 15+ Years indicator */}
<motion.text
x="20" y="115"
className="text-[8px] font-bold fill-slate-400 uppercase tracking-widest"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1.5 }}
>
15+ YEARS
</motion.text>
</svg>
);

View File

@@ -0,0 +1,52 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
import { IllustrationProps } from './types';
export const ResponsibilityIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Shield / Responsibility shape */}
<motion.path
d="M 60 20 L 90 35 V 65 C 90 85 60 100 60 100 C 60 100 30 85 30 65 V 35 L 60 20 Z"
stroke="currentColor"
strokeWidth="1"
className="text-slate-900"
initial={{ pathLength: 0, fill: "rgba(15, 23, 42, 0)" }}
whileInView={{ pathLength: 1, fill: "rgba(15, 23, 42, 0.05)" }}
viewport={{ once: true }}
transition={{ duration: 1.5, delay }}
/>
{/* Core point */}
<motion.circle
cx="60" cy="55" r="8"
className="fill-slate-900"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1, type: "spring" }}
/>
{/* Responsibility lines */}
{[0, 120, 240].map((angle, i) => {
const x1 = 60 + Math.cos((angle * Math.PI) / 180) * 12;
const y1 = 55 + Math.sin((angle * Math.PI) / 180) * 12;
const x2 = 60 + Math.cos((angle * Math.PI) / 180) * 30;
const y2 = 55 + Math.sin((angle * Math.PI) / 180) * 30;
return (
<motion.line
key={i}
x1={x1} y1={y1} x2={x2} y2={y2}
stroke="currentColor"
strokeWidth="1"
className="text-slate-400"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1.2 + i * 0.2 }}
/>
);
})}
</svg>
);

View File

@@ -0,0 +1,54 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
import { IllustrationProps } from './types';
export const ResultIllustration: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Result Box */}
<motion.rect
x="30" y="30" width="60" height="60" rx="4"
stroke="currentColor"
strokeWidth="1"
className="text-slate-900"
initial={{ pathLength: 0, rotate: -10, opacity: 0 }}
whileInView={{ pathLength: 1, rotate: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay }}
/>
{/* Checkmark */}
<motion.path
d="M 45 60 L 55 70 L 75 50"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="text-slate-900"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 1 }}
/>
{/* Sparkles */}
{[
{ x: 25, y: 25 },
{ x: 95, y: 35 },
{ x: 85, y: 95 }
].map((pos, i) => (
<motion.path
key={i}
d={`M ${pos.x} ${pos.y-4} V ${pos.y+4} M ${pos.x-4} ${pos.y} H ${pos.x+4}`}
stroke="currentColor"
strokeWidth="1"
className="text-slate-300"
initial={{ scale: 0, opacity: 0 }}
whileInView={{ scale: 1, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1.5 + i * 0.2, type: "spring" }}
/>
))}
</svg>
);

View File

@@ -0,0 +1,333 @@
'use client';
import * as React from 'react';
import { motion } from 'framer-motion';
import { IllustrationProps } from './types';
export const SystemArchitecture: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Central Core */}
<motion.rect
x="70" y="70" width="60" height="60" rx="12"
className="fill-slate-900"
initial={{ scale: 0, rotate: -45 }}
whileInView={{ scale: 1, rotate: 0 }}
viewport={{ once: true }}
transition={{ type: "spring", stiffness: 100, delay }}
/>
{/* Orbiting Elements */}
{[0, 90, 180, 270].map((angle, i) => {
const rad = (angle * Math.PI) / 180;
const x = 100 + Math.cos(rad) * 60 - 15;
const y = 100 + Math.sin(rad) * 60 - 15;
return (
<motion.rect
key={i}
x={x} y={y} width="30" height="30" rx="8"
className="fill-white stroke-slate-200"
strokeWidth="1"
initial={{ opacity: 0, scale: 0 }}
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
animate={{
y: [y, y - 5, y],
}}
transition={{
delay: delay + 0.2 + i * 0.1,
duration: 3,
repeat: Infinity,
repeatDelay: i * 0.5,
ease: "easeInOut"
}}
/>
);
})}
{/* Connection Lines */}
<motion.path
d="M 100 40 V 70 M 100 130 V 160 M 40 100 H 70 M 130 100 H 160"
stroke="currentColor" strokeWidth="1"
className="text-slate-200"
strokeDasharray="4 4"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay: delay + 0.6 }}
/>
</svg>
);
export const SpeedPerformance: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* The "Built" Foundation */}
<motion.path
d="M 40 160 H 160"
stroke="currentColor" strokeWidth="4" strokeLinecap="round"
className="text-slate-900"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8, delay }}
/>
{/* Bricks forming a structure */}
{[
{ x: 50, y: 130, w: 30 },
{ x: 85, y: 130, w: 30 },
{ x: 120, y: 130, w: 30 },
{ x: 65, y: 105, w: 30 },
{ x: 105, y: 105, w: 30 },
].map((brick, i) => (
<motion.rect
key={i}
x={brick.x} y={brick.y} width={brick.w} height="20" rx="2"
className="fill-slate-100 stroke-slate-200"
strokeWidth="1"
initial={{ opacity: 0, y: brick.y + 10 }}
whileInView={{ opacity: 1, y: brick.y }}
viewport={{ once: true }}
transition={{ delay: delay + 0.2 + i * 0.1 }}
/>
))}
{/* Lightning Bolt emerging from the "Built" structure */}
<motion.path
d="M 110 30 L 80 80 H 100 L 70 130"
stroke="currentColor" strokeWidth="6" strokeLinecap="round" strokeLinejoin="round"
className="text-slate-900"
initial={{ pathLength: 0, filter: "drop-shadow(0 0 0px rgba(0,0,0,0))" }}
whileInView={{ pathLength: 1, filter: "drop-shadow(0 0 8px rgba(0,0,0,0.1))" }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 1, ease: "easeOut" }}
/>
{/* Speed Lines */}
{[0, 1, 2].map((i) => (
<motion.path
key={i}
d={`M ${130 + i * 10} ${50 + i * 20} H ${150 + i * 10}`}
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
initial={{ x: -10, opacity: 0 }}
animate={{ x: 10, opacity: [0, 1, 0] }}
transition={{ duration: 0.8, repeat: Infinity, delay: delay + 1.2 + i * 0.2 }}
/>
))}
</svg>
);
export const SolidFoundation: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Stacked Blocks */}
<motion.rect
x="40" y="140" width="120" height="30" rx="4"
className="fill-slate-900"
initial={{ y: 20, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay }}
/>
<motion.rect
x="60" y="100" width="80" height="30" rx="4"
className="fill-slate-400"
initial={{ y: 20, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.2 }}
/>
<motion.rect
x="80" y="60" width="40" height="30" rx="4"
className="fill-slate-200"
initial={{ y: 20, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.4 }}
/>
{/* Shield Icon Overlay */}
<motion.path
d="M 100 30 L 120 40 V 60 C 120 80 100 90 100 90 C 100 90 80 80 80 60 V 40 L 100 30 Z"
className="fill-white stroke-slate-900"
strokeWidth="2"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ type: "spring", delay: delay + 0.8 }}
/>
</svg>
);
export const LayerSeparation: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Top Layer (Content) */}
<motion.g
initial={{ y: -20, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay }}
>
<rect x="40" y="40" width="120" height="40" rx="8" className="fill-white stroke-slate-200" strokeWidth="1" />
<rect x="55" y="55" width="30" height="10" rx="2" className="fill-slate-100" />
<rect x="95" y="55" width="50" height="10" rx="2" className="fill-slate-100" />
</motion.g>
{/* Gap with Arrows */}
<motion.path
d="M 100 90 V 110"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
strokeDasharray="4 4"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.4 }}
/>
{/* Bottom Layer (Code/Logic) */}
<motion.g
initial={{ y: 20, opacity: 0 }}
whileInView={{ y: 0, opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.2 }}
>
<rect x="40" y="120" width="120" height="40" rx="8" className="fill-slate-900" />
<path d="M 60 140 L 70 135 L 60 130 M 140 140 L 130 135 L 140 130" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</motion.g>
</svg>
);
export const DirectService: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Two Nodes */}
<motion.circle
cx="50" cy="100" r="15"
className="fill-slate-200"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay }}
/>
<motion.circle
cx="150" cy="100" r="15"
className="fill-slate-900"
initial={{ scale: 0 }}
whileInView={{ scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 0.2 }}
/>
{/* Direct Connection */}
<motion.path
d="M 65 100 H 135"
stroke="currentColor" strokeWidth="3" strokeLinecap="round"
className="text-slate-900"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.8, delay: delay + 0.4 }}
/>
{/* Pulse moving between */}
<motion.circle r="4" className="fill-white">
<animateMotion
dur="2s"
repeatCount="indefinite"
path="M 65 100 H 135"
/>
</motion.circle>
</svg>
);
export const AgencyChaos: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Messy Path */}
<motion.path
d="M 30 100 C 50 40, 70 160, 90 100 C 110 40, 130 160, 170 100"
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 2, delay }}
/>
{/* Intersecting Circles (Meetings) */}
{[0, 1, 2].map((i) => (
<motion.circle
key={i}
cx={60 + i * 40} cy={100 + (i % 2 === 0 ? -30 : 30)} r="20"
className="stroke-slate-100 fill-white"
strokeWidth="1"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
animate={{ scale: [1, 1.1, 1] }}
transition={{
delay: delay + 0.5 + i * 0.3,
duration: 4,
repeat: Infinity,
repeatDelay: i * 0.5
}}
/>
))}
{/* Slate "X" or Stop signs - NO COLOR */}
<motion.path
d="M 160 90 L 180 110 M 180 90 L 160 110"
stroke="currentColor" strokeWidth="3" strokeLinecap="round"
className="text-slate-300"
initial={{ opacity: 0, scale: 0 }}
whileInView={{ opacity: 0.5, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1.5 }}
/>
</svg>
);
export const TaskDone: React.FC<IllustrationProps> = ({ className = "", delay = 0 }) => (
<svg className={className} viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
{/* Checkmark Circle */}
<motion.circle
cx="100" cy="100" r="60"
className="stroke-slate-900"
strokeWidth="2"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 1, delay }}
/>
{/* Checkmark */}
<motion.path
d="M 70 100 L 90 120 L 135 75"
stroke="currentColor" strokeWidth="8" strokeLinecap="round" strokeLinejoin="round"
className="text-slate-900"
initial={{ pathLength: 0 }}
whileInView={{ pathLength: 1 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: delay + 0.8 }}
/>
{/* Confetti/Sparkles */}
{[0, 45, 90, 135, 180, 225, 270, 315].map((angle, i) => {
const rad = (angle * Math.PI) / 180;
const x1 = 100 + Math.cos(rad) * 70;
const y1 = 100 + Math.sin(rad) * 70;
const x2 = 100 + Math.cos(rad) * 85;
const y2 = 100 + Math.sin(rad) * 85;
return (
<motion.line
key={i}
x1={x1} y1={y1} x2={x2} y2={y2}
stroke="currentColor" strokeWidth="2" strokeLinecap="round"
className="text-slate-200"
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
viewport={{ once: true }}
transition={{ delay: delay + 1.2 + i * 0.05 }}
/>
);
})}
</svg>
);

View File

@@ -10,3 +10,6 @@ export * from './ConceptTarget';
export * from './ConceptMessy';
export * from './HeroArchitecture';
export * from './HeroMainIllustration';
export * from './ExperienceIllustration';
export * from './ResponsibilityIllustration';
export * from './ResultIllustration';

View File

@@ -1,6 +1,7 @@
export * from './AbstractLines';
export * from './ExplanatoryIllustrations';
export * from './ConceptIllustrations';
export * from './Illustrations';
export * from './ComparisonRow';
export * from './FeatureCard';
export * from './HeroItem';

View File

@@ -11,6 +11,7 @@ interface SectionProps {
borderTop?: boolean;
connector?: React.ReactNode;
containerVariant?: 'narrow' | 'normal' | 'wide';
illustration?: React.ReactNode;
}
export const Section: React.FC<SectionProps> = ({
@@ -23,6 +24,7 @@ export const Section: React.FC<SectionProps> = ({
borderTop = false,
connector,
containerVariant = 'narrow',
illustration,
}) => {
const bgClass = variant === 'gray' ? 'bg-slate-50' : 'bg-white';
const borderClass = borderTop ? 'border-t border-slate-100' : '';
@@ -91,6 +93,13 @@ export const Section: React.FC<SectionProps> = ({
</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>

24
src/types/images.d.ts vendored Normal file
View File

@@ -0,0 +1,24 @@
declare module '*.svg' {
const content: any;
export default content;
}
declare module '*.webp' {
const content: any;
export default content;
}
declare module '*.png' {
const content: any;
export default content;
}
declare module '*.jpg' {
const content: any;
export default content;
}
declare module '*.jpeg' {
const content: any;
export default content;
}

4
src/types/svg.d.ts vendored
View File

@@ -1,4 +0,0 @@
declare module '*.svg' {
const content: any;
export default content;
}