Portfolio/portfolio.html
2025-04-18 03:42:35 -04:00

510 lines
No EOL
16 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vi0's Portfolio</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--bg-color: #f9f9f9;
--text-color: #202020;
--card-bg: #ffffff;
--shadow: rgba(0, 0, 0, 0.1);
--accent: #0078d7;
--accent-hover: #106ebe;
--border-color: #e0e0e0;
--card-hover: #f3f3f3;
--taskbar-bg: rgba(243, 243, 243, 0.85);
--search-bg: #f0f0f0;
}
.dark-mode {
--bg-color: #1f1f1f;
--text-color: #ffffff;
--card-bg: #2d2d2d;
--shadow: rgba(0, 0, 0, 0.3);
--accent: #60cdff;
--accent-hover: #8adaff;
--border-color: #3d3d3d;
--card-hover: #3a3a3a;
--taskbar-bg: rgba(45, 45, 45, 0.85);
--search-bg: #3d3d3d;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', sans-serif;
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
min-height: 100vh;
padding-bottom: 48px;
position: relative;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 24px;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
padding: 12px;
border-radius: 8px;
backdrop-filter: blur(10px);
background-color: var(--card-bg);
box-shadow: 0 4px 12px var(--shadow);
}
.profile {
display: flex;
align-items: center;
gap: 16px;
}
.profile-img {
width: 64px;
height: 64px;
border-radius: 50%;
object-fit: cover;
border: 2px solid var(--accent);
}
.profile-info h1 {
font-size: 24px;
margin-bottom: 4px;
}
.profile-info p {
color: var(--text-color);
opacity: 0.8;
}
.actions {
display: flex;
gap: 12px;
align-items: center;
}
.search-bar {
position: relative;
margin-right: 12px;
}
.search-bar input {
background-color: var(--search-bg);
border: none;
border-radius: 20px;
padding: 8px 16px 8px 36px;
color: var(--text-color);
width: 200px;
outline: none;
}
.search-bar i {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-color);
opacity: 0.7;
}
.theme-toggle {
background-color: var(--card-bg);
color: var(--text-color);
border: 1px solid var(--border-color);
border-radius: 20px;
padding: 8px 16px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
}
.theme-toggle:hover {
background-color: var(--card-hover);
}
.xivo-button {
background-color: var(--accent);
color: white;
border: none;
border-radius: 20px;
padding: 8px 16px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
}
.xivo-button:hover {
background-color: var(--accent-hover);
}
.forgejo-button {
background-color: #333;
color: white;
border: none;
border-radius: 20px;
padding: 8px 16px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
}
.forgejo-button:hover {
background-color: #444;
}
.section-title {
margin: 24px 0 16px;
font-size: 20px;
position: relative;
padding-bottom: 8px;
}
.section-title::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 60px;
height: 3px;
background-color: var(--accent);
border-radius: 3px;
}
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
}
.project-card {
background-color: var(--card-bg);
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px var(--shadow);
transition: transform 0.3s, box-shadow 0.3s;
}
.project-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 24px var(--shadow);
}
.project-image {
height: 160px;
background-size: cover;
background-position: center;
background-color: var(--accent);
display: flex;
align-items: center;
justify-content: center;
}
.project-image i {
font-size: 48px;
color: white;
}
.project-content {
padding: 16px;
}
.project-content h3 {
margin-bottom: 8px;
font-size: 18px;
}
.project-content p {
margin-bottom: 16px;
color: var(--text-color);
opacity: 0.8;
font-size: 14px;
line-height: 1.4;
}
.project-button {
background-color: var(--accent);
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.project-button:hover {
background-color: var(--accent-hover);
}
.taskbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 48px;
background-color: var(--taskbar-bg);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 -2px 10px var(--shadow);
z-index: 100;
}
.taskbar-item {
width: 40px;
height: 40px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.taskbar-item:hover {
background-color: var(--card-hover);
}
.taskbar-item i {
font-size: 20px;
color: var(--text-color);
}
.tooltip {
position: absolute;
background-color: var(--card-bg);
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
bottom: 56px;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
box-shadow: 0 4px 8px var(--shadow);
white-space: nowrap;
}
.taskbar-item:hover .tooltip {
opacity: 1;
visibility: visible;
}
.hidden {
display: none;
}
@media (max-width: 768px) {
.header {
flex-direction: column;
align-items: flex-start;
}
.profile {
margin-bottom: 16px;
}
.actions {
width: 100%;
justify-content: space-between;
}
.search-bar {
width: 100%;
margin-right: 0;
margin-bottom: 16px;
}
.search-bar input {
width: 100%;
}
.projects-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="profile">
<img src="/api/placeholder/64/64" alt="vi0's Profile Picture" class="profile-img" id="profile-img">
<div class="profile-info">
<h1>vi0</h1>
<p>Young developer | Pronunciation: v-eye-zero</p>
</div>
</div>
<div class="actions">
<div class="search-bar">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search projects..." id="search-input">
</div>
<button class="xivo-button" id="copy-xivo">
<i class="fas fa-copy"></i>
<span>COPY XIVO ID: vi0</span>
</button>
<a href="https://git.nadeko.net/vi0" target="_blank" class="forgejo-button">
<i class="fas fa-code-branch"></i>
<span>Forgejo</span>
</a>
<button class="theme-toggle" id="theme-toggle">
<i class="fas fa-moon"></i>
<span>Dark Mode</span>
</button>
</div>
</div>
<h2 class="section-title">About Me</h2>
<p>I'm vi0, a 13-year-old passionate coder who always has something to build. I love creating web applications and tools that solve problems and make life easier for users. When I'm not coding, I'm probably thinking about my next project!</p>
<h2 class="section-title">My Projects</h2>
<div class="projects-grid" id="projects-container">
<!-- Projects will be loaded here -->
</div>
</div>
<script>
// Project data
const projects = [
{
id: 1,
name: "Xivo",
description: "A free chat application that runs in your browser with a clean interface. Chat with friends without downloads or complex setups.",
icon: "fa-comments",
link: "https://git.nadeko.net/vi0/Xivo"
},
{
id: 2,
name: "Clax",
description: "An Eaglercraft resources page with everything you need for Minecraft gameplay in the browser.",
icon: "fa-gamepad",
link: "https://git.nadeko.net/vi0/Clax"
},
{
id: 3,
name: "YueJ",
description: "Run .yue files in the browser to mod websites with ease. Add custom cursors, dark mode, and more to your favorite websites.",
icon: "fa-code",
link: "https://git.nadeko.net/vi0/YueJ"
}
];
// Load projects
function loadProjects(projectsToShow = projects) {
const projectsContainer = document.getElementById('projects-container');
projectsContainer.innerHTML = '';
if (projectsToShow.length === 0) {
projectsContainer.innerHTML = '<p>No projects found matching your search.</p>';
return;
}
projectsToShow.forEach(project => {
const projectCard = document.createElement('div');
projectCard.className = 'project-card';
projectCard.innerHTML = `
<div class="project-image">
<i class="fas ${project.icon}"></i>
</div>
<div class="project-content">
<h3>${project.name}</h3>
<p>${project.description}</p>
<button class="project-button" data-id="${project.id}">View Project</button>
</div>
`;
projectsContainer.appendChild(projectCard);
});
// Add event listeners to project buttons
document.querySelectorAll('.project-button').forEach(button => {
button.addEventListener('click', function() {
const projectId = this.getAttribute('data-id');
const project = projects.find(p => p.id == projectId);
if (confirm(`Open ${project.name} Project?`)) {
window.open(project.link, '_blank');
}
});
});
}
// Initialize projects
loadProjects();
// Search functionality
const searchInput = document.getElementById('search-input');
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
const filteredProjects = projects.filter(project =>
project.name.toLowerCase().includes(searchTerm) ||
project.description.toLowerCase().includes(searchTerm)
);
loadProjects(filteredProjects);
});
// Theme toggle
const themeToggle = document.getElementById('theme-toggle');
const themeIcon = themeToggle.querySelector('i');
const themeText = themeToggle.querySelector('span');
// Check for saved theme preference or default to light
const savedTheme = localStorage.getItem('theme') || 'dark';
if (savedTheme === 'dark') {
document.body.classList.add('dark-mode');
themeIcon.classList.replace('fa-moon', 'fa-sun');
themeText.textContent = 'Light Mode';
}
themeToggle.addEventListener('click', function() {
document.body.classList.toggle('dark-mode');
if (document.body.classList.contains('dark-mode')) {
themeIcon.classList.replace('fa-moon', 'fa-sun');
themeText.textContent = 'Light Mode';
localStorage.setItem('theme', 'dark');
} else {
themeIcon.classList.replace('fa-sun', 'fa-moon');
themeText.textContent = 'Dark Mode';
localStorage.setItem('theme', 'light');
}
});
// Copy Xivo ID
const copyXivoBtn = document.getElementById('copy-xivo');
copyXivoBtn.addEventListener('click', function() {
navigator.clipboard.writeText('vi0').then(() => {
const originalText = this.innerHTML;
this.innerHTML = '<i class="fas fa-check"></i><span>Copied!</span>';
setTimeout(() => {
this.innerHTML = originalText;
}, 2000);
});
});
// Placeholder for profile image (to be replaced with actual image)
document.getElementById('profile-img').addEventListener('error', function() {
this.src = 'https://media-hosting.imagekit.io/ee59b42f4f784512/v-letter-logo-icon-for-business-and-company-vector (1).jpg?Expires=1839419020&Key-Pair-Id=K2ZIVPTIP2VGHC&Signature=aMDXsZfgF3jISb7sKahmvuL5bdqTV6g3ZTd71R7qD3UFokg5V9mx74OO8P52o~kNAp4ZNmIQEE2UrdVZ4Lm~JoECQrPV62YF4hm5LgCXFtQ16otvIXUJxl~s2kgM176pn1HFf-V-FOyltGmJgYzjsowywE-rzSWhCccA-KgjCxPtzL6cOi6HjM~X4KIUH2AyzdhS-FhJfFzDPcjZyavPciC0XZYZKgqNNVkWu4YTW376LByT3NNXufuRsc50cEvKfBJWSWNyK86C2AZkv0AXCQwk~UAXvaW6hi0sHmptFZTXXRDL8Al5KFX6tXhflE2P89oo567~hBPta1Lrx1Evpw__';
});
</script>
</body>
</html>