first commit

This commit is contained in:
2026-06-10 19:16:52 +02:00
commit 9169af831d
18 changed files with 907 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
/Cargo.lock
/target
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "Website"
version = "0.1.0"
edition = "2024"
[dependencies]
rocket = "0.5.1"
+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>

After

Width:  |  Height:  |  Size: 278 B

+12
View File
@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
<rect x="9" y="9" width="6" height="6"></rect>
<line x1="9" y1="1" x2="9" y2="4"></line>
<line x1="15" y1="1" x2="15" y2="4"></line>
<line x1="9" y1="20" x2="9" y2="23"></line>
<line x1="15" y1="20" x2="15" y2="23"></line>
<line x1="20" y1="9" x2="23" y2="9"></line>
<line x1="20" y1="14" x2="23" y2="14"></line>
<line x1="1" y1="9" x2="4" y2="9"></line>
<line x1="1" y1="14" x2="4" y2="14"></line>
</svg>

After

Width:  |  Height:  |  Size: 663 B

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="16 18 22 12 16 6"></polyline>
<polyline points="8 6 2 12 8 18"></polyline>
</svg>

After

Width:  |  Height:  |  Size: 278 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
<polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
<line x1="12" y1="22.08" x2="12" y2="12"></line>
</svg>

After

Width:  |  Height:  |  Size: 437 B

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
<polyline points="22,6 12,13 2,6"></polyline>
</svg>

After

Width:  |  Height:  |  Size: 325 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
<polyline points="15 3 21 3 21 9"></polyline>
<line x1="10" y1="14" x2="21" y2="3"></line>
</svg>

After

Width:  |  Height:  |  Size: 353 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>

After

Width:  |  Height:  |  Size: 493 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<line x1="2" y1="12" x2="22" y2="12"></line>
<path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
</svg>

After

Width:  |  Height:  |  Size: 382 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
<line x1="3" y1="9" x2="21" y2="9"></line>
<line x1="9" y1="21" x2="9" y2="9"></line>
</svg>

After

Width:  |  Height:  |  Size: 336 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>

After

Width:  |  Height:  |  Size: 320 B

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect>
<rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect>
<line x1="6" y1="6" x2="6.01" y2="6"></line>
<line x1="6" y1="18" x2="6.01" y2="18"></line>
</svg>

After

Width:  |  Height:  |  Size: 406 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>

After

Width:  |  Height:  |  Size: 245 B

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="4 17 10 11 4 5"></polyline>
<line x1="12" y1="19" x2="20" y2="19"></line>
</svg>

After

Width:  |  Height:  |  Size: 277 B

+369
View File
@@ -0,0 +1,369 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jarne Götz - Portfolio</title>
<meta name="description"
content="Software Developer & Technology Enthusiast. Focusing on Rust, AI, Security, and Infrastructure.">
<!-- Font: Space Grotesk -->
<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=Space+Grotesk:wght@300;400;500;600;700&display=swap"
rel="stylesheet">
<!-- Preload Icons -->
<link rel="preload" href="icons/menu.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/terminal.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/arrow-right.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/github.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/chip.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/cube.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/globe.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/code.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/server.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/shield.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/layout.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/external-link.svg" as="image" type="image/svg+xml">
<link rel="preload" href="icons/envelope.svg" as="image" type="image/svg+xml">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Navigation -->
<nav>
<input type="checkbox" id="menu-toggle">
<div class="container nav-inner">
<div class="logo">JARNE GÖTZ</div>
<div class="nav-links">
<a href="#projects" onclick="document.getElementById('menu-toggle').checked = false">Projects</a>
<a href="#stack" onclick="document.getElementById('menu-toggle').checked = false">Stack</a>
<a href="#lab" onclick="document.getElementById('menu-toggle').checked = false">Lab</a>
<a href="#contact" onclick="document.getElementById('menu-toggle').checked = false">Contact</a>
</div>
<label for="menu-toggle" class="mobile-menu-label" aria-label="Menu">
<img src="icons/menu.svg" alt="Menu" class="icon-sm">
</label>
</div>
</nav>
<!-- Hero Section -->
<header class="section">
<div class="container">
<div class="mb-4"
style="display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.75rem; text-transform: uppercase; color: var(--fg-muted); border: 1px solid var(--border); padding: 0.25rem 0.75rem;">
<img src="icons/terminal.svg" alt="Terminal" class="icon-sm">
Software Developer
</div>
<h1 class="mb-6">
Building.<br>
Secure.<br>
Efficient.
</h1>
<p class="text-muted mb-8" style="max-width: 600px; font-size: 1.125rem;">
I develop software solutions ranging from Rust-based AI agents to self-hosted infrastructure.
Focused on security, performance, and modern tech.
</p>
<div class="flex gap-2 mb-8" style="flex-wrap: wrap;">
<span class="text-sm text-muted py-1">Focus:</span>
<span class="tag">AI Agents</span>
<span class="tag">Security</span>
<span class="tag">Infrastructure</span>
</div>
<div class="flex gap-4">
<a href="#contact" class="btn btn-primary">
Contact Me
<img src="icons/arrow-right.svg" alt="Arrow Right" class="icon-sm">
</a>
<a href="https://git.zerozipp.dev/explore/repos" target="_blank" class="btn btn-secondary">
<img src="icons/github.svg" alt="Git">
Git
</a>
</div>
</div>
</header>
<!-- Tech Strip -->
<div class="tech-strip">
<div class="container tech-strip-inner">
<span>Rust</span>
<span>//</span>
<span>Kotlin</span>
<span>//</span>
<span>Docker</span>
<span>//</span>
<span>Alpine Linux</span>
<span>//</span>
<span>Arch Linux</span>
<span>//</span>
<span>Node.js</span>
<span>//</span>
<span>Caddy</span>
</div>
</div>
<!-- Projects Section -->
<section id="projects" class="section">
<div class="container">
<div class="flex"
style="justify-content: space-between; align-items: flex-end; border-bottom: 1px solid var(--border); padding-bottom: 1rem; margin-bottom: 2rem;">
<h2>Selected Projects</h2>
<span class="text-sm font-mono text-muted">03 / REPOS</span>
</div>
<div class="grid">
<!-- Project 1 -->
<div class="grid-item project-card">
<div style="flex: 1;">
<div class="flex gap-4 mb-4 items-center">
<img src="icons/chip.svg" alt="Chip" class="icon-md text-muted">
<h3>Folyo</h3>
</div>
<p class="text-muted mb-6" style="max-width: 600px;">
AI Agent Device Control System. Enables AI agents to control physical and virtual devices
through a high-performance Rust server.
</p>
<div class="flex gap-2 mb-6" style="flex-wrap: wrap;">
<span class="tag">Rust</span>
<span class="tag">Agents</span>
<span class="tag">IoT</span>
</div>
</div>
<div class="project-links">
<a href="https://git.zerozipp.dev/folyo/server" target="_blank" class="btn btn-secondary"
style="padding: 0.5rem 1rem; font-size: 0.75rem; justify-content: space-between;">
Git <img src="icons/external-link.svg" alt="External Link" class="icon-sm">
</a>
<a href="https://folyo.dev" target="_blank" class="btn btn-secondary"
style="padding: 0.5rem 1rem; font-size: 0.75rem; justify-content: space-between;">
Website <img src="icons/external-link.svg" alt="External Link" class="icon-sm">
</a>
</div>
</div>
<!-- Project 2 -->
<div class="grid-item project-card">
<div style="flex: 1;">
<div class="flex gap-4 mb-4 items-center">
<img src="icons/cube.svg" alt="Cube" class="icon-md text-muted">
<h3>Agent</h3>
</div>
<p class="text-muted mb-6" style="max-width: 600px;">
A modern Minecraft Mod Loader developed from scratch in Kotlin. Provides
a flexible architecture for mod developers.
</p>
<div class="flex gap-2 mb-6" style="flex-wrap: wrap;">
<span class="tag">Kotlin</span>
<span class="tag">Minecraft</span>
<span class="tag">Plugins</span>
</div>
</div>
<div class="project-links">
<a href="https://git.zerozipp.dev/zerozipp/agent" target="_blank" class="btn btn-secondary"
style="padding: 0.5rem 1rem; font-size: 0.75rem; justify-content: space-between;">
Git <img src="icons/external-link.svg" alt="External Link" class="icon-sm">
</a>
</div>
</div>
<!-- Project 3 -->
<div class="grid-item project-card">
<div style="flex: 1;">
<div class="flex gap-4 mb-4 items-center">
<img src="icons/globe.svg" alt="Globe" class="icon-md text-muted">
<h3>Marick Studio</h3>
</div>
<p class="text-muted mb-6" style="max-width: 600px;">
Full-stack development of a corporate website using Next.js and Tailwind CSS. Features
a booking system, video optimization, and animations.
</p>
<div class="flex gap-2 mb-6" style="flex-wrap: wrap;">
<span class="tag">Next.js</span>
<span class="tag">React</span>
<span class="tag">Tailwind</span>
</div>
</div>
<div class="project-links">
<a href="https://marickstudio.com" target="_blank" class="btn btn-secondary"
style="padding: 0.5rem 1rem; font-size: 0.75rem; justify-content: space-between;">
Website <img src="icons/external-link.svg" alt="External Link" class="icon-sm">
</a>
</div>
</div>
</div>
</div>
</section>
<!-- About / Stack -->
<section id="stack" class="section" style="border-top: 1px solid var(--border);">
<div class="container">
<div class="grid grid-cols-2" style="border: none; background: transparent; gap: 4rem;">
<!-- Col 1 -->
<div>
<h2 class="mb-6">About</h2>
<div class="text-muted" style="display: flex; flex-direction: column; gap: 1rem;">
<p>
Software development is more than just writing code. It is about understanding systems,
designing robust architectures, and continuous learning.
</p>
<p>
My work focuses on three core areas: building autonomous AI agents, analyzing systems from a
security perspective,
and maintaining full control over infrastructure through self-hosting.
</p>
<p>
In my Home Lab, I deploy services like Matrix, Gitea, and Home Assistant on Alpine Linux
containers.
On the desktop, I use Arch Linux to stay close to the system.
</p>
</div>
</div>
<!-- Col 2 -->
<div>
<h2 class="mb-6">Capabilities</h2>
<div style="display: flex; flex-direction: column; gap: 1.5rem;">
<div class="flex gap-4 items-center">
<img src="icons/code.svg" alt="Code" class="icon-lg text-muted">
<div>
<h4 class="mb-1">Languages</h4>
<p class="text-sm text-muted">Rust, Kotlin, Java, TypeScript, Python</p>
</div>
</div>
<div class="flex gap-4 items-center">
<img src="icons/server.svg" alt="Server" class="icon-lg text-muted">
<div>
<h4 class="mb-1">Infrastructure</h4>
<p class="text-sm text-muted">Docker, Alpine Linux, Arch Linux, Caddy</p>
</div>
</div>
<div class="flex gap-4 items-center">
<img src="icons/shield.svg" alt="Shield" class="icon-lg text-muted">
<div>
<h4 class="mb-1">Security</h4>
<p class="text-sm text-muted">Pen Testing Basics, System Hardening</p>
</div>
</div>
<div class="flex gap-4 items-center">
<img src="icons/layout.svg" alt="Layout" class="icon-lg text-muted">
<div>
<h4 class="mb-1">Web</h4>
<p class="text-sm text-muted">Node.js, React, Tailwind CSS</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Home Lab -->
<section id="lab" class="section" style="background-color: #18181b33;">
<div class="container">
<div class="flex gap-4 mb-8 items-center">
<img src="icons/server.svg" alt="Server" class="icon-lg">
<h2>Home Lab</h2>
</div>
<p class="text-muted mb-8" style="max-width: 600px;">
All services below run on my own hardware with Alpine Linux and Docker.
Demonstrating practical skills in administration, containerization, and security.
</p>
<div class="grid grid-cols-3">
<a href="https://matrix.org" class="grid-item lab-item" target="_blank">
<h3>Matrix</h3>
<p class="text-sm text-muted">Decentralized communication</p>
</a>
<a href="https://about.gitea.com" class="grid-item lab-item" target="_blank">
<h3>Gitea</h3>
<p class="text-sm text-muted">Self-hosted Git service</p>
</a>
<a href="https://www.home-assistant.io" class="grid-item lab-item" target="_blank">
<h3>Home Assistant</h3>
<p class="text-sm text-muted">Smart Home Automation</p>
</a>
<a href="https://www.librechat.ai" class="grid-item lab-item" target="_blank">
<h3>LibreChat</h3>
<p class="text-sm text-muted">LLM Web Interface</p>
</a>
<a href="https://github.com/dani-garcia/vaultwarden" class="grid-item lab-item" target="_blank">
<h3>Vaultwarden</h3>
<p class="text-sm text-muted">Password Management</p>
</a>
<a href="https://www.portainer.io" class="grid-item lab-item" target="_blank">
<h3>Portainer</h3>
<p class="text-sm text-muted">Docker Management</p>
</a>
<a href="https://jellyfin.org" class="grid-item lab-item" target="_blank">
<h3>Jellyfin</h3>
<p class="text-sm text-muted">Media Streaming</p>
</a>
<a href="https://technitium.com/dns/" class="grid-item lab-item" target="_blank">
<h3>Technitium DNS</h3>
<p class="text-sm text-muted">Secure DNS Server</p>
</a>
<a href="https://nextcloud.com" class="grid-item lab-item" target="_blank">
<h3>Nextcloud</h3>
<p class="text-sm text-muted">File Collaboration</p>
</a>
</div>
</div>
</section>
<!-- Contact -->
<section id="contact" class="section"
style="border-top: 1px solid var(--border); flex: 1; display: flex; flex-direction: column; justify-content: flex-end;">
<div class="container">
<h2 class="mb-12" style="font-size: clamp(2rem, 5vw, 3.5rem);">Let's Connect.</h2>
<div class="grid grid-cols-2" style="border: none; background: transparent; gap: 2rem;">
<!-- Matrix -->
<a href="https://matrix.to/#/@jarne:zerozipp.dev" target="_blank" class="contact-card">
<div class="flex" style="justify-content: space-between; align-items: flex-start;">
<div class="icon-box">
<img src="icons/terminal.svg" alt="Terminal" viewBox="0 0 24 24">
</div>
<span class="text-sm font-mono text-muted">PREFERRED</span>
</div>
<div>
<h3 class="mb-2">Matrix</h3>
<p class="text-sm text-muted font-mono">@jarne:zerozipp.dev</p>
</div>
</a>
<!-- Email -->
<a href="mailto:jarne@zerozipp.dev" class="contact-card">
<div class="flex" style="justify-content: space-between; align-items: flex-start;">
<div class="icon-box">
<img src="icons/envelope.svg" alt="Envelope">
</div>
</div>
<div>
<h3 class="mb-2">Email</h3>
<p class="text-sm text-muted font-mono">jarne@zerozipp.dev</p>
</div>
</a>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<div class="container flex font-mono">
<div>© 2026 Jarne Götz</div>
<div class="flex gap-4">
<span>zerozipp.dev</span>
</div>
</div>
</footer>
</body>
</html>
+455
View File
@@ -0,0 +1,455 @@
:root {
/* Monochromatic Palette */
--bg-body: #09090b;
/* neutral-950 */
--bg-card: #09090b;
--bg-hover: #18181b;
/* neutral-900 */
--fg-primary: #fafafa;
/* neutral-50 */
--fg-secondary: #a1a1aa;
/* neutral-400 */
--fg-muted: #71717a;
/* neutral-500 */
--border: #27272a;
/* neutral-800 */
--accent: #ffffff;
--spacing-unit: 1rem;
--container-width: 960px;
}
/* Reset & Base */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
}
body {
background-color: var(--bg-body);
color: var(--fg-primary);
font-family: 'Space Grotesk', sans-serif;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
/* Typography */
h1,
h2,
h3,
h4,
p {
font-weight: 400;
}
h1 {
font-size: clamp(2.5rem, 5vw, 4rem);
line-height: 0.95;
font-weight: 700;
letter-spacing: -0.03em;
}
h2 {
font-size: clamp(1.5rem, 3vw, 2.25rem);
font-weight: 700;
letter-spacing: -0.02em;
}
h3 {
font-size: 1.25rem;
font-weight: 700;
}
a {
color: inherit;
text-decoration: none;
transition: color 0.15s ease;
}
ul {
list-style: none;
}
/* Layout Utilities */
.container {
max-width: var(--container-width);
margin: 0 auto;
padding: 0 1.5rem;
}
.section {
padding: 5rem 0;
}
.grid {
display: grid;
gap: 1px;
background-color: var(--border);
border: 1px solid var(--border);
}
.grid-item {
background-color: var(--bg-card);
padding: 2rem;
}
.grid-cols-2 {
grid-template-columns: 1fr;
}
.grid-cols-3 {
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.grid-cols-2 {
grid-template-columns: 1fr 1fr;
}
.grid-cols-3 {
grid-template-columns: repeat(3, 1fr);
}
}
/* Navigation */
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 64px;
background-color: rgba(9, 9, 11, 0.9);
backdrop-filter: blur(8px);
border-bottom: 1px solid var(--border);
z-index: 50;
display: flex;
align-items: center;
}
.nav-inner {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.logo {
font-weight: 700;
font-size: 1.25rem;
letter-spacing: -0.03em;
}
/* Mobile Menu - CSS Only with Checkbox Hack */
#menu-toggle {
display: none;
}
.nav-links {
display: none;
gap: 2rem;
font-size: 0.875rem;
font-weight: 500;
position: absolute;
top: 64px;
left: 0;
right: 0;
background-color: rgba(9, 9, 11, 0.98);
border-bottom: 1px solid var(--border);
flex-direction: column;
padding: 1rem 1.5rem;
gap: 1rem;
}
@media (min-width: 768px) {
.nav-links {
display: flex;
position: static;
background-color: transparent;
border-bottom: none;
flex-direction: row;
padding: 0;
}
}
#menu-toggle:checked+.nav-inner .nav-links {
display: flex;
}
.nav-links a:hover {
color: var(--fg-muted);
}
.nav-links a {
padding: 0.5rem 0;
}
@media (min-width: 768px) {
.nav-links a {
padding: 0;
}
}
/* Hamburger Menu Label */
.mobile-menu-label {
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
color: white;
cursor: pointer;
padding: 0.5rem;
}
@media (min-width: 768px) {
.mobile-menu-label {
display: none;
}
}
/* Components */
.btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
font-size: 0.875rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
border: 1px solid var(--border);
transition: all 0.2s ease;
}
.btn-primary {
background-color: white;
color: black;
border-color: white;
}
.btn-primary:hover {
background-color: #e5e5e5;
border-color: #e5e5e5;
}
.btn-secondary {
background-color: transparent;
color: white;
border-color: var(--fg-muted);
}
.btn-secondary:hover {
border-color: white;
background-color: rgba(255, 255, 255, 0.05);
}
.tag {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.25rem 0.5rem;
border: 1px solid var(--border);
color: var(--fg-muted);
display: inline-block;
}
/* Tech Strip - Fixed Overflow */
.tech-strip {
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
background-color: #18181b33;
padding: 2rem 0;
overflow-x: auto;
white-space: nowrap;
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
}
.tech-strip::-webkit-scrollbar {
display: none;
/* Chrome, Safari, Opera */
}
.tech-strip-inner {
display: flex;
width: 100%;
}
.tech-strip span {
margin-right: 2rem;
color: var(--fg-muted);
font-size: 0.875rem;
}
.tech-strip span:last-child {
margin-right: 0;
}
/* Project Cards */
.project-card {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 2rem;
}
.project-card {
flex-direction: column;
}
@media (min-width: 768px) {
.project-card {
flex-direction: row;
}
}
.project-links {
display: flex;
flex-direction: column;
gap: 0.75rem;
min-width: 140px;
}
.lab-item {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
gap: 0.5rem;
}
.lab-item:hover {
background-color: var(--bg-hover);
}
.contact-card {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 12rem;
border: 1px solid var(--border);
padding: 2rem;
transition: border-color 0.2s ease, background-color 0.2s ease;
}
.contact-card:hover {
border-color: white;
background-color: var(--bg-hover);
}
.icon-box {
width: 40px;
height: 40px;
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
}
/* Utils */
.text-muted {
color: var(--fg-secondary);
}
.text-sm {
font-size: 0.875rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.mb-6 {
margin-bottom: 1.5rem;
}
.mb-8 {
margin-bottom: 2rem;
}
.mb-12 {
margin-bottom: 3rem;
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.gap-2 {
gap: 0.5rem;
}
.gap-4 {
gap: 1rem;
}
.uppercase {
text-transform: uppercase;
}
.font-mono {
font-family: monospace;
}
/* Footer */
footer {
border-top: 1px solid var(--border);
padding: 2rem 0;
font-size: 0.75rem;
color: var(--fg-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
footer .flex {
justify-content: space-between;
}
@media (max-width: 768px) {
footer .flex {
flex-direction: column;
align-items: center;
gap: 1rem;
}
}
/* SVG Icons */
svg {
width: 20px;
height: 20px;
stroke: currentColor;
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.icon-sm {
width: 16px;
height: 16px;
}
.icon-md {
width: 24px;
height: 24px;
}
.icon-lg {
width: 28px;
height: 28px;
}
+9
View File
@@ -0,0 +1,9 @@
use rocket::fs::FileServer;
#[rocket::main]
async fn main() -> Result<(), Box<rocket::Error>> {
let frontend = FileServer::from("frontend");
let server = rocket::build().mount("/", frontend);
server.launch().await?;
Ok(())
}