fix: update styles and component fixes

This commit is contained in:
End 2025-02-17 23:53:22 -07:00
parent e865983761
commit 815b363a96
No known key found for this signature in database
25 changed files with 561 additions and 901 deletions

View file

@ -1,98 +1,90 @@
{
"name": "personal-site",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "powershell ./dev.ps1",
"dev": "vite --host 0.0.0.0",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"deploy": "powershell ./deploy.ps1",
"setup": "powershell ./first-time-setup.ps1",
"clean": "rimraf node_modules dist .wrangler .cloudflare",
"type-check": "tsc --noEmit",
"format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
"test": "vitest",
"test:ui": "vitest --ui",
"prepare": "husky install",
"build:worker": "esbuild --bundle src/worker/index.ts --outfile=dist/worker/index.js --format=esm --platform=browser",
"dev:worker": "wrangler dev src/worker/index.ts",
"deploy:worker": "wrangler deploy src/worker/index.ts"
},
"dependencies": {
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"itty-router": "^4.0.27",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.0",
"tailwind-merge": "^2.2.1",
"zustand": "5.0.3"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20250129.0",
"@commitlint/cli": "^18.6.0",
"@commitlint/config-conventional": "^18.6.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "20.17.16",
"@types/react": "18.3.18",
"@types/react-dom": "18.3.5",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/ui": "^1.2.2",
"autoprefixer": "10.4.20",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"husky": "^9.0.10",
"jsdom": "^24.0.0",
"lint-staged": "^15.2.2",
"lucide-react": "0.474.0",
"postcss": "8.5.1",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"rimraf": "^5.0.5",
"tailwindcss": "3.4.17",
"typescript": "^5.3.3",
"vite": "^5.1.0",
"vitest": "^1.2.2",
"web-vitals": "4.2.4",
"wrangler": "^3.28.0"
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{html,css,json,md}": [
"prettier --write"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"engines": {
"node": ">=18.0.0"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
"name": "personal-site",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "vite",
"lint": "eslint . --ext ts,tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
"build": "tsc \u0026\u0026 vite build",
"type-check": "tsc --noEmit",
"dev": "vite --host 0.0.0.0",
"clean": "rimraf dist node_modules/.cache",
"preview": "vite preview"
},
"dependencies": {
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"itty-router": "^4.0.27",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.0",
"tailwind-merge": "^2.2.1",
"zustand": "5.0.3"
},
"devDependencies": {
"@cloudflare/workers-types": "4.20250129.0",
"@commitlint/cli": "^18.6.0",
"@commitlint/config-conventional": "^18.6.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@testing-library/user-event": "^14.5.2",
"@types/node": "20.17.16",
"@types/react": "18.3.18",
"@types/react-dom": "18.3.5",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/ui": "^1.2.2",
"autoprefixer": "10.4.20",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"husky": "^9.0.10",
"jsdom": "^24.0.0",
"lint-staged": "^15.2.2",
"lucide-react": "0.474.0",
"postcss": "8.5.1",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"rimraf": "^5.0.5",
"tailwindcss": "3.4.17",
"typescript": "^5.3.3",
"vite": "^5.1.0",
"vitest": "^1.2.2",
"web-vitals": "4.2.4",
"wrangler": "^3.28.0"
},
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{html,css,json,md}": [
"prettier --write"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"engines": {
"node": "\u003e=18.0.0"
},
"browserslist": {
"production": [
"\u003e0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View file

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>APCSP Project</title>
<link rel="stylesheet" href="/pages/style.css"> <!-- CSS with correct path -->
</head>
<body>
<!-- Include the Navbar -->
<div id="navbar"></div>
<script>
// Load the navbar
fetch('/pages/navbar.html') <!-- Correct path within pages folder -->
.then(response => response.text())
.then(data => {
document.getElementById('navbar').innerHTML = data;
});
</script>
<!-- Page Content -->
<header class="header">
<div class="header-content">
<h1>APCSP</h1>
<p class="apcsp-blurb">AP Computer Science Principles (APCSP) offers a multidisciplinary approach to teaching the foundations of modern computing. The course will introduce students to the creative aspects of programming, abstractions, algorithms, large data sets, the Internet, cybersecurity concerns, and societal impacts of computing. APCSP also gives students the opportunity to use current technologies to create computational artifacts for both self-expression and problem solving. This course seeks to provide knowledge and skills to meaningfully participate in our increasingly digital society, economy, and culture. Together, these aspects of the course make up a rigorous and rich curriculum that aims to broaden participation in computer science.</p>
</div>
</header>
<main class="main-content">
<h2 class="section-title">APCSP Project</h2>
<div class="project-demo">
<h3>Demo of My Project</h3>
<iframe
src="https://drive.google.com/file/d/1JT7nZ82QJh5NIxFVHyewRBR1MLsWohEF/preview"
width="640"
height="480"
allow="autoplay">
</iframe>
<p><a href="https://drive.google.com/file/d/1JT7nZ82QJh5NIxFVHyewRBR1MLsWohEF/view" target="_blank">View the full demo</a></p>
</div>
</main>
<script src="/pages/theme-toggle.js"></script> <!-- Correct path within pages folder -->
</body>
</html>

View file

View file

View file

@ -1,33 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Projects</title>
<link rel="stylesheet" href="/pages/style.css">
</head>
<body>
<div id="loading">
<div class="spinner"></div>
</div>
<div id="navbar"></div>
<script>
fetch('/pages/navbar.html')
.then(response => response.text())
.then(data => {
document.getElementById('navbar').innerHTML = data;
});
</script>
<main>
<img src="/logo.png" alt="Logo" style="width: 100px; height: auto;">
<h1>My GitHub Projects</h1>
<ul id="repo-list"></ul>
</main>
<script>
window.addEventListener('load', () => {
document.getElementById('loading').style.display = 'none';
});
</script>
<script src="/scripts/github-repos.js"></script>
</body>
</html>

View file

@ -1,10 +0,0 @@
<nav>
<ul>
<li><a href="/public/pages/about-us.html">About Us</a><li>
<li><a href="/public/pages/system.html">Our system></a></li>
<li><a href="../index.html">Home</a></li>
<li><a href="/public/pages/APCSP.html">APCSP Project</a></li>
<li><a href="/public/pages/github-repos.html">GitHub Projects</a></li>
</ul>
<input type="color" id="theme-color-picker" title="Choose your color">
</nav>

View file

@ -1,106 +0,0 @@
/* public/pages/style.css */
:root {
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
}
body {
margin: 0;
min-height: 100vh;
background: linear-gradient(135deg, var(--background-primary), var(--background-secondary));
color: var(--text-primary);
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
/* Neon text effect */
.neon-text {
color: var(--text-primary);
text-shadow: 0 0 5px var(--text-glow),
0 0 10px var(--text-glow),
0 0 20px var(--accent-neon);
}
/* Interactive elements */
a, button {
color: var(--text-primary);
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 8px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
a:hover, button:hover {
color: var(--accent-neon);
text-shadow: 0 0 5px var(--text-glow);
transform: translateY(-2px);
}
/* Card styling */
.card {
background: rgba(47, 28, 84, 0.3);
backdrop-filter: blur(10px);
border: 1px solid rgba(157, 78, 221, 0.2);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s ease;
}
.card:hover {
border-color: var(--accent-neon);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
}
/* Navigation styling */
nav {
background: rgba(36, 0, 70, 0.8);
backdrop-filter: blur(10px);
padding: 1rem;
}
nav ul {
display: flex;
gap: 2rem;
justify-content: center;
list-style: none;
}
nav a {
font-weight: 500;
letter-spacing: 0.5px;
}
nav a:hover {
color: var(--accent-neon);
text-shadow: 0 0 10px var(--text-glow);
}
/* Content sections */
.content-section {
padding: 2rem;
margin: 2rem 0;
background: rgba(26, 11, 46, 0.5);
border-radius: 16px;
}
/* Animated gradient background */
@keyframes gradientAnimation {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.animated-bg {
background: linear-gradient(135deg,
var(--background-primary),
var(--background-secondary),
var(--dark-accent));
background-size: 200% 200%;
animation: gradientAnimation 15s ease infinite;
}

View file

@ -1,158 +1,138 @@
/* src/App.css */
:root {
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 10px;
width: 10px;
}
::-webkit-scrollbar-track {
background: var(--background-primary);
background: var(--background-primary);
}
::-webkit-scrollbar-thumb {
background: var(--accent-primary);
border-radius: 5px;
background: var(--accent-primary);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--accent-neon);
box-shadow: 0 0 10px var(--text-glow);
background: var(--accent-neon);
box-shadow: 0 0 10px var(--text-glow);
}
/* Particle Effects */
.particle-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.particle {
position: absolute;
width: 3px;
height: 3px;
background: var(--text-glow);
border-radius: 50%;
animation: particleFloat linear infinite;
opacity: 0.5;
position: absolute;
width: 3px;
height: 3px;
background: var(--text-glow);
border-radius: 50%;
animation: particleFloat linear infinite;
opacity: 0.5;
}
@keyframes particleFloat {
0% {
transform: translateY(100vh) scale(0);
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
transform: translateY(-20vh) scale(1);
opacity: 0;
}
0% {
transform: translateY(100vh) scale(0);
opacity: 0;
}
50% {
opacity: 0.5;
}
100% {
transform: translateY(-20vh) scale(1);
opacity: 0;
}
}
/* Main Layout */
.app-container {
min-height: 100vh;
background: linear-gradient(135deg, var(--background-primary), var(--background-secondary));
color: var(--text-primary);
font-family: 'Inter', sans-serif;
position: relative;
overflow-x: hidden;
min-height: 100vh;
background: linear-gradient(135deg, var(--background-primary), var(--background-secondary));
color: var(--text-primary);
font-family: 'Inter', sans-serif;
position: relative;
overflow-x: hidden;
}
/* Header Styles */
.header {
text-align: center;
padding: 4rem 2rem;
text-align: center;
padding: 4rem 2rem;
}
.header h1 {
font-size: 3.5rem;
margin-bottom: 1rem;
font-size: 3.5rem;
margin-bottom: 1rem;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
font-size: 1.2rem;
opacity: 0.9;
}
/* Content Sections */
.content-section {
max-width: 1200px;
margin: 2rem auto;
padding: 2rem;
background: rgba(26, 11, 46, 0.5);
backdrop-filter: blur(10px);
border-radius: 16px;
position: relative;
z-index: 2;
max-width: 1200px;
margin: 2rem auto;
padding: 2rem;
background: rgba(26, 11, 46, 0.5);
backdrop-filter: blur(10px);
border-radius: 16px;
position: relative;
z-index: 2;
}
/* Interests Grid */
.interests-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
margin-top: 2rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
.interest-card {
background: rgba(47, 28, 84, 0.3);
padding: 1.5rem;
border-radius: 12px;
border: 1px solid rgba(157, 78, 221, 0.2);
transition: all 0.3s ease;
background: rgba(47, 28, 84, 0.3);
padding: 1.5rem;
border-radius: 12px;
border: 1px solid rgba(157, 78, 221, 0.2);
transition: all 0.3s ease;
}
.interest-card:hover {
transform: translateY(-5px);
border-color: var(--accent-neon);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
transform: translateY(-5px);
border-color: var(--accent-neon);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
}
/* Twitch Button */
.twitch-button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: #9146ff;
color: white;
padding: 0.75rem 1.5rem;
border-radius: 8px;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 0.5rem;
background: #9146ff;
color: white;
padding: 0.75rem 1.5rem;
border-radius: 8px;
transition: all 0.3s ease;
}
.twitch-button:hover {
background: #7c2bff;
transform: translateY(-2px);
box-shadow: 0 0 15px rgba(145, 70, 255, 0.5);
background: #7c2bff;
transform: translateY(-2px);
box-shadow: 0 0 15px rgba(145, 70, 255, 0.5);
}
/* Responsive Design */
@media (max-width: 768px) {
.header h1 {
font-size: 2.5rem;
}
.content-section {
padding: 1rem;
margin: 1rem;
}
.interests-grid {
grid-template-columns: 1fr;
}
}
.header h1 {
font-size: 2.5rem;
}
.content-section {
padding: 1rem;
margin: 1rem;
}
.interests-grid {
grid-template-columns: 1fr;
}
}

View file

@ -1,35 +1,31 @@
.fox-card {
position: relative;
background: var(--gradient-card);
border-radius: 16px;
padding: 1.5rem;
border: 1px solid rgba(157, 78, 221, 0.2);
overflow: hidden;
.fox-card {
position: relative;
background: var(--gradient-card);
border-radius: 16px;
padding: 1.5rem;
border: 1px solid rgba(157, 78, 221, 0.2);
overflow: hidden;
}
.fox-ear {
position: absolute;
width: 30px;
height: 30px;
background: var(--fox-pink);
opacity: 0.1;
transition: opacity 0.3s ease;
position: absolute;
width: 30px;
height: 30px;
background: var(--fox-pink);
opacity: 0.1;
transition: opacity 0.3s ease;
}
.fox-ear-left {
top: -15px;
left: -15px;
transform: rotate(45deg);
border-radius: 0 0 0 15px;
top: -15px;
left: -15px;
transform: rotate(45deg);
border-radius: 0 0 0 15px;
}
.fox-ear-right {
top: -15px;
right: -15px;
transform: rotate(-45deg);
border-radius: 0 0 15px 0;
top: -15px;
right: -15px;
transform: rotate(-45deg);
border-radius: 0 0 15px 0;
}
.fox-card:hover .fox-ear {
opacity: 0.2;
opacity: 0.2;
}

View file

@ -1,69 +1,60 @@
.github-repos-container {
width: 100%;
padding: 1rem;
.github-repos-container {
width: 100%;
padding: 1rem;
}
.repos-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.repo-card {
background: rgba(47, 28, 84, 0.3);
border: 1px solid rgba(157, 78, 221, 0.2);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s ease;
background: rgba(47, 28, 84, 0.3);
border: 1px solid rgba(157, 78, 221, 0.2);
border-radius: 12px;
padding: 1.5rem;
transition: all 0.3s ease;
}
.repo-card:hover {
transform: translateY(-5px);
border-color: var(--accent-neon);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
transform: translateY(-5px);
border-color: var(--accent-neon);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
}
.repo-name {
font-size: 1.2rem;
font-weight: 600;
color: var(--text-primary);
text-decoration: none;
margin-bottom: 0.5rem;
display: block;
font-size: 1.2rem;
font-weight: 600;
color: var(--text-primary);
text-decoration: none;
margin-bottom: 0.5rem;
display: block;
}
.repo-name:hover {
color: var(--accent-neon);
color: var(--accent-neon);
}
.repo-description {
color: var(--text-primary);
opacity: 0.8;
margin: 0.5rem 0;
font-size: 0.9rem;
color: var(--text-primary);
opacity: 0.8;
margin: 0.5rem 0;
font-size: 0.9rem;
}
.repo-language {
display: inline-block;
padding: 0.25rem 0.75rem;
background: rgba(157, 78, 221, 0.2);
border-radius: 1rem;
font-size: 0.8rem;
color: var(--text-primary);
margin-top: 0.5rem;
display: inline-block;
padding: 0.25rem 0.75rem;
background: rgba(157, 78, 221, 0.2);
border-radius: 1rem;
font-size: 0.8rem;
color: var(--text-primary);
margin-top: 0.5rem;
}
.repo-languages {
margin-top: 0.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.5rem;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.language-tag {
padding: 0.25rem 0.75rem;
background: rgba(157, 78, 221, 0.1);
border-radius: 1rem;
font-size: 0.8rem;
color: var(--text-primary);
padding: 0.25rem 0.75rem;
background: rgba(157, 78, 221, 0.1);
border-radius: 1rem;
font-size: 0.8rem;
color: var(--text-primary);
}

View file

@ -1,49 +1,42 @@
.loading-fox-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
.loading-fox-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
}
.fox-loader {
position: relative;
width: 100px;
height: 100px;
position: relative;
width: 100px;
height: 100px;
}
.fox-face {
position: relative;
width: 60px;
height: 60px;
background: var(--fox-orange);
border-radius: 50%;
animation: bounce 1s ease-in-out infinite;
position: relative;
width: 60px;
height: 60px;
background: var(--fox-orange);
border-radius: 50%;
animation: bounce 1s ease-in-out infinite;
}
.fox-ears {
position: absolute;
top: -15px;
width: 100%;
display: flex;
justify-content: space-between;
position: absolute;
top: -15px;
width: 100%;
display: flex;
justify-content: space-between;
}
.ear {
width: 20px;
height: 20px;
background: var(--fox-orange);
border-radius: 5px;
width: 20px;
height: 20px;
background: var(--fox-orange);
border-radius: 5px;
}
.ear.left {
transform: rotate(-30deg);
transform: rotate(-30deg);
}
.ear.right {
transform: rotate(30deg);
transform: rotate(30deg);
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}

View file

@ -1,21 +1,17 @@
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
@keyframes glow {
0%, 100% { filter: drop-shadow(0 0 2px var(--accent-neon)); }
50% { filter: drop-shadow(0 0 8px var(--accent-neon)); }
0%, 100% { filter: drop-shadow(0 0 2px var(--accent-neon)); }
50% { filter: drop-shadow(0 0 8px var(--accent-neon)); }
}
.animate-float {
animation: float 3s ease-in-out infinite;
animation: float 3s ease-in-out infinite;
}
.animate-glow {
animation: glow 2s ease-in-out infinite;
animation: glow 2s ease-in-out infinite;
}
.content-spacing > * + * {
margin-top: 2rem;
margin-top: 2rem;
}

View file

@ -1,67 +1,40 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
--fox-pink: #ffc6e5;
--fox-pink-glow: #ffadd6;
--fox-orange: #ff9466;
--fox-white: #fff5f9;
}
body {
@apply bg-background-primary text-text-primary;
font-family: "Inter", sans-serif;
}
/* Global spacing */
.content-wrapper {
@apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8;
}
.section-spacing {
@apply space-y-12;
}
.card-spacing {
@apply space-y-8;
}
.element-spacing {
@apply space-y-4;
}
:root {
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
--fox-pink: #ffc6e5;
--fox-pink-glow: #ffadd6;
--fox-orange: #ff9466;
--fox-white: #fff5f9;
}
@layer components {
.nav-link {
@apply flex items-center gap-3 px-4 py-2 rounded-lg transition-all
hover:bg-accent-primary/10 hover:text-accent-neon my-1;
}
.nav-link.active {
@apply bg-accent-primary/20 text-accent-neon;
}
.fox-card {
@apply relative bg-gradient-card rounded-xl p-8 border border-accent-primary/20
transition-all hover:border-accent-neon/40 hover:shadow-lg
hover:shadow-accent-primary/10 mb-8;
}
.text-glow {
@apply text-text-primary drop-shadow-[0_0_10px_rgba(224,170,255,0.5)];
}
/* Card Grid */
.content-grid {
@apply grid gap-8 grid-cols-1 md:grid-cols-2 lg:grid-cols-3;
}
body {
@apply
font-family: "Inter", sans-serif
bg-background-primary text-text-primary;;
}
/* Global spacing */
.content-wrapper {
@apply
gap-3 px-4 py-2 my-1
items-center rounded-lg
transition-all hover:bg-accent-primary/10 hover:text-accent-neon
flex
hover:bg-accent-primary/10 hover:text-accent-neon;
}
.nav-link.active {
@apply
p-8 mb-8
rounded-xl
transition-all hover:border-accent-neon/40 hover:shadow-lg hover:shadow-accent-primary/10
relative
bg-gradient-card border border-accent-primary/20 hover:border-accent-neon/40 hover:shadow-lg hover:shadow-accent-primary/10;
}
.text-glow {

View file

@ -1,10 +1,9 @@
/* Default cursor for all elements */
* {
cursor: url('/cursors/default.svg') 16 16, auto;
cursor: url('@/assets/cursors/default.svg') 16 16, auto;
}
/* Interactive elements cursor */
a,
a,
button,
[role="button"],
input[type="submit"],
@ -12,42 +11,36 @@ input[type="button"],
select,
.interactive,
.nav-link {
cursor: url('/cursors/paw.svg') 16 16, pointer;
cursor: url('@/assets/cursors/paw.svg') 16 16, pointer;
}
/* Loading state cursor */
.loading,
:disabled,
[aria-busy="true"] {
cursor: url('/cursors/tail-loading.svg') 16 16, progress;
cursor: url('@/assets/cursors/tail-loading.svg') 16 16, progress;
}
/* Hover effects for interactive elements */
a:hover,
button:hover,
[role="button"]:hover,
.nav-link:hover {
/* Add a subtle glow effect on hover */
filter: drop-shadow(0 0 4px var(--fox-pink-glow));
transition: filter 0.3s ease;
/* Add a subtle glow effect on hover */
filter: drop-shadow(0 0 4px var(--fox-pink-glow));
transition: filter 0.3s ease;
}
/* Custom cursor regions */
.text-select {
cursor: text;
cursor: text;
}
.resize {
cursor: nw-resize;
cursor: nw-resize;
}
/* Ensure cursors work with transform effects */
* {
cursor-position: fixed;
cursor-position: fixed;
}
/* Prevent cursor inheritance in certain cases */
iframe,
canvas {
cursor: inherit;
}
cursor: inherit;
}

View file

@ -1,31 +1,26 @@
/* Game-specific styles */
.game-active * {
cursor: none;
cursor: none;
}
.game-viewport {
touch-action: none;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
touch-action: none;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
/* Animation utilities */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.3s ease-in-out;
animation: fadeIn 0.3s ease-in-out;
}
/* Game-specific shadows */
.fox-shadow {
filter: drop-shadow(0 0 8px var(--fox-pink-glow));
filter: drop-shadow(0 0 8px var(--fox-pink-glow));
}
.enemy-shadow {
filter: drop-shadow(0 0 8px rgba(255, 0, 0, 0.3));
filter: drop-shadow(0 0 8px rgba(255, 0, 0, 0.3));
}

View file

@ -1,205 +1,173 @@
/* src/styles/game.css */
@import 'base.css';
@import 'animations.css';
@import 'utilities.css';
@import 'cursor.css';
/* Base game styles */
.game-viewport {
touch-action: none;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
overflow: hidden;
background: linear-gradient(
135deg,
var(--background-primary) 0%,
var(--background-secondary) 100%
);
touch-action: none;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
overflow: hidden;
background: linear-gradient(
135deg,
var(--background-primary) 0%,
var(--background-secondary) 100%
);
}
/* Game UI elements */
.game-hud {
pointer-events: none;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
pointer-events: none;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
.game-card {
background: rgba(47, 28, 84, 0.3);
backdrop-filter: blur(8px);
border: 1px solid rgba(157, 78, 221, 0.2);
transition: all 0.3s ease;
background: rgba(47, 28, 84, 0.3);
backdrop-filter: blur(8px);
border: 1px solid rgba(157, 78, 221, 0.2);
transition: all 0.3s ease;
}
.game-card:hover {
border-color: rgba(178, 73, 248, 0.4);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
border-color: rgba(178, 73, 248, 0.4);
box-shadow: 0 0 20px rgba(178, 73, 248, 0.2);
}
/* Player animations */
.player-idle {
animation: playerIdle 2s ease-in-out infinite;
animation: playerIdle 2s ease-in-out infinite;
}
.player-move {
animation: playerMove 0.3s linear infinite;
animation: playerMove 0.3s linear infinite;
}
.player-hit {
animation: playerHit 0.5s ease-in-out;
animation: playerHit 0.5s ease-in-out;
}
@keyframes playerIdle {
0%, 100% { transform: translate(-50%, -50%); }
50% { transform: translate(-50%, calc(-50% - 4px)); }
0%, 100% { transform: translate(-50%, -50%); }
50% { transform: translate(-50%, calc(-50% - 4px)); }
}
@keyframes playerMove {
0% { transform: rotate(-2deg); }
50% { transform: rotate(2deg); }
100% { transform: rotate(-2deg); }
0% { transform: rotate(-2deg); }
50% { transform: rotate(2deg); }
100% { transform: rotate(-2deg); }
}
@keyframes playerHit {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
/* Enemy animations */
.enemy-patrol {
animation: enemyPatrol 3s linear infinite;
animation: enemyPatrol 3s linear infinite;
}
.enemy-chase {
animation: enemyChase 0.5s ease-in-out infinite;
animation: enemyChase 0.5s ease-in-out infinite;
}
@keyframes enemyPatrol {
0% { transform: translateX(0); }
50% { transform: translateX(50px); }
100% { transform: translateX(0); }
0% { transform: translateX(0); }
50% { transform: translateX(50px); }
100% { transform: translateX(0); }
}
@keyframes enemyChase {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
/* Collectible animations */
.collectible {
animation: collectibleFloat 2s ease-in-out infinite;
animation: collectibleFloat 2s ease-in-out infinite;
}
.collectible-gem {
animation: collectibleGem 3s linear infinite;
animation: collectibleGem 3s linear infinite;
}
@keyframes collectibleFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes collectibleGem {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Power-up effects */
.powerup-active {
animation: powerupPulse 1s ease-in-out infinite;
animation: powerupPulse 1s ease-in-out infinite;
}
.powerup-shield {
animation: shieldRotate 3s linear infinite;
animation: shieldRotate 3s linear infinite;
}
@keyframes powerupPulse {
0%, 100% { filter: brightness(1); }
50% { filter: brightness(1.5); }
0%, 100% { filter: brightness(1); }
50% { filter: brightness(1.5); }
}
@keyframes shieldRotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Game effects */
.particle {
position: absolute;
pointer-events: none;
animation: particleFade 1s ease-out forwards;
position: absolute;
pointer-events: none;
animation: particleFade 1s ease-out forwards;
}
@keyframes particleFade {
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(0); opacity: 0; }
0% { transform: scale(1); opacity: 1; }
100% { transform: scale(0); opacity: 0; }
}
/* Game UI animations */
.score-popup {
animation: scorePopup 0.5s ease-out forwards;
animation: scorePopup 0.5s ease-out forwards;
}
.health-change {
animation: healthChange 0.5s ease-in-out;
animation: healthChange 0.5s ease-in-out;
}
@keyframes scorePopup {
0% { transform: scale(0) translateY(0); opacity: 1; }
50% { transform: scale(1.2) translateY(-20px); opacity: 1; }
100% { transform: scale(1) translateY(-40px); opacity: 0; }
0% { transform: scale(0) translateY(0); opacity: 1; }
50% { transform: scale(1.2) translateY(-20px); opacity: 1; }
100% { transform: scale(1) translateY(-40px); opacity: 0; }
}
@keyframes healthChange {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.2); }
0%, 100% { transform: scale(1); }
50% { transform: scale(1.2); }
}
/* Menu transitions */
.menu-enter {
animation: menuEnter 0.3s ease-out forwards;
animation: menuEnter 0.3s ease-out forwards;
}
.menu-exit {
animation: menuExit 0.3s ease-in forwards;
animation: menuExit 0.3s ease-in forwards;
}
@keyframes menuEnter {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
@keyframes menuExit {
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(1.1); }
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(1.1); }
}
/* Custom cursor */
.game-cursor {
width: 24px;
height: 24px;
pointer-events: none;
position: fixed;
z-index: 9999;
mix-blend-mode: difference;
transition: transform 0.1s ease;
width: 24px;
height: 24px;
pointer-events: none;
position: fixed;
z-index: 9999;
mix-blend-mode: difference;
transition: transform 0.1s ease;
}
/* Responsive adjustments */
@media (max-width: 640px) {
.game-hud {
font-size: 0.875rem;
}
.game-card {
padding: 1rem;
}
.game-hud {
font-size: 0.875rem;
}
.game-card {
padding: 1rem;
}
}
/* Accessibility */
@media (prefers-reduced-motion: reduce) {
.player-idle,
.player-move,
.enemy-patrol,
.collectible,
.powerup-active {
animation: none;
}
}
.player-idle,
.player-move,
.enemy-patrol,
.collectible,
.powerup-active {
animation: none;
}
}

View file

@ -1,77 +1,65 @@
/* Page Container */
/* Page Container */
.page-container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
min-height: calc(100vh - 4rem);
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
min-height: calc(100vh - 4rem);
}
/* Header Card */
.header-card {
margin-bottom: 2rem;
text-align: center;
background: var(--gradient-primary);
margin-bottom: 2rem;
text-align: center;
background: var(--gradient-primary);
}
.header-card h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
font-size: 2.5rem;
margin-bottom: 1rem;
}
/* Content Grid */
.content-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
/* Interest List */
.interest-list {
list-style: none;
padding: 0;
margin: 1rem 0;
list-style: none;
padding: 0;
margin: 1rem 0;
}
.interest-list li {
padding: 0.5rem 0;
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0;
display: flex;
align-items: center;
gap: 0.5rem;
}
.interest-list li::before {
content: "🦊";
margin-right: 0.5rem;
content: "🦊";
margin-right: 0.5rem;
}
/* Project Demo */
.project-demo {
margin-top: 1rem;
border-radius: var(--border-radius-lg);
overflow: hidden;
margin-top: 1rem;
border-radius: var(--border-radius-lg);
overflow: hidden;
}
/* Responsive Design */
@media (max-width: 768px) {
.page-container {
padding: 1rem;
}
.header-card h1 {
font-size: 2rem;
}
.content-grid {
grid-template-columns: 1fr;
}
.page-container {
padding: 1rem;
}
.header-card h1 {
font-size: 2rem;
}
.content-grid {
grid-template-columns: 1fr;
}
}
/* Animation Classes */
.fade-in {
animation: fadeIn 0.5s ease-in;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}

View file

@ -1,52 +1,45 @@
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow-x: hidden;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
height: 100%;
overflow-x: hidden;
font-family: Arial, sans-serif;
}
.parallax-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
perspective: 2px; /* Creates the parallax effect */
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
perspective: 2px; /* Creates the parallax effect */
}
.parallax-layer {
position: absolute;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
transform: translateZ(0);
z-index: -1;
position: absolute;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
transform: translateZ(0);
z-index: -1;
}
.layer-1 {
background-image: url('https://source.unsplash.com/1600x900/?nature');
transform: translateZ(-1px) scale(1.5);
background-image: url('https://source.unsplash.com/1600x900/?nature');
transform: translateZ(-1px) scale(1.5);
}
.layer-2 {
background-image: url('https://source.unsplash.com/1600x900/?forest');
transform: translateZ(-0.5px) scale(1.2);
background-image: url('https://source.unsplash.com/1600x900/?forest');
transform: translateZ(-0.5px) scale(1.2);
}
.content-layer {
position: relative;
z-index: 1;
text-align: center;
color: white;
font-size: 2rem;
padding-top: 40vh;
position: relative;
z-index: 1;
text-align: center;
color: white;
font-size: 2rem;
padding-top: 40vh;
}
.parallax-text {
background: rgba(0, 0, 0, 0.5);
padding: 1rem 2rem;
display: inline-block;
border-radius: 8px;
background: rgba(0, 0, 0, 0.5);
padding: 1rem 2rem;
display: inline-block;
border-radius: 8px;
}

View file

@ -1,22 +1,20 @@
/* Base theme colors */
/* Base theme colors */
:root {
/* Main colors */
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
/* Fox theme accents */
--fox-pink: #ffc6e5;
--fox-pink-glow: #ffadd6;
--fox-orange: #ff9466;
--fox-white: #fff5f9;
/* Gradients */
--gradient-primary: linear-gradient(135deg, var(--background-primary) 0%, var(--background-secondary) 100%);
--gradient-card: linear-gradient(135deg, rgba(47, 28, 84, 0.3) 0%, rgba(157, 78, 221, 0.1) 100%);
--gradient-hover: linear-gradient(135deg, rgba(157, 78, 221, 0.2) 0%, rgba(178, 73, 248, 0.1) 100%);
/* Main colors */
--background-primary: #1a0b2e;
--background-secondary: #2f1c54;
--accent-primary: #9d4edd;
--accent-neon: #b249f8;
--text-glow: #e0aaff;
--text-primary: #ffffff;
--dark-accent: #240046;
/* Fox theme accents */
--fox-pink: #ffc6e5;
--fox-pink-glow: #ffadd6;
--fox-orange: #ff9466;
--fox-white: #fff5f9;
/* Gradients */
--gradient-primary: linear-gradient(135deg, var(--background-primary) 0%, var(--background-secondary) 100%);
--gradient-card: linear-gradient(135deg, rgba(47, 28, 84, 0.3) 0%, rgba(157, 78, 221, 0.1) 100%);
--gradient-hover: linear-gradient(135deg, rgba(157, 78, 221, 0.2) 0%, rgba(178, 73, 248, 0.1) 100%);
}

View file

@ -1,27 +1,13 @@
@layer utilities {
.animated-bg {
@apply relative bg-gradient-primary overflow-hidden;
}
.animated-bg::before {
content: '';
@apply absolute inset-0 bg-gradient-primary opacity-50;
animation: gradientShift 15s ease infinite;
}
.fox-ear {
@apply absolute w-8 h-8 bg-fox-pink opacity-10 transition-opacity;
}
.fox-ear-left {
@apply -top-4 -left-4 transform rotate-45 rounded-bl-xl;
}
.fox-ear-right {
@apply -top-4 -right-4 transform -rotate-45 rounded-br-xl;
}
.fox-card:hover .fox-ear {
@apply opacity-20;
}
.animated-bg {
@apply
overflow-hidden; } { content: ''
.animated-bg::before
relative
bg-gradient-primary .animated-bg::before;
@apply
inset-0 opacity-50; animation: gradientShift 15s ease infinite
absolute
bg-gradient-primary;
}
.fox-ear {

View file

@ -1,26 +1,40 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"types": ["@cloudflare/workers-types"]
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
},
"types": [
"@cloudflare/workers-types"
]
},
"include": [
"src"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}