feat(portfolio): expand project stories and services
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
||||
# w-make.com
|
||||
|
||||
Portfolio von Jan Wagner für industrielle Softwareentwicklung, Systems Thinking und Glass Technology.
|
||||
|
||||
Die Startseite stellt veröffentlichbare Projekte und die dahinterliegenden Engineering-Entscheidungen vor. Inhalte liegen bewusst noch direkt in `src/app/page.tsx`: Ein CMS oder eigene Case-Study-Routen kommen erst hinzu, wenn mehrere freigegebene Langform-Projekte vorhanden sind.
|
||||
|
||||
## Getting Started
|
||||
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "w-make.com - Engineering Reliability",
|
||||
description: "w-make.com Portfolio und Showroom für industrielle Softwareentwicklung, Batchmaker und die Affine App.",
|
||||
title: "Jan Wagner — Software für anspruchsvolle Prozesse",
|
||||
description: "Portfolio von Jan Wagner: industrielle Software, Full-Stack Engineering, AI-Tooling und Glass Technology.",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: LayoutProps<"/">) {
|
||||
|
||||
+81
-30
@@ -1,36 +1,67 @@
|
||||
const projects = [
|
||||
type Project = {
|
||||
number: string;
|
||||
label: string;
|
||||
title: string;
|
||||
summary: string;
|
||||
details: string;
|
||||
role: string;
|
||||
stack: string;
|
||||
status: string;
|
||||
href: string;
|
||||
cta: string;
|
||||
};
|
||||
|
||||
const projects: Project[] = [
|
||||
{
|
||||
label: "Industrie-Software",
|
||||
number: "01",
|
||||
label: "Industrie-Software · Produktentwicklung",
|
||||
title: "W-Make Batch",
|
||||
text: "Eine durchgängige Batchmanagement-Lösung für die Behälterglas-Produktion — von Satzzettel und Gemengebuch bis Silo-Management, Schichtprotokoll und Berechnung.",
|
||||
facts: "Node.js · SQLite · Web Components · E2E-Tests",
|
||||
summary: "Batchmanagement für die Behälterglas-Produktion — vom Satzzettel bis zum Tagesprotokoll.",
|
||||
details: "Das System bildet eine reale Produktionskette ab: Rezepte, Materialverbrauch, Silos, Schichten und Berechnungen bleiben fachlich nachvollziehbar verbunden. Der Schwerpunkt liegt nicht auf möglichst vielen Screens, sondern auf sicheren Zuständen und belastbaren Buchungen.",
|
||||
role: "Domänenmodell, Full-Stack-Entwicklung und technische Qualität",
|
||||
stack: "Node.js · Express · SQLite · Web Components · native Tests · Playwright",
|
||||
status: "öffentliche Produkt-Demo",
|
||||
href: "https://batch.w-make.com",
|
||||
cta: "Produkt-Showroom öffnen",
|
||||
},
|
||||
{
|
||||
label: "Produktentwicklung",
|
||||
title: "Digitale Prozesse, die den Betrieb verstehen",
|
||||
text: "Ich verbinde Domänenwissen aus der Glasindustrie mit sauberer Softwarearchitektur. Das Ergebnis sind Systeme, die fachlich belastbar und im Alltag nutzbar sind.",
|
||||
facts: "Fachlichkeit · Datenintegrität · Wartbarkeit",
|
||||
number: "02",
|
||||
label: "AI Engineering · Tooling",
|
||||
title: "Hermes Tools",
|
||||
summary: "Werkzeuge, die mehrere AI-Agents, Projekte und technische Arbeitsabläufe zuverlässig verbinden.",
|
||||
details: "Hier geht es um die unsichtbare Schicht hinter produktiver AI-Arbeit: klare Delegationsverträge, gemeinsame Kontext-Schnittstellen, Registry-Logik und nachvollziehbare Übergaben. Gute Automatisierung braucht dabei genauso klare Grenzen wie gute Fachsoftware.",
|
||||
role: "Architektur, Python-Tooling und Integrationsdesign",
|
||||
stack: "Python · MCP · APIs · CLI-Workflows · strukturierte Protokolle",
|
||||
status: "laufendes Engineering-Projekt",
|
||||
href: "#arbeitsweise",
|
||||
cta: "Arbeitsweise ansehen",
|
||||
cta: "Entscheidungen ansehen",
|
||||
},
|
||||
{
|
||||
label: "Technische Systeme",
|
||||
title: "Automatisierung mit klaren Grenzen",
|
||||
text: "Von APIs und Datenmodellen bis zu Infrastruktur und Observability: Automatisierung wird dort eingesetzt, wo sie Risiken reduziert — nicht um Komplexität zu verstecken.",
|
||||
facts: "Backend · Tooling · Betrieb",
|
||||
number: "03",
|
||||
label: "Domänenwissen · Systems Thinking",
|
||||
title: "Glas-Technologie als Engineering-Vorteil",
|
||||
summary: "Technische Software entsteht besser, wenn der Prozess nicht erst nachträglich erklärt werden muss.",
|
||||
details: "Der Hintergrund in der Behälterglas-Produktion prägt die Art, wie Systeme entworfen werden: Materialflüsse, Messwerte, Zeitbezug und irreversible fachliche Entscheidungen werden als Teil der Architektur behandelt — nicht als Randnotiz im UI.",
|
||||
role: "Domänenanalyse, Modellbildung und Übersetzung in Software",
|
||||
stack: "Prozessverständnis · Datenmodelle · Berechnungen · Dokumentation",
|
||||
status: "dauerhafter fachlicher Schwerpunkt",
|
||||
href: "#kontakt",
|
||||
cta: "Projekt besprechen",
|
||||
cta: "Ähnlichen Prozess besprechen",
|
||||
},
|
||||
];
|
||||
|
||||
const principles = [
|
||||
["Fachlichkeit zuerst", "Ich beginne beim realen Prozess, nicht beim Framework. Fachliche Regeln werden sichtbar, prüfbar und nachvollziehbar umgesetzt."],
|
||||
["Verlässliche Systeme", "Datenintegrität, sichere Zustände und verständliche Fehlerbehandlung sind keine Extras — sie sind die Grundlage."],
|
||||
["Verlässliche Zustände", "Buchungen, Migrationen und Fehlerpfade werden so entworfen, dass ein System auch unter realen Bedingungen verständlich bleibt."],
|
||||
["Kleine, tragfähige Lösungen", "Keine Architektur um ihrer selbst willen. Erst die kleinste Lösung, die den Prozess dauerhaft besser macht."],
|
||||
];
|
||||
|
||||
const offers = [
|
||||
["Prozessanalyse", "Bestehende Abläufe verstehen, Bruchstellen sichtbar machen und eine priorisierte technische Roadmap ableiten."],
|
||||
["Produkt- und Backend-Entwicklung", "Anwendungen entwickeln oder stabilisieren, bei denen Datenmodell und Geschäftslogik wichtiger sind als schnelle CRUD-Oberflächen."],
|
||||
["Technische Zusammenarbeit", "Architekturentscheidungen, Integrationen und gewachsenen Code gemeinsam in wartbare Systeme überführen."],
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="min-h-screen bg-grid-pattern">
|
||||
@@ -38,7 +69,7 @@ export default function Home() {
|
||||
<div className="relative z-10 mx-auto w-full max-w-6xl px-6 py-8 md:px-10 md:py-12">
|
||||
<nav className="flex items-center justify-between border-b border-slate-800/80 pb-6" aria-label="Hauptnavigation">
|
||||
<a href="#top" className="font-mono text-sm tracking-[0.22em] text-primary">W-MAKE</a>
|
||||
<div className="flex gap-6 text-sm text-slate-400">
|
||||
<div className="flex gap-4 text-sm text-slate-400 md:gap-6">
|
||||
<a href="#projekte" className="hover:text-white">Projekte</a>
|
||||
<a href="#arbeitsweise" className="hover:text-white">Arbeitsweise</a>
|
||||
<a href="#kontakt" className="hover:text-white">Kontakt</a>
|
||||
@@ -48,21 +79,17 @@ export default function Home() {
|
||||
<section id="top" className="grid gap-12 py-24 md:grid-cols-[1.25fr_0.75fr] md:items-end md:py-32">
|
||||
<div>
|
||||
<p className="mb-6 font-mono text-sm uppercase tracking-[0.22em] text-primary">Jan Wagner · Software Engineering</p>
|
||||
<h1 className="max-w-4xl text-5xl font-semibold tracking-tight text-white md:text-7xl">
|
||||
Software für Prozesse, auf die man sich verlassen muss.
|
||||
</h1>
|
||||
<p className="mt-8 max-w-2xl text-lg leading-8 text-slate-300 md:text-xl">
|
||||
Ich entwickle robuste digitale Systeme für industrielle und anspruchsvolle Geschäftsprozesse — mit Domänenverständnis, klarer Architektur und Verantwortung für den Betrieb.
|
||||
</p>
|
||||
<h1 className="max-w-4xl text-5xl font-semibold tracking-tight text-white md:text-7xl">Software für Prozesse, auf die man sich verlassen muss.</h1>
|
||||
<p className="mt-8 max-w-2xl text-lg leading-8 text-slate-300 md:text-xl">Ich entwickle robuste digitale Systeme für industrielle und anspruchsvolle Geschäftsprozesse — mit Domänenverständnis, klarer Architektur und Verantwortung für den Betrieb.</p>
|
||||
<div className="mt-10 flex flex-wrap gap-4">
|
||||
<a href="#projekte" className="rounded-full bg-primary px-6 py-3 font-medium text-slate-950 transition hover:bg-cyan-300">Arbeiten ansehen</a>
|
||||
<a href="#kontakt" className="rounded-full border border-slate-700 px-6 py-3 font-medium text-white transition hover:border-primary hover:text-primary">Projekt besprechen</a>
|
||||
</div>
|
||||
</div>
|
||||
<aside className="border-l border-primary/50 pl-6 text-sm leading-7 text-slate-400">
|
||||
<p className="font-mono text-primary">POSITIONIERUNG</p>
|
||||
<p className="mt-4 text-base text-slate-200">Senior Full-Stack Engineering für Software, die reale Abläufe abbildet — vom Fachprozess bis zum produktiven System.</p>
|
||||
<p className="mt-6">Schwerpunkt: industrielle Software, Datenintegrität, Automatisierung und wartbare Plattformen.</p>
|
||||
<p className="font-mono text-primary">WAS ICH VERBINDE</p>
|
||||
<p className="mt-4 text-base text-slate-200">Glass Technology, Full-Stack Engineering und Systems Thinking.</p>
|
||||
<p className="mt-6">Der gemeinsame Nenner: reale Abläufe in Software übersetzen, ohne die fachliche Wahrheit zu verlieren.</p>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
@@ -72,15 +99,23 @@ export default function Home() {
|
||||
<p className="font-mono text-sm uppercase tracking-[0.22em] text-primary">Ausgewählte Arbeit</p>
|
||||
<h2 className="mt-3 text-3xl font-semibold text-white md:text-4xl">Nicht nur Features. Systeme.</h2>
|
||||
</div>
|
||||
<p className="max-w-md text-sm leading-6 text-slate-400">Die stärkste Referenz ist ein nachvollziehbares System mit echtem fachlichem Kontext — nicht eine lange Liste von Buzzwords.</p>
|
||||
<p className="max-w-md text-sm leading-6 text-slate-400">Jedes Projekt zeigt eine andere Seite derselben Arbeit: Domäne verstehen, Entscheidungen explizit machen und ein System in der Realität betreiben.</p>
|
||||
</div>
|
||||
<div className="grid gap-5 md:grid-cols-3">
|
||||
{projects.map((project) => (
|
||||
<article key={project.title} className="flex flex-col rounded-2xl border border-slate-800 bg-slate-950/60 p-7 transition hover:-translate-y-1 hover:border-primary/60">
|
||||
<p className="font-mono text-xs uppercase tracking-[0.16em] text-primary">{project.label}</p>
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<p className="font-mono text-xs uppercase tracking-[0.16em] text-primary">{project.label}</p>
|
||||
<span className="font-mono text-xs text-slate-600">{project.number}</span>
|
||||
</div>
|
||||
<h3 className="mt-5 text-2xl font-semibold text-white">{project.title}</h3>
|
||||
<p className="mt-4 flex-1 text-sm leading-7 text-slate-400">{project.text}</p>
|
||||
<p className="mt-6 border-t border-slate-800 pt-4 font-mono text-xs leading-5 text-slate-500">{project.facts}</p>
|
||||
<p className="mt-4 text-sm leading-7 text-slate-300">{project.summary}</p>
|
||||
<p className="mt-4 flex-1 text-sm leading-7 text-slate-500">{project.details}</p>
|
||||
<div className="mt-6 space-y-3 border-t border-slate-800 pt-4 text-xs leading-5">
|
||||
<p><span className="font-mono uppercase text-slate-600">Rolle</span><br /><span className="text-slate-400">{project.role}</span></p>
|
||||
<p><span className="font-mono uppercase text-slate-600">Werkzeuge</span><br /><span className="text-slate-400">{project.stack}</span></p>
|
||||
<p><span className="font-mono uppercase text-slate-600">Status</span><br /><span className="text-primary/80">{project.status}</span></p>
|
||||
</div>
|
||||
<a href={project.href} className="mt-6 text-sm font-medium text-primary hover:text-cyan-300">{project.cta} <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
))}
|
||||
@@ -92,6 +127,7 @@ export default function Home() {
|
||||
<div>
|
||||
<p className="font-mono text-sm uppercase tracking-[0.22em] text-primary">Arbeitsweise</p>
|
||||
<h2 className="mt-3 text-3xl font-semibold text-white md:text-4xl">Senior heißt: Entscheidungen verantworten.</h2>
|
||||
<p className="mt-6 max-w-md leading-7 text-slate-400">Technologie ist Mittel zum Zweck. Entscheidend ist, ob ein System die richtigen fachlichen Zustände abbildet und im Alltag erklärbar bleibt.</p>
|
||||
</div>
|
||||
<div className="grid gap-8">
|
||||
{principles.map(([title, text], index) => (
|
||||
@@ -104,6 +140,20 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="leistungen" className="scroll-mt-8 border-t border-slate-800 py-20">
|
||||
<p className="font-mono text-sm uppercase tracking-[0.22em] text-primary">Zusammenarbeit</p>
|
||||
<h2 className="mt-3 max-w-2xl text-3xl font-semibold text-white md:text-4xl">Wo ich am meisten beitragen kann.</h2>
|
||||
<div className="mt-10 grid gap-5 md:grid-cols-3">
|
||||
{offers.map(([title, text], index) => (
|
||||
<div key={title} className="border-l border-slate-700 pl-5">
|
||||
<span className="font-mono text-xs text-primary">0{index + 1}</span>
|
||||
<h3 className="mt-4 text-xl font-medium text-white">{title}</h3>
|
||||
<p className="mt-3 text-sm leading-7 text-slate-400">{text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="kontakt" className="scroll-mt-8 border-t border-slate-800 py-20">
|
||||
<div className="rounded-3xl border border-primary/30 bg-primary/5 p-8 md:p-12">
|
||||
<p className="font-mono text-sm uppercase tracking-[0.22em] text-primary">Kontakt</p>
|
||||
@@ -114,7 +164,7 @@ export default function Home() {
|
||||
</section>
|
||||
|
||||
<footer className="flex flex-wrap justify-between gap-4 border-t border-slate-800 py-8 text-xs text-slate-500">
|
||||
<span>© {new Date().getFullYear()} Jan Wagner · w-make.org</span>
|
||||
<span>© {new Date().getFullYear()} Jan Wagner · w-make.com</span>
|
||||
<span>Software Engineering · Glass Technology · Systems Thinking</span>
|
||||
</footer>
|
||||
</div>
|
||||
@@ -123,3 +173,4 @@ export default function Home() {
|
||||
}
|
||||
|
||||
// ponytail: Kontaktadresse und rechtliche Angaben erst ergänzen, wenn die UG-/Domain-Daten feststehen.
|
||||
// ponytail: Detailseiten erst abspalten, wenn mehrere veröffentlichbare Case Studies existieren.
|
||||
|
||||
Reference in New Issue
Block a user