Landingpage/index.html
JaysonCleve e5ecb2199c
All checks were successful
Deploy landingpage / deploy (push) Successful in 4s
full overhaul of the landingpage
2026-04-14 14:31:41 +02:00

1023 lines
36 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>noctura.dev — Portfolio</title>
<meta name="description" content="Portfolio für Web, Systeme und Infrastruktur."/>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@300;400;500;600&family=Geist+Mono:wght@300;400&display=swap" rel="stylesheet"/>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--ink:#0a0a0c;
--ink-soft:#141417;
--ink-mid:#1c1c22;
--ink-border:rgba(255,255,255,0.07);
--ink-border-hi:rgba(255,255,255,0.14);
--text:#f0ede8;
--text-dim:#8a8780;
--text-muted:#5a5855;
--gold:#c9a96e;
--gold-dim:rgba(201,169,110,0.15);
--gold-glow:rgba(201,169,110,0.08);
--teal:#5ec4a8;
--teal-dim:rgba(94,196,168,0.12);
--ff-serif:'Instrument Serif',Georgia,serif;
--ff-sans:'Geist',system-ui,sans-serif;
--ff-mono:'Geist Mono',monospace;
--ease-out:cubic-bezier(0.16,1,0.3,1);
}
html{scroll-behavior:smooth;font-size:16px}
body{
background:var(--ink);
color:var(--text);
font-family:var(--ff-sans);
line-height:1.6;
min-height:100vh;
overflow-x:hidden;
}
::selection{background:rgba(201,169,110,0.22);color:#fff}
a{color:inherit;text-decoration:none}
img{display:block}
/* ── NOISE TEXTURE ───────────────────────────── */
body::after{
content:'';
position:fixed;inset:0;
background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
opacity:0.028;
pointer-events:none;
z-index:999;
}
/* ── CANVAS ──────────────────────────────────── */
#c{position:fixed;inset:0;z-index:0;pointer-events:none}
/* ── NAV ─────────────────────────────────────── */
nav{
position:fixed;top:0;left:0;right:0;z-index:100;
padding:0 2.5rem;
height:60px;
display:flex;align-items:center;justify-content:space-between;
border-bottom:1px solid var(--ink-border);
background:rgba(10,10,12,0.82);
backdrop-filter:blur(24px);
}
.nav-logo{
font-family:var(--ff-mono);
font-size:0.78rem;
letter-spacing:0.12em;
color:var(--text-dim);
}
.nav-logo span{color:var(--gold)}
.nav-links{
display:flex;gap:2.5rem;
list-style:none;
}
.nav-links a{
font-size:0.72rem;
letter-spacing:0.1em;
text-transform:uppercase;
color:var(--text-muted);
transition:color 0.2s;
}
.nav-links a:hover{color:var(--text)}
/* ── LAYOUT ─────────────────────────────────── */
.container{
position:relative;z-index:1;
max-width:1140px;
margin:0 auto;
padding:0 2.5rem;
}
/* ── HERO ───────────────────────────────────── */
.hero{
padding:148px 0 100px;
display:grid;
grid-template-columns:1fr 360px;
gap:3rem;
align-items:start;
}
.hero-eyebrow{
font-family:var(--ff-mono);
font-size:0.68rem;
letter-spacing:0.18em;
text-transform:uppercase;
color:var(--gold);
margin-bottom:1.75rem;
display:flex;align-items:center;gap:0.75rem;
opacity:0;animation:up 0.7s var(--ease-out) 0.1s forwards;
}
.hero-eyebrow::before{
content:'';width:24px;height:1px;
background:var(--gold);opacity:0.5;
}
.hero h1{
font-family:var(--ff-serif);
font-size:clamp(3.5rem,7vw,6rem);
font-weight:400;
line-height:0.95;
letter-spacing:-0.02em;
margin-bottom:2rem;
opacity:0;animation:up 0.8s var(--ease-out) 0.25s forwards;
}
.hero h1 em{
font-style:italic;
color:var(--gold);
}
.hero-desc{
font-size:1rem;
color:var(--text-dim);
line-height:1.85;
max-width:560px;
margin-bottom:2.5rem;
opacity:0;animation:up 0.8s var(--ease-out) 0.4s forwards;
}
.hero-desc strong{color:var(--text);font-weight:500}
.hero-actions{
display:flex;gap:1rem;flex-wrap:wrap;
opacity:0;animation:up 0.8s var(--ease-out) 0.55s forwards;
}
.btn{
display:inline-flex;align-items:center;gap:8px;
padding:0.78rem 1.5rem;
font-family:var(--ff-sans);
font-size:0.8rem;
font-weight:500;
letter-spacing:0.03em;
border-radius:4px;
transition:all 0.2s var(--ease-out);
cursor:pointer;border:none;
}
.btn-gold{
background:var(--gold);
color:#0a0a0c;
}
.btn-gold:hover{background:#d4b07c;transform:translateY(-1px)}
.btn-ghost{
background:transparent;
color:var(--text-dim);
border:1px solid var(--ink-border-hi);
}
.btn-ghost:hover{color:var(--text);border-color:rgba(255,255,255,0.28);transform:translateY(-1px)}
/* Hero metrics row */
.hero-metrics{
display:flex;gap:0;
border:1px solid var(--ink-border);
border-radius:6px;
overflow:hidden;
margin-top:3rem;
opacity:0;animation:up 0.8s var(--ease-out) 0.7s forwards;
}
.hero-metric{
flex:1;
padding:1.2rem 1.5rem;
border-right:1px solid var(--ink-border);
}
.hero-metric:last-child{border-right:none}
.hero-metric-label{
font-family:var(--ff-mono);
font-size:0.6rem;
letter-spacing:0.14em;
text-transform:uppercase;
color:var(--teal);
margin-bottom:0.5rem;
}
.hero-metric-val{font-size:0.88rem;font-weight:500;margin-bottom:0.2rem}
.hero-metric-copy{font-size:0.76rem;color:var(--text-muted);line-height:1.5}
/* ── HERO CARD ───────────────────────────────── */
.hero-card{
opacity:0;animation:up 0.8s var(--ease-out) 0.6s forwards;
position:sticky;top:80px;
border:1px solid var(--ink-border);
border-radius:10px;
overflow:hidden;
background:var(--ink-soft);
}
.hc-bar{
height:3px;
background:linear-gradient(90deg,var(--gold),var(--teal));
}
.hc-body{padding:1.5rem}
.hc-top{
display:flex;align-items:center;justify-content:space-between;
margin-bottom:1.25rem;
}
.hc-name{font-size:0.92rem;font-weight:500}
.hc-sub{font-size:0.75rem;color:var(--text-muted);margin-top:2px}
.hc-badge{
display:inline-flex;align-items:center;gap:6px;
padding:0.3rem 0.7rem;
border-radius:99px;
background:rgba(94,196,168,0.1);
border:1px solid rgba(94,196,168,0.2);
font-family:var(--ff-mono);
font-size:0.63rem;
letter-spacing:0.06em;
color:var(--teal);
}
.hc-badge::before{
content:'';width:6px;height:6px;border-radius:50%;
background:var(--teal);
animation:blink 2s ease-in-out infinite;
}
@keyframes blink{0%,100%{opacity:1}50%{opacity:0.35}}
.hc-grid{display:grid;grid-template-columns:1fr 1fr;gap:0.6rem;margin-bottom:1rem}
.hc-cell{
padding:0.85rem;
border-radius:6px;
background:var(--ink-mid);
border:1px solid var(--ink-border);
}
.hc-cell-label{
font-family:var(--ff-mono);
font-size:0.6rem;letter-spacing:0.12em;text-transform:uppercase;
color:var(--gold);margin-bottom:0.35rem;
}
.hc-cell-val{font-size:0.82rem;font-weight:500;margin-bottom:0.15rem}
.hc-cell-copy{font-size:0.72rem;color:var(--text-muted);line-height:1.45}
.hc-list{display:grid;gap:0.5rem}
.hc-list-item{
padding:0.75rem;border-radius:6px;
background:var(--ink-mid);border:1px solid var(--ink-border);
font-size:0.76rem;color:var(--text-muted);line-height:1.5;
}
.hc-list-item strong{display:block;color:var(--text);font-weight:500;margin-bottom:2px;font-size:0.78rem}
/* ── SECTION COMMONS ─────────────────────────── */
section{padding:96px 0;position:relative;z-index:1}
.divider{
height:1px;
background:linear-gradient(90deg,transparent,var(--ink-border) 30%,var(--ink-border) 70%,transparent);
}
.s-label{
font-family:var(--ff-mono);
font-size:0.66rem;
letter-spacing:0.18em;
text-transform:uppercase;
color:var(--gold);
margin-bottom:1rem;
}
.s-title{
font-family:var(--ff-serif);
font-size:clamp(2rem,3.5vw,3rem);
font-weight:400;
line-height:1.1;
letter-spacing:-0.02em;
margin-bottom:0.75rem;
}
.s-title em{font-style:italic;color:var(--gold)}
.s-subtitle{
font-size:0.95rem;
color:var(--text-dim);
max-width:640px;
line-height:1.75;
margin-bottom:3.5rem;
}
/* ── ABOUT ───────────────────────────────────── */
.about-grid{
display:grid;
grid-template-columns:1fr 1fr;
gap:1px;
background:var(--ink-border);
border:1px solid var(--ink-border);
border-radius:10px;
overflow:hidden;
margin-bottom:1px;
}
.about-cell{
background:var(--ink-soft);
padding:2rem;
}
.about-cell p{font-size:0.9rem;color:var(--text-dim);line-height:1.85;margin-bottom:1rem}
.about-cell p:last-child{margin-bottom:0}
.about-cell p strong{color:var(--text);font-weight:500}
.about-notes{
background:var(--ink-soft);
border:1px solid var(--ink-border);
border-top:none;
border-radius:0 0 10px 10px;
padding:1.5rem 2rem;
}
.notes-label{
font-family:var(--ff-mono);
font-size:0.62rem;letter-spacing:0.14em;text-transform:uppercase;
color:var(--teal);margin-bottom:1rem;
}
.notes-list{display:flex;flex-wrap:wrap;gap:0.5rem;list-style:none}
.notes-list li{
padding:0.4rem 0.85rem;
border-radius:4px;
border:1px solid var(--ink-border-hi);
font-size:0.78rem;
color:var(--text-dim);
}
.principles{
display:grid;grid-template-columns:repeat(3,1fr);
gap:1px;
background:var(--ink-border);
border:1px solid var(--ink-border);
border-radius:10px;
overflow:hidden;
margin-top:1rem;
}
.principle{
background:var(--ink-soft);
padding:1.75rem;
}
.p-num{
font-family:var(--ff-mono);
font-size:0.62rem;letter-spacing:0.14em;
color:var(--text-muted);
margin-bottom:0.85rem;
}
.p-title{font-weight:500;font-size:0.92rem;margin-bottom:0.5rem}
.p-copy{font-size:0.82rem;color:var(--text-muted);line-height:1.65}
/* ── SKILLS ──────────────────────────────────── */
.skills-grid{
display:grid;grid-template-columns:repeat(3,1fr);
gap:1px;
background:var(--ink-border);
border:1px solid var(--ink-border);
border-radius:10px;
overflow:hidden;
}
.skill{
background:var(--ink-soft);
padding:2.25rem 2rem;
transition:background 0.25s;
}
.skill:hover{background:var(--ink-mid)}
.skill-icon{
font-family:var(--ff-mono);
font-size:1.1rem;
color:var(--gold);
margin-bottom:1.25rem;
display:block;
}
.skill-name{font-size:1rem;font-weight:500;margin-bottom:0.6rem}
.skill-desc{font-size:0.83rem;color:var(--text-dim);line-height:1.7;margin-bottom:1.5rem}
.tags{display:flex;flex-wrap:wrap;gap:6px}
.tag{
font-family:var(--ff-mono);
font-size:0.62rem;letter-spacing:0.04em;
padding:4px 8px;border-radius:3px;
}
.tag-gold{background:var(--gold-dim);color:var(--gold);border:1px solid rgba(201,169,110,0.25)}
.tag-teal{background:var(--teal-dim);color:var(--teal);border:1px solid rgba(94,196,168,0.25)}
.tag-dim{background:rgba(255,255,255,0.04);color:var(--text-muted);border:1px solid var(--ink-border-hi)}
/* ── PROJECTS ────────────────────────────────── */
.projects-grid{
display:grid;grid-template-columns:repeat(2,1fr);
gap:1px;
background:var(--ink-border);
border:1px solid var(--ink-border);
border-radius:10px;
overflow:hidden;
}
.project{
background:var(--ink-soft);
padding:2rem;
display:flex;flex-direction:column;
gap:1rem;
transition:background 0.25s;
position:relative;
}
.project::before{
content:'';
position:absolute;top:0;left:0;right:0;
height:2px;
background:linear-gradient(90deg,var(--gold),transparent);
opacity:0;
transition:opacity 0.25s;
}
.project:hover{background:var(--ink-mid)}
.project:hover::before{opacity:1}
.proj-top{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem}
.proj-icon{
width:44px;height:44px;
border-radius:8px;
border:1px solid var(--ink-border-hi);
display:flex;align-items:center;justify-content:center;
font-family:var(--ff-mono);
font-size:0.78rem;
color:var(--text-dim);
flex-shrink:0;
}
.proj-eyebrow{
font-family:var(--ff-mono);
font-size:0.62rem;letter-spacing:0.1em;text-transform:uppercase;
color:var(--text-muted);margin-bottom:4px;
}
.proj-name{font-size:1.05rem;font-weight:500}
.proj-desc{font-size:0.83rem;color:var(--text-dim);line-height:1.7;flex:1}
.proj-tags{display:flex;flex-wrap:wrap;gap:6px}
.proj-pts{list-style:none;display:grid;gap:0.5rem}
.proj-pts li{
font-size:0.78rem;color:var(--text-muted);
padding-left:1rem;position:relative;line-height:1.55;
}
.proj-pts li::before{
content:'';position:absolute;
left:0;top:0.55rem;
width:4px;height:4px;border-radius:50%;
background:var(--teal);
}
.proj-foot{
display:flex;align-items:center;justify-content:space-between;
margin-top:auto;padding-top:0.25rem;
}
.proj-status{
display:flex;align-items:center;gap:6px;
font-family:var(--ff-mono);font-size:0.62rem;color:var(--text-muted);
}
.dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
.dot-live{background:#4ade80;box-shadow:0 0 5px #4ade80}
.dot-wip{background:#facc15;box-shadow:0 0 5px #facc15}
.dot-plan{background:var(--text-muted)}
.proj-link{
font-family:var(--ff-mono);font-size:0.65rem;letter-spacing:0.06em;
text-transform:uppercase;color:var(--text-muted);
transition:color 0.2s;
}
.project:hover .proj-link{color:var(--gold)}
/* proof band */
.proof-band{
display:grid;grid-template-columns:repeat(3,1fr);
gap:1px;background:var(--ink-border);
border:1px solid var(--ink-border);
border-top:none;
border-radius:0 0 10px 10px;
overflow:hidden;
}
.proof-item{background:var(--ink-soft);padding:1.25rem 1.5rem}
.proof-label{
font-family:var(--ff-mono);
font-size:0.6rem;letter-spacing:0.14em;text-transform:uppercase;
color:var(--teal);margin-bottom:0.5rem;
}
.proof-copy{font-size:0.8rem;color:var(--text-muted);line-height:1.6}
/* ── SNAPSHOT ────────────────────────────────── */
.snapshot-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--ink-border);border:1px solid var(--ink-border);border-radius:10px;overflow:hidden}
.snap{
background:var(--ink-soft);padding:1.75rem 1.5rem;
transition:background 0.25s;
}
.snap:hover{background:var(--ink-mid)}
.snap-kicker{
font-family:var(--ff-mono);font-size:0.6rem;letter-spacing:0.14em;text-transform:uppercase;
color:var(--gold);margin-bottom:0.75rem;
}
.snap-val{
font-family:var(--ff-serif);font-size:1.4rem;font-weight:400;font-style:italic;
line-height:1.2;margin-bottom:0.6rem;
}
.snap-desc{font-size:0.78rem;color:var(--text-muted);line-height:1.6}
/* ── CONTACT ─────────────────────────────────── */
.contact-box{
position:relative;overflow:hidden;
border:1px solid var(--ink-border);
border-radius:10px;
padding:5rem 3rem;
text-align:center;
background:var(--ink-soft);
}
.contact-box::before{
content:'';position:absolute;
top:-80px;left:50%;transform:translateX(-50%);
width:500px;height:200px;
background:radial-gradient(ellipse,rgba(201,169,110,0.07),transparent 70%);
pointer-events:none;
}
.contact-box h2{
font-family:var(--ff-serif);
font-size:clamp(2rem,4vw,3.2rem);
font-weight:400;letter-spacing:-0.02em;
margin-bottom:1rem;position:relative;
}
.contact-box h2 em{font-style:italic;color:var(--gold)}
.contact-box p{
font-size:0.95rem;color:var(--text-dim);
max-width:560px;margin:0 auto 2.5rem;
line-height:1.8;position:relative;
}
.contact-email{
font-family:var(--ff-mono);
font-size:0.78rem;letter-spacing:0.08em;
color:var(--text-dim);
margin-top:1.5rem;
display:block;
position:relative;
}
/* ── FOOTER ──────────────────────────────────── */
footer{
border-top:1px solid var(--ink-border);
padding:2rem 0;
}
.footer-inner{
max-width:1140px;margin:0 auto;padding:0 2.5rem;
display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;
}
.footer-inner span{
font-family:var(--ff-mono);font-size:0.65rem;letter-spacing:0.06em;
color:var(--text-muted);
}
/* ── REVEAL ──────────────────────────────────── */
.reveal{
opacity:0;transform:translateY(28px);
transition:opacity 0.7s var(--ease-out),transform 0.7s var(--ease-out);
}
.reveal.in{opacity:1;transform:none}
@keyframes up{
from{opacity:0;transform:translateY(22px)}
to{opacity:1;transform:none}
}
/* ── RESPONSIVE ──────────────────────────────── */
@media(max-width:1060px){
.hero{grid-template-columns:1fr}
.hero-card{position:static}
.hero-metrics{flex-wrap:wrap}
.hero-metric{flex:1 1 160px}
.snapshot-grid{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:760px){
nav{padding:0 1.25rem}
.nav-links{display:none}
.container{padding:0 1.25rem}
.hero{padding:100px 0 64px}
section{padding:72px 0}
.about-grid,.skills-grid,.projects-grid,.proof-band,.principles,.snapshot-grid{
grid-template-columns:1fr
}
.hc-grid{grid-template-columns:1fr}
.contact-box{padding:3rem 1.5rem}
.footer-inner{padding:0 1.25rem}
}
@media(prefers-reduced-motion:reduce){
*,*::before,*::after{
animation-duration:0.01ms!important;
transition-duration:0.01ms!important;
}
.reveal,.hero-eyebrow,.hero h1,.hero-desc,.hero-actions,.hero-metrics,.hero-card{
opacity:1;transform:none;animation:none;
}
}
</style>
</head>
<body>
<canvas id="c"></canvas>
<nav>
<a href="#" class="nav-logo">noctura<span>.dev</span></a>
<ul class="nav-links">
<li><a href="#about">Über mich</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projekte</a></li>
<li><a href="#snapshot">Profil</a></li>
<li><a href="#contact">Kontakt</a></li>
</ul>
</nav>
<div class="container">
<!-- HERO -->
<section class="hero">
<div class="hero-copy">
<div class="hero-eyebrow">Persönliches Portfolio · Web · Systeme · Infrastruktur</div>
<h1>Interfaces mit<br><em>Haltung.</em><br>Systeme mit<br>Substanz.</h1>
<p class="hero-desc">Ich baue digitale Arbeiten, die nicht bei schöner Oberfläche aufhören. Mich interessieren <strong>klare Nutzerführung, saubere Entscheidungen und Betrieb ohne Blackbox</strong> — Frontend, Backend und Deployment als zusammenhängendes System gedacht.</p>
<div class="hero-actions">
<a href="#projects" class="btn btn-gold">Arbeiten ansehen</a>
<a href="#contact" class="btn btn-ghost">Kontakt aufnehmen</a>
</div>
<div class="hero-metrics">
<div class="hero-metric">
<div class="hero-metric-label">Fokus</div>
<div class="hero-metric-val">End-to-End</div>
<div class="hero-metric-copy">Interface bis Deployment, in einem Zug.</div>
</div>
<div class="hero-metric">
<div class="hero-metric-label">Arbeitsweise</div>
<div class="hero-metric-val">Präzise &amp; direkt</div>
<div class="hero-metric-copy">Klare Entscheidungen, echte Umsetzung.</div>
</div>
<div class="hero-metric">
<div class="hero-metric-label">Stack</div>
<div class="hero-metric-val">HTML · CSS · JS · Linux</div>
<div class="hero-metric-copy">Fokussiert genug für gute Details.</div>
</div>
</div>
</div>
<aside class="hero-card">
<div class="hc-bar"></div>
<div class="hc-body">
<div class="hc-top">
<div>
<div class="hc-name">noctura.dev</div>
<div class="hc-sub">Portfolio · eigene Infrastruktur</div>
</div>
<div class="hc-badge">Aktiv</div>
</div>
<div class="hc-grid">
<div class="hc-cell">
<div class="hc-cell-label">Schwerpunkt</div>
<div class="hc-cell-val">Produktnahe Webprojekte</div>
<div class="hc-cell-copy">Interfaces mit klarer technischer Kante.</div>
</div>
<div class="hc-cell">
<div class="hc-cell-label">Umfeld</div>
<div class="hc-cell-val">Self-hosted</div>
<div class="hc-cell-copy">Design, Code und Betrieb direkt vereint.</div>
</div>
<div class="hc-cell">
<div class="hc-cell-label">Anspruch</div>
<div class="hc-cell-val">Belegen statt zeigen</div>
<div class="hc-cell-copy">Entscheidungen sichtbar, nicht nur Ergebnisse.</div>
</div>
<div class="hc-cell">
<div class="hc-cell-label">Ideal für</div>
<div class="hc-cell-val">Einstieg mit Verantwortung</div>
<div class="hc-cell-copy">Teams mit Eigeninitiative und technischem Anspruch.</div>
</div>
</div>
<div class="hc-list">
<div class="hc-list-item">
<strong>Ziel dieser Seite</strong>
Entwicklerprofil mit Persönlichkeit statt generischer Agentur-Sprache.
</div>
<div class="hc-list-item">
<strong>Was zählt</strong>
Verständliche Projekte, saubere Struktur, Signale für technische Tiefe.
</div>
</div>
</div>
</aside>
</section>
</div>
<div class="divider"></div>
<!-- ABOUT -->
<div class="container">
<section id="about">
<div class="reveal">
<div class="s-label">// Über mich</div>
<h2 class="s-title">Ein Portfolio sollte zeigen,<br>wie jemand <em>denkt.</em></h2>
<p class="s-subtitle">Nicht was er aufzählen kann. Technische Haltung, Lernkurve und Umsetzungskompetenz sichtbar gemacht.</p>
</div>
<div class="reveal">
<div class="about-grid">
<div class="about-cell">
<p>Ich entwickle Oberflächen mit Blick auf Wirkung — aber genauso auf Aufbau, Wartbarkeit und Übergabe. Webentwicklung endet für mich nicht am Browserfenster, sondern schließt APIs, Server, Sicherheit und Deployment ein.</p>
<p>Gerade deshalb passt ein <strong>persönliches Portfolio</strong> besser zu mir als eine sterile Leistungsseite. Es darf Charakter haben, solange die Technik dahinter belastbar bleibt und die Aussagen durch Projekte gedeckt sind.</p>
</div>
<div class="about-cell" style="border-left:1px solid var(--ink-border)">
<div class="notes-label">Was Recruiter hier schnell erfassen sollen</div>
<ul class="notes-list">
<li>Gestalten, bauen, deployen und begründen.</li>
<li>Eigenständig, schnell lernend, in Systemen denkend.</li>
<li>Projekte zeigen technische Reife, nicht nur Optik.</li>
<li>Keine Platzhalter — echte Entscheidungen.</li>
</ul>
</div>
</div>
<div class="about-notes">
<div class="notes-label">Stack &amp; Kontext</div>
<ul class="notes-list">
<li>HTML / CSS / JavaScript</li>
<li>Node.js / REST APIs</li>
<li>Docker &amp; Compose</li>
<li>Debian Linux</li>
<li>Caddy / systemd</li>
<li>Forgejo</li>
<li>ufw / fail2ban</li>
<li>SSH-Härtung</li>
</ul>
</div>
</div>
<div class="principles reveal">
<div class="principle">
<div class="p-num">01 —</div>
<div class="p-title">Klarheit vor Effekthascherei</div>
<p class="p-copy">Gutes Design darf auffallen, muss aber immer lesbar, navigierbar und argumentierbar bleiben.</p>
</div>
<div class="principle" style="border-left:1px solid var(--ink-border)">
<div class="p-num">02 —</div>
<div class="p-title">Technik sichtbar mitdenken</div>
<p class="p-copy">Lösungen, bei denen man nicht nur das Ergebnis, sondern auch die Struktur dahinter ernst nehmen kann.</p>
</div>
<div class="principle" style="border-left:1px solid var(--ink-border)">
<div class="p-num">03 —</div>
<div class="p-title">Wartbarkeit ist Qualität</div>
<p class="p-copy">Sauberer Code, nachvollziehbare Entscheidungen und robuste Deployments sind kein Bonus, sondern Standard.</p>
</div>
</div>
</section>
</div>
<div class="divider"></div>
<!-- SKILLS -->
<div class="container">
<section id="skills">
<div class="reveal">
<div class="s-label">// Fähigkeiten</div>
<h2 class="s-title">Breit genug für ganze Produkte.<br><em>Präzise</em> genug für gute Details.</h2>
<p class="s-subtitle">Interface, Logik und Betrieb als Einheit — das ist der Bereich, in dem ich am stärksten arbeite.</p>
</div>
<div class="skills-grid reveal">
<div class="skill">
<span class="skill-icon">&lt;/&gt;</span>
<div class="skill-name">Frontend &amp; Interface Design</div>
<p class="skill-desc">Responsive Oberflächen mit Charakter, sauberer Informationshierarchie und einem klaren Gefühl für visuelle Spannung ohne Unordnung.</p>
<div class="tags">
<span class="tag tag-gold">HTML / CSS</span>
<span class="tag tag-gold">JavaScript</span>
<span class="tag tag-gold">UI Systems</span>
<span class="tag tag-gold">Responsive</span>
</div>
</div>
<div class="skill" style="border-left:1px solid var(--ink-border)">
<span class="skill-icon"></span>
<div class="skill-name">Backend &amp; Infrastruktur</div>
<p class="skill-desc">Services verbinden, Datenflüsse strukturieren und Hosting so aufsetzen, dass Anwendungen nicht nur laufen, sondern verständlich betrieben werden können.</p>
<div class="tags">
<span class="tag tag-teal">Docker</span>
<span class="tag tag-teal">Node.js</span>
<span class="tag tag-teal">REST APIs</span>
<span class="tag tag-teal">Caddy</span>
<span class="tag tag-teal">Forgejo</span>
</div>
</div>
<div class="skill" style="border-left:1px solid var(--ink-border)">
<span class="skill-icon">$_</span>
<div class="skill-name">Linux &amp; Betrieb</div>
<p class="skill-desc">Server einrichten, absichern und nachhaltig betreiben. Self-hosting, Deployments und die Wartbarkeit echter Systeme — das ist der Kern.</p>
<div class="tags">
<span class="tag tag-dim">Debian Linux</span>
<span class="tag tag-dim">SSH</span>
<span class="tag tag-dim">systemd</span>
<span class="tag tag-dim">ufw / fail2ban</span>
</div>
</div>
</div>
</section>
</div>
<div class="divider"></div>
<!-- PROJECTS -->
<div class="container">
<section id="projects">
<div class="reveal">
<div class="s-label">// Portfolio</div>
<h2 class="s-title">Ausgewählte Arbeiten mit<br>technischer und <em>gestalterischer</em> Aussage.</h2>
<p class="s-subtitle">Kein Produktkatalog. Ein verdichteter Blick darauf, wie ich Probleme angehe und Qualität bewerte.</p>
</div>
<div class="reveal">
<div class="projects-grid">
<article class="project">
<div class="proj-top">
<div>
<div class="proj-eyebrow">Tooling</div>
<div class="proj-name">Developer Utilities</div>
</div>
<div class="proj-icon"></div>
</div>
<p class="proj-desc">Kleine Web-Tools mit klarer UX, schneller Interaktion und pragmatischem Produktgedanken. Der Fokus liegt auf Nutzbarkeit statt Marketing-Schichten.</p>
<div class="proj-tags">
<span class="tag tag-gold">Utility-first</span>
<span class="tag tag-dim">Schnelle Interaktion</span>
<span class="tag tag-dim">Klares UI</span>
</div>
<ul class="proj-pts">
<li>Macht Produktgefühl und Reduktion auf das Wesentliche sichtbar.</li>
<li>Zeigt, dass auch kleine Projekte sorgfältige Informationsarchitektur brauchen.</li>
</ul>
<div class="proj-foot">
<div class="proj-status"><span class="dot dot-wip"></span>In Entwicklung</div>
<span class="proj-link">Work in progress ↗</span>
</div>
</article>
<article class="project">
<div class="proj-top">
<div>
<div class="proj-eyebrow">Backend</div>
<div class="proj-name">Custom Backend API</div>
</div>
<div class="proj-icon" style="font-size:0.65rem">API</div>
</div>
<p class="proj-desc">Eine eigene API-Struktur für persönliche Anwendungen — Routing, Datenmodelle und Hosting nicht ausgelagert, sondern bewusst kontrolliert.</p>
<div class="proj-tags">
<span class="tag tag-teal">Routing</span>
<span class="tag tag-teal">Datenmodelle</span>
<span class="tag tag-dim">Eigenes Hosting</span>
</div>
<ul class="proj-pts">
<li>Technische Entscheidungen nicht nur verwenden, sondern selbst tragen.</li>
<li>Verbindet Frontend-Anforderungen mit sauberem Service-Aufbau.</li>
</ul>
<div class="proj-foot">
<div class="proj-status"><span class="dot dot-wip"></span>In Entwicklung</div>
<span class="proj-link">Architekturaufbau ↗</span>
</div>
</article>
<article class="project">
<div class="proj-top">
<div>
<div class="proj-eyebrow">Experiment</div>
<div class="proj-name">Lab / Playground</div>
</div>
<div class="proj-icon"></div>
</div>
<p class="proj-desc">Prototypen, visuelle Versuche und technische Experimente. Hier wird sichtbar, wie ich neue Themen erschließe und Entscheidungen teste.</p>
<div class="proj-tags">
<span class="tag tag-dim">Prototyping</span>
<span class="tag tag-dim">Designstudien</span>
<span class="tag tag-gold">Lernsystem</span>
</div>
<ul class="proj-pts">
<li>Neugier und Iteration sichtbar statt nur fertige Ergebnisse.</li>
<li>Dort laufen Stil, Technik und persönliche Handschrift am direktesten zusammen.</li>
</ul>
<div class="proj-foot">
<div class="proj-status"><span class="dot dot-plan"></span>Geplant</div>
<span class="proj-link">In Vorbereitung ↗</span>
</div>
</article>
<article class="project">
<div class="proj-top">
<div>
<div class="proj-eyebrow">Infrastruktur</div>
<div class="proj-name">noctura.dev Infrastruktur</div>
</div>
<div class="proj-icon"></div>
</div>
<p class="proj-desc">Selbst verwalteter VPS mit realen Services, Sicherheitsmaßnahmen und einer Umgebung, die mehr kann als statische Auslieferung.</p>
<div class="proj-tags">
<span class="tag tag-dim">VPS</span>
<span class="tag tag-teal">Deployment</span>
<span class="tag tag-dim">Security</span>
</div>
<ul class="proj-pts">
<li>Belegt, dass ich nicht nur UI baue, sondern Betrieb mitdenke.</li>
<li>Relevant für Rollen, in denen Eigenständigkeit und technisches Verständnis zählen.</li>
</ul>
<div class="proj-foot">
<div class="proj-status"><span class="dot dot-live"></span>Live</div>
<span class="proj-link">Produktiv im Einsatz ↗</span>
</div>
</article>
</div>
<div class="proof-band">
<div class="proof-item">
<div class="proof-label">Portfolio-Ziel</div>
<p class="proof-copy">Arbeiten, die nach echter Substanz aussehen — nicht nach Platzhaltern mit hübschem Rahmen.</p>
</div>
<div class="proof-item" style="border-left:1px solid var(--ink-border)">
<div class="proof-label">Signalwirkung</div>
<p class="proof-copy">Jede Karte trägt eine erkennbare Perspektive: Produkt, Architektur, Lernen oder Betrieb.</p>
</div>
<div class="proof-item" style="border-left:1px solid var(--ink-border)">
<div class="proof-label">Wirkung im Gespräch</div>
<p class="proof-copy">Inhalte als Einstieg für Fachgespräche — statt austauschbarer Selbstdarstellung.</p>
</div>
</div>
</div>
</section>
</div>
<div class="divider"></div>
<!-- SNAPSHOT -->
<div class="container">
<section id="snapshot">
<div class="reveal">
<div class="s-label">// Profil</div>
<h2 class="s-title">Die komprimierte Version — für den<br><em>schnellen Eindruck.</em></h2>
<p class="s-subtitle">Vier kurze Aussagen, die im Kopf bleiben sollen, wenn sich jemand nur wenige Minuten Zeit nimmt.</p>
</div>
<div class="snapshot-grid reveal">
<div class="snap">
<div class="snap-kicker">Arbeitsweise</div>
<div class="snap-val">Hands-on</div>
<p class="snap-desc">Lernen über echte Umsetzung, Fehleranalyse und Iteration — nicht über Tutorial-Nachbauen.</p>
</div>
<div class="snap">
<div class="snap-kicker">Stärke</div>
<div class="snap-val">Frontend plus Betrieb</div>
<p class="snap-desc">Entscheidungen vom Interface bis zum Deployment zusammenhängend betrachten und daraus bessere Lösungen ableiten.</p>
</div>
<div class="snap">
<div class="snap-kicker">Motivation</div>
<div class="snap-val">Systeme wirklich verstehen</div>
<p class="snap-desc">Technik reizt mich, wenn ich sie nicht nur benutze, sondern selbst strukturieren und betreiben kann.</p>
</div>
<div class="snap">
<div class="snap-kicker">Eindruck</div>
<div class="snap-val">Substanz vor Buzzwords</div>
<p class="snap-desc">Diese Seite zeigt, wie ich arbeite und entscheide — nicht nur welche Begriffe ich aufzählen könnte.</p>
</div>
</div>
</section>
</div>
<div class="divider"></div>
<!-- CONTACT -->
<div class="container">
<section id="contact">
<div class="contact-box reveal">
<h2>Kontakt für <em>Bewerbungen,</em><br>Zusammenarbeit und technische Gespräche</h2>
<p>Wenn du einen Entwickler suchst, der Design nicht von Technik trennt und Verantwortung auch hinter der Oberfläche übernimmt — schreib mir direkt.</p>
<a href="mailto:kontakt@noctura.dev" class="btn btn-gold">kontakt@noctura.dev</a>
<span class="contact-email">noctura.dev — persönliches Portfolio</span>
</div>
</section>
</div>
<footer>
<div class="footer-inner">
<span>noctura.dev — Persönliches Portfolio mit eigener Infrastruktur</span>
<span>HTML · CSS · JavaScript · Debian 12</span>
</div>
</footer>
<script>
// Particle canvas
(function(){
const canvas=document.getElementById('c');
const ctx=canvas.getContext('2d');
let W,H,stars=[];
const rm=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function init(){
W=canvas.width=window.innerWidth;
H=canvas.height=window.innerHeight;
const n=Math.floor((W*H)/14000);
stars=Array.from({length:n},()=>({
x:Math.random()*W,
y:Math.random()*H,
r:Math.random()*1.1+0.15,
o:Math.random()*0.45+0.08,
s:Math.random()*0.4+0.05,
t:Math.random()*Math.PI*2
}));
}
function draw(){
ctx.clearRect(0,0,W,H);
stars.forEach(s=>{
s.t+=0.007*s.s;
const op=s.o*(0.55+0.45*Math.sin(s.t));
ctx.beginPath();
ctx.arc(s.x,s.y,s.r,0,Math.PI*2);
ctx.fillStyle=`rgba(240,237,232,${op})`;
ctx.fill();
});
requestAnimationFrame(draw);
}
window.addEventListener('resize',init);
init();
if(!rm) draw();
})();
// Reveal on scroll
(function(){
const els=document.querySelectorAll('.reveal');
const rm=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if(rm){els.forEach(e=>e.classList.add('in'));return;}
const io=new IntersectionObserver((entries)=>{
entries.forEach((e,i)=>{
if(e.isIntersecting){
setTimeout(()=>e.target.classList.add('in'),i*80);
io.unobserve(e.target);
}
});
},{threshold:0.1});
els.forEach(e=>io.observe(e));
})();
</script>
</body>
</html>