Fix category styling, replace Network with Skills section, fix terminal to stop after 3 commands

This commit is contained in:
Roberth Rajala 2026-02-01 17:58:51 +01:00
parent 5dd6161b93
commit 41987fba17
3 changed files with 163 additions and 91 deletions

View File

@ -262,7 +262,7 @@
<div class="services-category">
<h3 class="category-title">
<span class="category-icon">🌐</span>
Public Services
<span class="category-title-text">Public Services</span>
<span class="category-badge">Open Access</span>
</h3>
<div class="services-grid">
@ -326,7 +326,7 @@
<div class="services-category">
<h3 class="category-title">
<span class="category-icon">🔒</span>
Private Services
<span class="category-title-text">Private Services</span>
<span class="category-badge">Restricted Access</span>
</h3>
<div class="services-grid">
@ -517,80 +517,74 @@
</div>
</section>
<!-- Network Section -->
<section id="network" class="section network-section">
<!-- Skills & Stack Section -->
<section id="skills" class="section skills-section">
<div class="section-container">
<div class="section-header">
<span class="section-badge">🌐 Sub-Domains</span>
<h2 class="section-title">Network</h2>
<p class="section-desc">Explore the LemonLink ecosystem</p>
<span class="section-badge">🛠️ Toolbox</span>
<h2 class="section-title">Skills & Stack</h2>
<p class="section-desc">Technologies and tools I work with</p>
</div>
<div class="network-map">
<div class="domain-hub">
<div class="hub-center">
<span class="hub-icon">🍋</span>
<span class="hub-text">lemonlink.eu</span>
</div>
<div class="hub-connections">
<svg class="connections-svg" viewBox="0 0 800 400" preserveAspectRatio="xMidYMid meet">
<defs>
<linearGradient id="line-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgba(234,179,8,0.2)"/>
<stop offset="50%" style="stop-color:rgba(234,179,8,0.8)"/>
<stop offset="100%" style="stop-color:rgba(234,179,8,0.2)"/>
</linearGradient>
</defs>
</svg>
<div class="skills-grid">
<div class="skill-category">
<h3 class="skill-cat-title">Virtualization</h3>
<div class="skill-tags">
<span class="skill-tag">Proxmox VE</span>
<span class="skill-tag">KVM/QEMU</span>
<span class="skill-tag">LXC Containers</span>
<span class="skill-tag">VMware</span>
</div>
</div>
<div class="domains-grid">
<a href="https://cloud.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">cloud</span>
<span class="node-desc">Nextcloud Storage</span>
</a>
<a href="https://git.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">git</span>
<span class="node-desc">Gitea Repositories</span>
</a>
<a href="https://stats.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">stats</span>
<span class="node-desc">Netdata Monitoring</span>
</a>
<a href="https://photos.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">photos</span>
<span class="node-desc">Immich Gallery</span>
</a>
<a href="https://dash.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">dash</span>
<span class="node-desc">Homarr Dashboard</span>
</a>
<a href="https://vpn.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">vpn</span>
<span class="node-desc">Tailscale Access</span>
</a>
<a href="https://lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">www</span>
<span class="node-desc">This Website</span>
</a>
<a href="https://git.lemonlink.eu/impulsivefps" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">projects</span>
<span class="node-desc">My Code</span>
</a>
<a href="https://retro.lemonlink.eu" class="domain-node" target="_blank">
<div class="node-pulse"></div>
<span class="node-name">retro</span>
<span class="node-desc">🎮 Classic Games</span>
</a>
<div class="skill-category">
<h3 class="skill-cat-title">Containerization</h3>
<div class="skill-tags">
<span class="skill-tag">Docker</span>
<span class="skill-tag">Docker Compose</span>
<span class="skill-tag">Portainer</span>
<span class="skill-tag">Kubernetes</span>
</div>
</div>
<div class="skill-category">
<h3 class="skill-cat-title">Networking</h3>
<div class="skill-tags">
<span class="skill-tag">Nginx Proxy Manager</span>
<span class="skill-tag">Tailscale</span>
<span class="skill-tag">VLANs</span>
<span class="skill-tag">WireGuard</span>
</div>
</div>
<div class="skill-category">
<h3 class="skill-cat-title">Storage</h3>
<div class="skill-tags">
<span class="skill-tag">TrueNAS SCALE</span>
<span class="skill-tag">ZFS</span>
<span class="skill-tag">NFS</span>
<span class="skill-tag">Samba</span>
</div>
</div>
<div class="skill-category">
<h3 class="skill-cat-title">Monitoring</h3>
<div class="skill-tags">
<span class="skill-tag">Netdata</span>
<span class="skill-tag">Grafana</span>
<span class="skill-tag">Prometheus</span>
<span class="skill-tag">Uptime Kuma</span>
</div>
</div>
<div class="skill-category">
<h3 class="skill-cat-title">Development</h3>
<div class="skill-tags">
<span class="skill-tag">Git/Gitea</span>
<span class="skill-tag">CI/CD</span>
<span class="skill-tag">Bash</span>
<span class="skill-tag">Python</span>
</div>
</div>
</div>
</div>

View File

@ -363,8 +363,6 @@ function initLimitedTerminalTyping() {
];
let currentCommand = 0;
let cycleCount = 0;
const maxCycles = 3;
let isTyping = false;
const typeCommand = () => {
@ -416,13 +414,7 @@ function initLimitedTerminalTyping() {
terminal.scrollTop = terminal.scrollHeight;
isTyping = false;
currentCommand++;
// Count completed cycles
if (currentCommand >= commands.length) {
currentCommand = 0;
cycleCount++;
}
currentCommand = (currentCommand + 1) % commands.length;
}, 500);
}
};
@ -430,18 +422,19 @@ function initLimitedTerminalTyping() {
typeChar();
};
// Start typing effect every 5 seconds - loops forever, clears after 3 cycles
setInterval(() => {
// Reset terminal after 3 cycles
if (cycleCount >= maxCycles) {
// Clear all dynamic content
const dynamicContent = terminal.querySelectorAll('.terminal-line:nth-child(n+4), .terminal-output');
dynamicContent.forEach(el => el.remove());
currentCommand = 0;
cycleCount = 0;
// Start typing effect - only run 3 commands total, then stop
let commandsTyped = 0;
const maxCommands = 3;
const intervalId = setInterval(() => {
if (commandsTyped >= maxCommands) {
clearInterval(intervalId);
// Just keep the cursor blinking on last line
return;
}
typeCommand();
}, 5000);
commandsTyped++;
}, 4000);
}
/**

View File

@ -1709,13 +1709,23 @@ body {
.category-title {
font-family: 'Space Grotesk', sans-serif;
font-size: 1.25rem;
font-size: 1.1rem;
font-weight: 600;
color: var(--color-text);
color: var(--color-text-muted);
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 0.75rem;
gap: 0.5rem;
text-transform: uppercase;
letter-spacing: 1px;
}
.category-title .category-icon {
font-size: 1.2rem;
}
.category-title-text {
color: var(--color-text);
}
.category-icon {
@ -1766,3 +1776,78 @@ body {
width: 20px;
height: 20px;
}
/* ========================================
Skills Section
======================================== */
.skills-section {
background: linear-gradient(180deg, transparent 0%, rgba(99, 102, 241, 0.05) 50%, transparent 100%);
}
.skills-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
.skill-category {
background: var(--color-bg-card);
backdrop-filter: blur(20px);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: 1.5rem;
transition: var(--transition-normal);
}
.skill-category:hover {
transform: translateY(-3px);
border-color: rgba(234, 179, 8, 0.3);
box-shadow: var(--shadow-card);
}
.skill-cat-title {
font-family: 'Space Grotesk', sans-serif;
font-size: 0.9rem;
font-weight: 600;
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--color-border);
}
.skill-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.skill-tag {
padding: 0.4rem 0.8rem;
background: rgba(255, 255, 255, 0.05);
border: 1px solid var(--color-border);
border-radius: 100px;
font-size: 0.85rem;
color: var(--color-text);
transition: var(--transition-fast);
}
.skill-tag:hover {
background: rgba(234, 179, 8, 0.1);
border-color: rgba(234, 179, 8, 0.3);
color: var(--color-primary);
}
@media (max-width: 1024px) {
.skills-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.skills-grid {
grid-template-columns: 1fr;
}
}