From 2b94024bc14fe0f8291fa139fa56d1c3988cde3d Mon Sep 17 00:00:00 2001 From: Unknown <53575465+EndofTimee@users.noreply.github.com> Date: Fri, 31 Jan 2025 18:21:23 -0700 Subject: [PATCH] . --- .npmrc | 7 + package.json | 31 ++-- public/index.html | 2 +- public/pages/navbar.html | 6 +- public/pages/style.css | 229 +++++++++++----------------- public/rolling-effects.css | 23 --- src/App.css | 165 +++++++++++++++++--- src/App.js | 136 +++++++++++++---- src/components/ErrorBoundary.js | 46 ++++++ src/components/FoxCar.js | 14 ++ src/components/FoxCard.js | 14 ++ src/components/GithubRepos.test.js | 9 -- src/components/SpotifyVisualizer.js | 59 +++++++ src/styles/FoxCard.css | 35 +++++ src/styles/LoadingAnimation.css | 79 +++++----- src/styles/LoadingFox.css | 49 ++++++ src/styles/cursor.css | 15 ++ src/styles/cursor/default.svg | 3 + src/styles/cursor/paw.svg | 4 + src/styles/theme.css | 22 +++ wrangler.toml | 15 +- 21 files changed, 666 insertions(+), 297 deletions(-) create mode 100644 .npmrc delete mode 100644 public/rolling-effects.css create mode 100644 src/components/ErrorBoundary.js create mode 100644 src/components/FoxCar.js create mode 100644 src/components/FoxCard.js delete mode 100644 src/components/GithubRepos.test.js create mode 100644 src/components/SpotifyVisualizer.js create mode 100644 src/styles/FoxCard.css create mode 100644 src/styles/LoadingFox.css create mode 100644 src/styles/cursor.css create mode 100644 src/styles/cursor/default.svg create mode 100644 src/styles/cursor/paw.svg create mode 100644 src/styles/theme.css diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..1e7e1ce --- /dev/null +++ b/.npmrc @@ -0,0 +1,7 @@ +legacy-peer-deps=true +strict-peer-dependencies=false +auto-install-peers=true +resolution-mode=highest +prefer-dedupe=true +package-lock=true +save-exact=true \ No newline at end of file diff --git a/package.json b/package.json index 6400b7b..275f214 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,11 @@ "lru-cache": "^10.1.0" }, "devDependencies": { - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@types/react": "^18.2.48", + "@types/react-dom": "^18.2.18", + "@types/node": "^16.18.70", "@cloudflare/workers-types": "^4.20240208.0", + "typescript": "^4.9.5", "wrangler": "^3.28.0" }, "scripts": { @@ -23,26 +26,20 @@ "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", - "deploy": "powershell ./deploy-master.ps1" + "deploy": "powershell ./deploy-master.ps1", + "clean": "rm -rf node_modules package-lock.json build dist .cache" }, "eslintConfig": { "extends": [ "react-app" ] }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "overrides": { - "inflight": "npm:lru-cache@^10.1.0" - } + "browserslist": [ + ">0.2%", + "not dead", + "not op_mini all", + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] } \ No newline at end of file diff --git a/public/index.html b/public/index.html index c3611aa..0e14433 100644 --- a/public/index.html +++ b/public/index.html @@ -3,7 +3,7 @@ - My Project Website + EndofTimee diff --git a/public/pages/navbar.html b/public/pages/navbar.html index 97a5c94..73c68da 100644 --- a/public/pages/navbar.html +++ b/public/pages/navbar.html @@ -1,8 +1,10 @@ diff --git a/public/pages/style.css b/public/pages/style.css index 2a68944..bcde467 100644 --- a/public/pages/style.css +++ b/public/pages/style.css @@ -1,165 +1,106 @@ -/* General reset */ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: Arial, sans-serif; - display: flex; - flex-direction: column; - min-height: 100vh; -} - +/* public/pages/style.css */ :root { - --background-color-light: #f9f9f9; - --text-color-light: #333; - --background-color-dark: #1e1e1e; - --text-color-dark: #e0e0e0; - --primary-color: #4a90e2; - --accent-color: #ff5722; -} - -[data-theme="light"] { - --background-color: var(--background-color-light); - --text-color: var(--text-color-light); -} - -[data-theme="dark"] { - --background-color: var(--background-color-dark); - --text-color: var(--text-color-dark); + --background-primary: #1a0b2e; + --background-secondary: #2f1c54; + --accent-primary: #9d4edd; + --accent-neon: #b249f8; + --text-glow: #e0aaff; + --text-primary: #ffffff; + --dark-accent: #240046; } body { - background-color: var(--background-color); - color: var(--text-color); + 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; } -/* Navbar styling */ +/* 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-color: var(--primary-color); - display: flex; - justify-content: center; - align-items: center; - padding: 10px; + background: rgba(36, 0, 70, 0.8); + backdrop-filter: blur(10px); + padding: 1rem; } nav ul { - list-style: none; - display: flex; - gap: 15px; + display: flex; + gap: 2rem; + justify-content: center; + list-style: none; } -nav ul li a { - color: white; - text-decoration: none; - font-weight: bold; +nav a { + font-weight: 500; + letter-spacing: 0.5px; } -/* Theme toggle button */ -.theme-toggle { - background: none; - border: none; - font-size: 1.5em; - cursor: pointer; - color: white; - margin-left: auto; +nav a:hover { + color: var(--accent-neon); + text-shadow: 0 0 10px var(--text-glow); } -/* Header styling */ -.header { - text-align: center; - padding: 20px; +/* Content sections */ +.content-section { + padding: 2rem; + margin: 2rem 0; + background: rgba(26, 11, 46, 0.5); + border-radius: 16px; } -.header-content { - max-width: 800px; - margin: 0 auto; +/* Animated gradient background */ +@keyframes gradientAnimation { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } } -.apcsp-blurb { - margin-top: 10px; - font-size: 1rem; - line-height: 1.5; -} - -/* Main content styling */ -.main-content { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - flex-grow: 1; - padding: 20px; -} - -.section-title { - margin-bottom: 20px; -} - -.project-demo { - text-align: center; -} - -.project-demo iframe { - border: none; - margin-bottom: 10px; -} - -/* Light/Dark Mode Toggle */ -[data-theme="dark"] body { - background-color: var(--background-color-dark); - color: var(--text-color-dark); -} - -[data-theme="light"] body { - background-color: var(--background-color-light); - color: var(--text-color-light); -} - -/* responsive design */ -@media (max-width: 768px) { - nav ul { - flex-direction: column; - } - - .main-content { padding: 10px; } -} - -/* Loading animation */ -#loading { - position: fixed; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.8); - display: flex; - justify-content: center; - align-items: center; - z-index: 9999; -} - -#loading .spinner { - border: 8px solid #f3f3f3; - border-top: 8px solid var(--primary-color); - border-radius: 50%; - width: 60px; - height: 60px; - animation: spin 1s linear infinite; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - -#spotify-list { - position:fixed; - right: 0; - top: 50%; - transform: translateY(-50%); - width: 200px; - background: rgba(255, 255, 255, 0.9); - padding: 10px; - box-sizing: 0 0 10px rgba(0, 0, 0, 0.1); +.animated-bg { + background: linear-gradient(135deg, + var(--background-primary), + var(--background-secondary), + var(--dark-accent)); + background-size: 200% 200%; + animation: gradientAnimation 15s ease infinite; } \ No newline at end of file diff --git a/public/rolling-effects.css b/public/rolling-effects.css deleted file mode 100644 index 287224a..0000000 --- a/public/rolling-effects.css +++ /dev/null @@ -1,23 +0,0 @@ - -@keyframes rollingCode { - 0% { transform: translateY(0); opacity: 1; } - 100% { transform: translateY(100vh); opacity: 0; } -} - -body { - margin: 0; - overflow: hidden; - background: black; - color: limegreen; - font-family: monospace; - font-size: 1rem; -} - -.code-line { - position: absolute; - top: -10%; - width: 100%; - white-space: nowrap; - overflow: hidden; - animation: rollingCode 5s linear infinite; -} diff --git a/src/App.css b/src/App.css index 8871b1b..038016c 100644 --- a/src/App.css +++ b/src/App.css @@ -1,41 +1,158 @@ -.App { - text-align: center; +/* 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; } -.App-logo { - height: 40vmin; +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: var(--background-primary); +} + +::-webkit-scrollbar-thumb { + background: var(--accent-primary); + border-radius: 5px; +} + +::-webkit-scrollbar-thumb:hover { + 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; - background-image: url('/logo.png'); - background-size: contain; - background-repeat: no-repeat; + z-index: 1; } -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; +.particle { + 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; } } -.App-header { - background-color: #282c34; +/* Main Layout */ +.app-container { min-height: 100vh; - display: flex; - flex-direction: column; + 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; +} + +.header h1 { + font-size: 3.5rem; + margin-bottom: 1rem; +} + +.subtitle { + 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; +} + +/* Interests Grid */ +.interests-grid { + 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; +} + +.interest-card:hover { + 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; - justify-content: center; - font-size: calc(10px + 2vmin); + gap: 0.5rem; + background: #9146ff; color: white; + padding: 0.75rem 1.5rem; + border-radius: 8px; + transition: all 0.3s ease; } -.App-link { - color: #61dafb; +.twitch-button:hover { + background: #7c2bff; + transform: translateY(-2px); + box-shadow: 0 0 15px rgba(145, 70, 255, 0.5); } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); +/* Responsive Design */ +@media (max-width: 768px) { + .header h1 { + font-size: 2.5rem; } - to { - transform: rotate(360deg); + + .content-section { + padding: 1rem; + margin: 1rem; } -} + + .interests-grid { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index d2f5ad9..afbffde 100644 --- a/src/App.js +++ b/src/App.js @@ -1,42 +1,112 @@ -import React, { useEffect } from 'react'; -import './styles/rolling-effects.css'; // Fixed import path -import './App.css'; +import React, { useEffect, useState } from 'react'; +import './styles/App.css'; +import SpotifyList from './components/SpotifyList'; +import LoadingAnimation from './components/LoadingAnimation'; +import GithubRepos from './components/GithubRepos'; +import { Music, Code, Twitch, Github, Cpu, Shield } from 'lucide-react'; const App = () => { - useEffect(() => { - // Generate rolling code lines - const container = document.querySelector('.rolling-code-container'); - if (container) { - for (let i = 0; i < 30; i++) { - const line = document.createElement('div'); - line.className = 'code-line'; - line.style.animationDelay = `${Math.random() * 5}s`; - line.textContent = Math.random().toString(36).substr(2, 80); - container.appendChild(line); - } - } + const [age, setAge] = useState(0); - // Generate particles - const particleContainer = document.querySelector('.particle-container'); - if (particleContainer) { - for (let i = 0; i < 50; i++) { - const particle = document.createElement('div'); - particle.className = 'particle'; - particle.style.left = `${Math.random() * 100}vw`; - particle.style.animationDelay = `${Math.random() * 10}s`; - particleContainer.appendChild(particle); + useEffect(() => { + // Age calculation + const calculateAge = () => { + const birthDate = new Date('2009-05-15'); + const today = new Date(); + let age = today.getFullYear() - birthDate.getFullYear(); + const monthDiff = today.getMonth() - birthDate.getMonth(); + + if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) { + age--; } - } - }, []); + return age; + }; + setAge(calculateAge()); + + // Particle effect setup + const createParticles = () => { + const particleContainer = document.querySelector('.particle-container'); + if (particleContainer) { + for (let i = 0; i < 50; i++) { + const particle = document.createElement('div'); + particle.className = 'particle'; + particle.style.left = `${Math.random() * 100}vw`; + particle.style.animationDuration = `${Math.random() * 3 + 2}s`; + particle.style.animationDelay = `${Math.random() * 2}s`; + particleContainer.appendChild(particle); + } + } + }; + + createParticles(); + }, []); + + const interests = [ + { icon: , title: 'Programming', description: 'Full-stack development & coding projects' }, + { icon: , title: 'Robotics', description: 'Building & programming robots' }, + { icon: , title: 'Cybersecurity', description: 'Network security & ethical hacking' }, + { icon: , title: 'Music', description: 'Music production & listening' }, + { icon: , title: 'Streaming', description: 'FiveM & variety gaming on Twitch' }, + { icon: , title: 'Open Source', description: 'Contributing to GitHub projects' } + ]; return ( -
-
-
-
-
-

Welcome to My Website

-

Enhanced Background with Lighting Effects

+
+
+ + {/* Header Section */} +
+

EndofTimee

+

Programmer • Streamer • Foxgirl 🦊

+
+ + {/* About Section */} +
+

About Me

+
+

Hey there! I'm a {age}-year-old transfem programmer and content creator. + When I'm not coding or building robots, you can find me streaming on + Twitch!

+
+
+ + {/* Interests Grid */} +
+

What I Do

+
+ {interests.map((interest, index) => ( +
+
{interest.icon}
+

{interest.title}

+

{interest.description}

+
+ ))} +
+
+ + {/* Streaming Section */} +
+

Streaming

+
+

Join me on Twitch for FiveM roleplay and various other games! + I love interacting with chat and building a positive community.

+ + + Watch Live + +
+
+ + {/* GitHub Section */} +
+ +
+ + {/* Music Section */} +
+
); diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.js new file mode 100644 index 0000000..c4beb87 --- /dev/null +++ b/src/components/ErrorBoundary.js @@ -0,0 +1,46 @@ +import React from 'react'; + +class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error) { + return { hasError: true, error }; + } + + componentDidCatch(error, errorInfo) { + console.error('Error caught by boundary:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+

Oops! Something went wrong

+ +
+
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/components/FoxCar.js b/src/components/FoxCar.js new file mode 100644 index 0000000..5c4557c --- /dev/null +++ b/src/components/FoxCar.js @@ -0,0 +1,14 @@ +import React from 'react'; +import '../styles/FoxCard.css'; + +const FoxCard = ({ children, className = '' }) => { + return ( +
+
+
+ {children} +
+ ); +}; + +export default FoxCard; \ No newline at end of file diff --git a/src/components/FoxCard.js b/src/components/FoxCard.js new file mode 100644 index 0000000..20d6636 --- /dev/null +++ b/src/components/FoxCard.js @@ -0,0 +1,14 @@ +import React from 'react'; +import '../styles/FoxCard.css'; + +const FoxCard = ({ children, className = '' }) => { + return ( +
+
+
+ {children} +
+ ); +}; + +export default FoxCard; diff --git a/src/components/GithubRepos.test.js b/src/components/GithubRepos.test.js deleted file mode 100644 index 9bd645c..0000000 --- a/src/components/GithubRepos.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import GithubRepos from './GithubRepos'; - -test('renders GithubRepos component', () => { - render(); - const linkElement = screen.getByText(/Github Repositories/i); - expect(linkElement).toBeInTheDocument(); -}); \ No newline at end of file diff --git a/src/components/SpotifyVisualizer.js b/src/components/SpotifyVisualizer.js new file mode 100644 index 0000000..cd2998e --- /dev/null +++ b/src/components/SpotifyVisualizer.js @@ -0,0 +1,59 @@ +import React, { useEffect, useRef } from 'react'; +import '../styles/SpotifyVisualizer.css'; + +const SpotifyVisualizer = ({ isPlaying }) => { + const canvasRef = useRef(null); + const animationRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + const ctx = canvas.getContext('2d'); + const bars = 50; + const barWidth = canvas.width / bars; + + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + for (let i = 0; i < bars; i++) { + const height = isPlaying ? + Math.random() * canvas.height * 0.8 : + canvas.height * 0.1; + + const gradient = ctx.createLinearGradient(0, canvas.height, 0, canvas.height - height); + gradient.addColorStop(0, '#9d4edd'); + gradient.addColorStop(1, '#b249f8'); + + ctx.fillStyle = gradient; + ctx.fillRect( + i * barWidth, + canvas.height - height, + barWidth - 2, + height + ); + } + + animationRef.current = requestAnimationFrame(animate); + }; + + animate(); + + return () => { + if (animationRef.current) { + cancelAnimationFrame(animationRef.current); + } + }; + }, [isPlaying]); + + return ( +
+ +
+ ); +}; + +export default SpotifyVisualizer; diff --git a/src/styles/FoxCard.css b/src/styles/FoxCard.css new file mode 100644 index 0000000..7a46907 --- /dev/null +++ b/src/styles/FoxCard.css @@ -0,0 +1,35 @@ +.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; +} + +.fox-ear-left { + 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; +} + +.fox-card:hover .fox-ear { + opacity: 0.2; +} diff --git a/src/styles/LoadingAnimation.css b/src/styles/LoadingAnimation.css index c7fb598..a494e45 100644 --- a/src/styles/LoadingAnimation.css +++ b/src/styles/LoadingAnimation.css @@ -1,62 +1,57 @@ +/* src/styles/LoadingAnimation.css */ .loading-container { position: fixed; width: 100%; height: 100%; - background: rgba(0, 0, 0, 0.8); + background: linear-gradient(135deg, rgba(26, 11, 46, 0.9), rgba(47, 28, 84, 0.9)); + backdrop-filter: blur(10px); display: flex; justify-content: center; align-items: center; z-index: 9999; } -.loading-background { +.loading-spinner { + width: 80px; + height: 80px; + border: 4px solid rgba(157, 78, 221, 0.1); + border-left: 4px solid #9d4edd; + border-radius: 50%; + animation: spin 1s linear infinite; + position: relative; +} + +.loading-spinner::after { + content: ''; position: absolute; width: 100%; height: 100%; - overflow: hidden; - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - opacity: 0.2; - z-index: -1; + border-radius: 50%; + border: 4px solid transparent; + border-left: 4px solid #b249f8; + animation: spin 0.5s linear infinite reverse; } -.code-char { - color: #00ff00; - font-family: 'Courier New', Courier, monospace; - font-size: 14px; - animation: scroll 10s linear infinite; +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } } -.code-char:hover { - background-color: rgba(255, 255, 255, 0.1); +.loading-text { + position: absolute; + margin-top: 100px; + color: #ffffff; + font-size: 1.2rem; + text-transform: uppercase; + letter-spacing: 2px; + animation: glow 1.5s ease-in-out infinite alternate; } -@keyframes scroll { - 0% { transform: translateY(100%); } - 100% { transform: translateY(-100%); } -} - -.loading-blocks { - display: flex; - gap: 10px; -} - -.block { - width: 20px; - height: 20px; - background-color: var(--primary-color); - animation: block-loading 1s infinite; -} - -.block:nth-child(1) { animation-delay: 0s; } -.block:nth-child(2) { animation-delay: 0.2s; } -.block:nth-child(3) { animation-delay: 0.4s; } -.block:nth-child(4) { animation-delay: 0.6s; } -.block:nth-child(5) { animation-delay: 0.8s; } - -@keyframes block-loading { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.5); } +@keyframes glow { + from { + text-shadow: 0 0 5px #e0aaff, 0 0 10px #e0aaff, 0 0 15px #b249f8; + } + to { + text-shadow: 0 0 10px #e0aaff, 0 0 20px #e0aaff, 0 0 30px #b249f8; + } } \ No newline at end of file diff --git a/src/styles/LoadingFox.css b/src/styles/LoadingFox.css new file mode 100644 index 0000000..be01354 --- /dev/null +++ b/src/styles/LoadingFox.css @@ -0,0 +1,49 @@ +.loading-fox-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 200px; +} + +.fox-loader { + 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; +} + +.fox-ears { + position: absolute; + top: -15px; + width: 100%; + display: flex; + justify-content: space-between; +} + +.ear { + width: 20px; + height: 20px; + background: var(--fox-orange); + border-radius: 5px; +} + +.ear.left { + transform: rotate(-30deg); +} + +.ear.right { + transform: rotate(30deg); +} + +@keyframes bounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-10px); } +} diff --git a/src/styles/cursor.css b/src/styles/cursor.css new file mode 100644 index 0000000..7c649b0 --- /dev/null +++ b/src/styles/cursor.css @@ -0,0 +1,15 @@ +/* Base cursor */ +* { + cursor: url("cursor/default.svg") 16 16, auto; +} + +/* Clickable elements cursor */ +a, button, [role="button"], input[type="submit"], +input[type="button"], select { + cursor: url("cursor/paw.svg") 16 16, pointer; +} + +/* Loading cursor */ +.loading { + cursor: url("cursor/tail-loading.svg") 16 16, progress; +} diff --git a/src/styles/cursor/default.svg b/src/styles/cursor/default.svg new file mode 100644 index 0000000..9141aa7 --- /dev/null +++ b/src/styles/cursor/default.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/cursor/paw.svg b/src/styles/cursor/paw.svg new file mode 100644 index 0000000..078b942 --- /dev/null +++ b/src/styles/cursor/paw.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/styles/theme.css b/src/styles/theme.css new file mode 100644 index 0000000..1280968 --- /dev/null +++ b/src/styles/theme.css @@ -0,0 +1,22 @@ +/* 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%); +} diff --git a/wrangler.toml b/wrangler.toml index 1032210..b267b9f 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -4,15 +4,26 @@ compatibility_date = "2024-01-30" [build] command = "npm run build" -watch_dir = "build" +cwd = "." +watch_dir = "src" [site] bucket = "./build" +# Environment-specific configurations [env.production] name = "personal-site" vars = { ENVIRONMENT = "production" } +routes = ["personal-site.pages.dev/*"] [env.development] name = "personal-site-dev" -vars = { ENVIRONMENT = "development" } \ No newline at end of file +vars = { ENVIRONMENT = "development" } + +[[rules]] +type = "CompiledWasm" +globs = ["**/*.wasm"] + +[[rules]] +type = "Text" +globs = ["**/*.html", "**/*.css", "**/*.js", "**/*.json"] \ No newline at end of file