2026-04-24 17:12:51 +02:00
'use client'
import { motion } from 'framer-motion'
import { ArrowUpRight , ExternalLink } from 'lucide-react'
import { Button } from '@/components/ui/button'
import Link from 'next/link'
const projects = [
{
2026-04-25 04:41:53 +02:00
title : 'Hacker News Daily AI Reports' ,
2026-04-24 17:12:51 +02:00
slug : 'hackernews' ,
2026-04-25 04:39:10 +02:00
description : 'KI Tools werten zweimal täglich die Hacker News aus und beurteilen deren Relevanz in Bezug auf KI.' ,
2026-04-25 04:49:39 +02:00
tech : [ 'Python' , 'FastAPI' , 'Openrouter' , 'deepseek-reasoner' , 'qwen3-max' ] ,
2026-04-24 17:12:51 +02:00
status : 'Aktiv' ,
url : 'https://jamulix.de/hackernews/' ,
featured : true ,
} ,
{
2026-04-25 04:53:27 +02:00
title : 'Sichtbare Sortier-Algorithmen (Demo)' ,
2026-04-24 17:12:51 +02:00
slug : 'sorting' ,
description : 'Interaktive Visualisierung verschiedener Sortieralgorithmen. Didaktisches Werkzeug für Algorithmen-Verständnis.' ,
2026-04-25 23:32:39 +02:00
tech : [ 'Vibe-Coding' , 'LLM' , 'Javascript' , 'Tailwind' ] ,
2026-04-24 17:12:51 +02:00
status : 'Aktiv' ,
url : 'https://jamulix.de/sorting' ,
featured : true ,
} ,
{
2026-04-25 04:58:05 +02:00
title : 'Digitalisierung einer "Mundorgel"' ,
2026-04-24 17:12:51 +02:00
slug : 'upcoming-1' ,
2026-04-25 04:58:05 +02:00
description : 'KI-gestützte Digitalisierung eines Liederheftes von 1960.' ,
2026-04-25 23:32:39 +02:00
tech : [ 'LLM-OCR' , 'JSON' , 'Typescript' , 'Tailwind' , 'Vibe-Coding' ] ,
2026-04-25 05:02:07 +02:00
status : 'Aktiv' ,
url : 'https://jamulix.de/mundorgel/' ,
2026-04-24 17:12:51 +02:00
featured : false ,
} ,
{
2026-04-26 00:20:34 +02:00
title : 'Desinformationsdetektor' ,
2026-04-24 17:12:51 +02:00
slug : 'upcoming-2' ,
2026-04-26 00:20:34 +02:00
description : 'Automatisierte Prüfung von Medieninhalten auf Manipulationspotenzial. Das Projekt analysiert mit verschiedenen KI-unterstützten Programmen veröffentlichte Texte, Audios und Videos auf zentrale Behauptungen, Belege, Lücken und Logik. Es identifiziert prüfbare Aussagen, recherchiert stützende und widersprechende Quellen mit Links, deckt ausgelassene Fakten auf, prüft argumentative Kohärenz und bewertet Framing, Sentiment und Meinungsdichte. Das Ergebnis ist ein transparentes, nachvollziehbares Gutachten zur Qualität und zum Desinformationsrisiko des Inhalts.' ,
2026-04-24 17:12:51 +02:00
tech : [ 'Rust' , 'Linux' , 'SQLite' ] ,
status : 'Geplant' ,
url : null ,
featured : false ,
} ,
]
function ProjectCard ( { project , index } : { project : typeof projects [ 0 ] ; index : number } ) {
const isClickable = project . url !== null
return (
< motion.article
initial = { { opacity : 0 , y : 30 } }
whileInView = { { opacity : 1 , y : 0 } }
viewport = { { once : true , margin : '-50px' } }
transition = { { duration : 0.5 , delay : index * 0.1 } }
className = { ` group relative ${ project . featured ? 'lg:col-span-1' : '' } ` }
>
< div
className = { `
relative h - full p - 6 lg :p - 8 rounded - lg border border - border
bg - card transition - all duration - 300
$ { isClickable ? 'hover:border-accent/50 hover:bg-card/80' : 'opacity-70' }
` }
>
{ /* Status badge */ }
< div className = "flex items-center justify-between mb-4" >
< span
className = { `
font - mono text - xs px - 2 py - 1 rounded
$ { project . status === 'Aktiv'
? 'bg-accent/10 text-accent'
: project . status === 'In Entwicklung'
? 'bg-secondary text-muted-foreground'
: 'bg-secondary/50 text-muted-foreground/70'
}
` }
>
{ project . status }
< / span >
{ isClickable && (
< ArrowUpRight className = "size-5 text-muted-foreground group-hover:text-accent transition-colors" / >
) }
< / div >
{ /* Title */ }
< h3 className = "font-serif text-xl lg:text-2xl mb-3 group-hover:text-accent transition-colors" >
{ project . title }
< / h3 >
{ /* Description */ }
< p className = "text-muted-foreground leading-relaxed mb-6" >
{ project . description }
< / p >
{ /* Tech stack */ }
< div className = "flex flex-wrap gap-2 mb-6" >
{ project . tech . map ( ( tech ) = > (
< span
key = { tech }
className = "font-mono text-xs px-2 py-1 bg-secondary text-secondary-foreground rounded"
>
{ tech }
< / span >
) ) }
< / div >
{ /* Link */ }
{ isClickable && (
< Button asChild variant = "outline" size = "sm" className = "group/btn" >
< Link href = { project . url } target = "_blank" rel = "noopener noreferrer" >
Ansehen
< ExternalLink className = "ml-2 size-3 transition-transform group-hover/btn:translate-x-0.5" / >
< / Link >
< / Button >
) }
< / div >
< / motion.article >
)
}
export function ProjectsSection() {
return (
< section id = "projekte" className = "py-24 lg:py-32 bg-secondary/30" >
< div className = "max-w-6xl mx-auto px-6 lg:px-8" >
{ /* Section Header */ }
< motion.div
initial = { { opacity : 0 , y : 20 } }
whileInView = { { opacity : 1 , y : 0 } }
viewport = { { once : true } }
transition = { { duration : 0.6 } }
className = "mb-16"
>
< span className = "font-mono text-xs tracking-wider text-accent uppercase" >
Experimente
< / span >
< h2 className = "font-serif text-3xl sm:text-4xl lg:text-5xl mt-4 text-balance" >
2026-04-25 04:51:00 +02:00
Ausgewählte junge Projekte
2026-04-24 17:12:51 +02:00
< / h2 >
< p className = "mt-6 text-lg text-muted-foreground max-w-2xl" >
Technische Experimente und Werkzeuge . Weniger Portfolio ,
mehr Labor für Ideen .
< / p >
< / motion.div >
{ /* Projects Grid */ }
< div className = "grid md:grid-cols-2 gap-6 lg:gap-8" >
{ projects . map ( ( project , index ) = > (
< ProjectCard key = { project . slug } project = { project } index = { index } / >
) ) }
< / div >
< / div >
< / section >
)
}