-
Welcome to My Website
-
Enhanced Background with Lighting Effects
+
+
+
+ {/* Header Section */}
+
+
+ {/* 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
+
window.location.reload()}>
+ Try Again
+
+
+
+ );
+ }
+
+ 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 (
+
+ );
+};
+
+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 (
+
+ );
+};
+
+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