+
-
+
-
+
+
+
+
+
+
+
+
+ Advancing Free Software Development
+
- Our game level and asset designer. He is responsible for all
- assets in our FreeFTF game. So if an asset looks ugly be mad at
- him. Also, we are not sure if he is human or just a drunk wizard
- cat but one thing is very clear he is still a novice at his job.
+ We develop high-quality free and open source software solutions,
+ with a focus on gaming and applications that respect user freedom.
-
+
+
-
-
- About Us
-
- Welcome to Interstellar Development! We are a small, passionate
- international team dedicated to transforming the programming world
- into a free-and-open-source future. Our diverse backgrounds and
- experiences fuel our commitment to creating free and open-source
- software, particularly in the realm of gaming.
-
-
- Our journey began with a shared vision: to better organize our efforts
- in making free and open-source games more efficient and accessible. We
- recognized that many current free software games are either lacking in
- quality or simply do not exist. This realization inspired us to focus
- on developing games that are unplayable on GNU/Linux and FreeBSD
- systems, as well as creating free software alternatives for those in
- need.
-
-
- At Interstellar Development, we believe that true freedom for computer
- users can only be achieved through the use of free software. That’s
- why we are committed to licensing all of our projects under copyleft
- free and open-source software licenses, ensuring that our games remain
- free for everyone to enjoy, forever.
-
-
- While we are not currently accepting donations, we welcome your
- support in the form of feedback and suggestions for improvements. If
- you wish to contribute financially, we encourage you to donate to the
- Free Software Foundation, as without them, we would have never started
- this.
-
-
- Join us as we strive to create a vibrant community around free
- software and gaming. Together, we can make a difference and pave the
- way for a free future!
-
+
+
+
+
+
+
+
+
+ All
+ Gaming
+
+ Software
+
+ Web
+
+
+
+
+
+
+
+
+
-
- Our Vision
- Interstellar Development: Free Software is Our Passion
-
- At Interstellar Development, we embarked on this journey to create a
- more organized and efficient approach to developing free and
- open-source software, with a particular focus on gaming. We recognized
- a significant gap in the availability and quality of free software
- games, which often fail to meet the expectations of users or simply do
- not exist. Our mission is to fill this void and elevate the standards
- of free gaming experiences.
-
-
- Our primary goal is to target games that are currently unplayable on
- GNU/Linux and FreeBSD systems. We aim to develop high-quality
- alternatives that not only provide enjoyable gameplay but also adhere
- to the principles of free software. Additionally, we are committed to
- identifying and addressing other areas within the software ecosystem
- that lack free alternatives, ensuring that users have access to a
- diverse range of tools and applications that respect their freedom.
-
-
- At Interstellar Development, we firmly believe that the path to true
- freedom for computer users lies in the adoption and promotion of free
- software. To this end, we are dedicated to licensing all of our
- projects under copyleft free and open-source software licenses. This
- commitment ensures that our games and software remain free for
- everyone to play, modify, and share, fostering a culture of
- collaboration and innovation within the community.
-
-
- We understand that community involvement is crucial to our success.
- While we are not currently accepting donations, we invite you to
- support us by providing feedback, reporting issues, and suggesting
- improvements. Your insights are invaluable in helping us refine our
- projects and enhance the user experience.
-
-
- If you feel compelled to contribute financially, we encourage you to
- consider donating to the Free Software Foundation. Their unwavering
- support and advocacy for free software principles have been
- instrumental in our journey, and your contributions to them help
- sustain the broader movement that enables us to create these games.
-
-
- Together, we can build a vibrant community around free software and
- gaming, paving the way for a future where everyone has access to
- high-quality, open-source alternatives. Join us in our mission to make
- a difference and champion the cause of free software for all!
-
-
-
+
+
+
+
-
-
+
+
+
+
+
+
Patrick
+
+ Lead Programmer & System Administrator
+
+
+ Patrick focuses on backend development and system
+ administration, managing our infrastructure and core application
+ logic with expertise in server-side technologies and DevOps.
+
+
+
+
+
+
+
+
Sage
+
Frontend Developer & Communications
+
+ Sage focuses on frontend development and is in charge of
+ communication and UI/UX design, ensuring our projects have
+ intuitive interfaces and excellent user experiences.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Interstellar Development is a small international team dedicated
+ to advancing free and open source software. Our diverse
+ backgrounds and shared commitment to user freedom drive our
+ development philosophy.
+
+
+
+ We began with a vision to create high-quality free software,
+ particularly in gaming where such options are often limited. We
+ recognized that many free software games either lack polish or
+ simply don't exist, inspiring us to focus on this under-served
+ area.
+
+
+
+ At Interstellar Development, we believe true digital freedom can
+ only be achieved through free software. All our projects are
+ released under copyleft licenses, ensuring they remain free for
+ everyone to use, modify, and distribute.
+
+
+
+ While we don't currently accept donations, we welcome feedback and
+ suggestions. If you wish to support the free software movement, we
+ encourage donations to the Free Software Foundation, whose work
+ continues to inspire our journey.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Our mission is to create high-quality free software
+ alternatives, particularly for games that are unavailable on
+ free operating systems like GNU/Linux and FreeBSD. We aim to
+ address gaps in the software ecosystem where free alternatives
+ are lacking.
+
+
+
+
+
+
+
+
+
Software Freedom
+
+ All our projects are released under copyleft licenses to
+ ensure user freedoms are protected and preserved.
+
+
+
+
+
+
+
+
Community Collaboration
+
+ We believe in building software with and for the community,
+ welcoming contributions and feedback.
+
+
+
+
+
+
+
+
Quality Standards
+
+ We strive to create software that matches or exceeds the
+ quality of proprietary alternatives.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/secret/asteroidDestroyer/explenation.html b/secret/asteroidDestroyer/explenation.html
deleted file mode 100644
index 843c32c..0000000
--- a/secret/asteroidDestroyer/explenation.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
Game Landing Page
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Welcome to the Asteroid Game!
-
- In this game, you control a spaceship that shoots at asteroids to
- avoid destruction and collect items for power-ups.
-
-
Your goal is to survive as long as possible while scoring points!
-
Play Game
-
-
-
-
-
-
diff --git a/secret/asteroidDestroyer/game.js b/secret/asteroidDestroyer/game.js
deleted file mode 100644
index 2ea6461..0000000
--- a/secret/asteroidDestroyer/game.js
+++ /dev/null
@@ -1,414 +0,0 @@
-"use strict";
-// Canvas setup
-const canvas = document.getElementById("gameCanvas");
-const ctx = canvas.getContext("2d");
-const targetFPS = 60;
-const targetFrameTime = 1000 / targetFPS;
-canvas.width = window.innerWidth;
-canvas.height = window.innerHeight;
-
-let lastFrameTime = performance.now();
-
-// Game elements
-const player = {
- x: canvas.width / 2,
- y: canvas.height - 60,
- width: 40,
- height: 40,
- color: "white",
- speed: 5,
- dx: 0,
-};
-
-let bullets = [];
-let asteroids = [];
-let items = [];
-let score = 0;
-let totalBulletsFired = 0;
-let isGameOver = false;
-let lastBulletTime = 0;
-let ammo = 100; // Ammo counter
-
-// Difficulty control
-let asteroidSpawnInterval = 800; // Faster spawn rate
-let asteroidSpeedMultiplier = 1.5; // Faster asteroids from the start
-let difficultyIncreaseRate = 0.2; // Faster scaling every 10 seconds
-
-// Controls
-let canShoot = true; // Flag to control shooting
-let rapidFireActive = false;
-let shotgunActive = false;
-let rainbowActive = false;
-let lastShotgunTime = 0;
-
-// Controls for sphere effects
-let blueSphereCooldown = 0;
-let yellowSphereCooldown = 0;
-let greenSphereCooldown = 0;
-let rainbowSphereCooldown = 0;
-
-// Sphere types
-const sphereTypes = ["blue", "yellow", "green", "rainbow"];
-
-/// Control for left button press and release
-function btnMoveLeft(isPressed) {
- if (isPressed) {
- player.dx = -player.speed; // Start moving left
- } else {
- player.dx = 0; // Stop moving when button is released
- }
-}
-
-// Control for shoot button click (simulates spacebar press)
-function btnShoot() {
- if (canShoot && !isGameOver) {
- shootBullet();
- canShoot = false; // Prevent shooting until the button is "released"
- }
-}
-
-// Control for right button press and release
-function btnMoveRight(isPressed) {
- if (isPressed) {
- player.dx = player.speed; // Start moving right
- } else {
- player.dx = 0; // Stop moving when button is released
- }
-}
-
-document.getElementById("shootBtn").addEventListener("mouseup", () => {
- canShoot = true; // Allow shooting again when button is released
-});
-
-window.addEventListener("keydown", (e) => {
- if (e.key === "ArrowLeft" || e.key === "a") player.dx = -player.speed;
- if (e.key === "ArrowRight" || e.key === "d") player.dx = player.speed;
-
- // Shoot only if it's not a hold, and we can shoot
- if (e.key === " " && canShoot && !isGameOver) {
- shootBullet();
- canShoot = false; // Prevent shooting until the key is released
- }
-
- if (e.key === "r" && isGameOver) restartGame();
-});
-
-window.addEventListener("keyup", (e) => {
- // Stop moving when either the arrow keys or the 'a'/'d' keys are released
- if (
- e.key === "ArrowLeft" ||
- e.key === "ArrowRight" ||
- e.key === "a" ||
- e.key === "d"
- ) {
- player.dx = 0;
- }
-
- // Allow shooting again when the space key is released
- if (e.key === " ") {
- canShoot = true;
- }
-});
-
-// Bullet mechanics with cooldown
-function shootBullet() {
- const now = Date.now();
- if (now - lastBulletTime < 100) return; // Enforce cooldown of 0.1 seconds
- if (ammo <= 0) return; // Prevent shooting if ammo is empty
- lastBulletTime = now;
- ammo--; // Decrease ammo
-
- totalBulletsFired++; // Increment total bullets fired
-
- if (rapidFireActive) {
- // If rapid fire is active, fire bullets continuously with a short delay
- for (let i = 0; i < 3; i++) {
- setTimeout(() => {
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- });
- }, i * 50); // Fire bullets with 50ms delay between shots
- }
- } else if (shotgunActive) {
- // Shotgun effect, firing 3 bullets with a spread
- for (let i = -1; i <= 1; i++) {
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- angle: i * 10, // Spray the bullets at different angles
- });
- }
- } else {
- // Normal bullet
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- });
- }
-}
-
-// Generate random color
-function getRandomColor() {
- const colors = ["red", "blue", "green", "orange", "purple", "pink"];
- return colors[Math.floor(Math.random() * colors.length)];
-}
-
-// Asteroid mechanics
-function createAsteroid() {
- const size = Math.random() * 40 + 30; // Bigger asteroids (min: 30, max: 70)
- asteroids.push({
- x: Math.random() * canvas.width,
- y: -size,
- width: size,
- height: size,
- color: getRandomColor(),
- speed: (Math.random() * 3 + 2) * asteroidSpeedMultiplier, // Faster initial speed
- });
-}
-
-// Item mechanics
-function createItem() {
- const randomType =
- sphereTypes[Math.floor(Math.random() * sphereTypes.length)];
- const size = 30;
- const x = Math.random() * canvas.width;
- items.push({
- x: x,
- y: -size,
- width: size,
- height: size,
- type: randomType,
- color:
- randomType === "blue"
- ? "blue"
- : randomType === "yellow"
- ? "yellow"
- : randomType === "green"
- ? "green"
- : "rainbow",
- speed: 3,
- });
-}
-
-// Update game elements
-function updatePlayer() {
- player.x += player.dx;
- if (player.x < 0) player.x = 0;
- if (player.x + player.width > canvas.width)
- player.x = canvas.width - player.width;
-}
-
-function updateBullets() {
- bullets.forEach((bullet, index) => {
- bullet.y -= bullet.speed;
- if (bullet.y + bullet.height < 0) bullets.splice(index, 1);
- });
-}
-
-function updateAsteroids() {
- asteroids.forEach((asteroid, index) => {
- asteroid.y += asteroid.speed;
- if (asteroid.y > canvas.height) asteroids.splice(index, 1);
- });
-}
-
-function updateItems() {
- items.forEach((item, index) => {
- item.y += item.speed;
- if (item.y > canvas.height) items.splice(index, 1);
- // Check if player collects the item
- if (
- player.x < item.x + item.width &&
- player.x + player.width > item.x &&
- player.y < item.y + item.height &&
- player.y + player.height > item.y
- ) {
- applyItemEffect(item.type);
- items.splice(index, 1); // Remove the item after it is collected
- }
- });
-}
-
-function applyItemEffect(type) {
- let points = Math.floor(Math.random() * 5) + 1; // Random points between 1 and 5
- if (type === "blue") {
- rapidFireActive = true;
- setTimeout(() => (rapidFireActive = false), 15000); // 15 seconds of rapid fire
- } else if (type === "yellow") {
- shotgunActive = true;
- setTimeout(() => (shotgunActive = false), 30000); // 30 seconds of shotgun
- } else if (type === "green") {
- ammo = 100; // Refill ammo
- } else if (type === "rainbow") {
- rapidFireActive = true;
- shotgunActive = true;
- setTimeout(() => {
- rapidFireActive = false;
- shotgunActive = false;
- }, 15000); // 15 seconds with all effects
- }
- score += points; // Add points when an item is collected
-}
-
-// Collision detection
-function checkCollisions() {
- bullets.forEach((bullet, bIndex) => {
- asteroids.forEach((asteroid, aIndex) => {
- if (
- bullet.x < asteroid.x + asteroid.width &&
- bullet.x + bullet.width > asteroid.x &&
- bullet.y < asteroid.y + asteroid.height &&
- bullet.y + bullet.height > asteroid.y
- ) {
- bullets.splice(bIndex, 1);
- asteroids.splice(aIndex, 1);
- score += Math.floor(Math.random() * 5) + 1; // Add points when an asteroid is destroyed
- // Visual feedback for destroyed asteroid
- createExplosion(asteroid.x, asteroid.y);
- }
- });
- });
-
- asteroids.forEach((asteroid) => {
- if (
- player.x < asteroid.x + asteroid.width &&
- player.x + player.width > asteroid.x &&
- player.y < asteroid.y + asteroid.height &&
- player.y + player.height > asteroid.y
- ) {
- isGameOver = true;
- }
- });
-}
-
-// Explosion effect
-function createExplosion(x, y) {
- ctx.fillStyle = "yellow";
- ctx.beginPath();
- ctx.arc(x, y, 20, 0, Math.PI * 2);
- ctx.fill();
- setTimeout(() => ctx.clearRect(x - 20, y - 20, 40, 40), 200); // Clear explosion after 200ms
-}
-
-// Draw elements
-function drawPlayer() {
- ctx.fillStyle = player.color;
- ctx.fillRect(player.x, player.y, player.width, player.height);
-}
-
-function drawBullets() {
- bullets.forEach((bullet) => {
- ctx.fillStyle = bullet.color;
- ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
- });
-}
-
-function drawAsteroids() {
- asteroids.forEach((asteroid) => {
- ctx.fillStyle = asteroid.color;
- ctx.fillRect(asteroid.x, asteroid.y, asteroid.width, asteroid.height);
- });
-}
-
-function drawItems() {
- items.forEach((item) => {
- ctx.fillStyle = item.color;
- ctx.beginPath();
- ctx.arc(
- item.x + item.width / 2,
- item.y + item.height / 2,
- item.width / 2,
- 0,
- Math.PI * 2
- );
- ctx.fill();
- });
-}
-
-function drawScore() {
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.fillText(`Score: ${score}`, 20, 40); // Score at top-left corner
-}
-
-function drawAmmo() {
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.fillText(`Ammo: ${ammo}`, 20, 70); // Ammo at top-left corner
-}
-
-function drawGameOver() {
- if (isGameOver) {
- ctx.fillStyle = "white";
- ctx.font = "40px Arial";
- ctx.textAlign = "center";
- ctx.fillText("Game Over!", canvas.width / 2, canvas.height / 2 - 40);
- ctx.font = "24px Arial";
- ctx.fillText(`Total Score: ${score}`, canvas.width / 2, canvas.height / 2);
- ctx.fillText(
- `Bullets Fired: ${totalBulletsFired}`,
- canvas.width / 2,
- canvas.height / 2 + 40
- );
- ctx.fillText(
- 'Press "R" to Restart',
- canvas.width / 2,
- canvas.height / 2 + 80
- );
- }
-}
-
-// Restart game
-function restartGame() {
- window.location.reload();
-}
-
-// Main game loop
-function gameLoop() {
- const currentTime = performance.now();
- const elapsedTime = currentTime - lastFrameTime;
-
- if (elapsedTime >= targetFrameTime) {
- lastFrameTime = currentTime - (elapsedTime % targetFrameTime);
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- if (!isGameOver) {
- updatePlayer();
- updateBullets();
- updateAsteroids();
- updateItems();
- checkCollisions();
- }
-
- drawPlayer();
- drawBullets();
- drawAsteroids();
- drawItems();
- drawScore();
- drawAmmo();
- drawGameOver();
-
- if (!isGameOver) {
- if (Math.random() < 0.01) createAsteroid(); // 1% chance every frame to spawn an asteroid
- if (Math.random() < 0.005) createItem(); // 0.5% chance to spawn an item
- }
- }
-
- requestAnimationFrame(gameLoop);
-}
-
-// Start game loop
-requestAnimationFrame(gameLoop);
diff --git a/secret/asteroidDestroyer/secret.html b/secret/asteroidDestroyer/secret.html
deleted file mode 100644
index 1b22d19..0000000
--- a/secret/asteroidDestroyer/secret.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
Asteroid Shooter
-
-
-
-
-
-
-
-
-
-
-
- Left
-
- Shoot
-
- Right
-
-
-
-
-
diff --git a/secret/asteroidDestroyer/style.css b/secret/asteroidDestroyer/style.css
deleted file mode 100644
index e90a6ad..0000000
--- a/secret/asteroidDestroyer/style.css
+++ /dev/null
@@ -1,43 +0,0 @@
-body {
- margin: 0;
- overflow: hidden;
-}
-
-canvas {
- display: block;
- background: black;
- width: 100%;
- height: 100%;
-}
-
-.controls {
- display: none;
- position: absolute;
- bottom: 20px;
- left: 50%;
- transform: translateX(-50%);
- display: flex;
- justify-content: space-between;
- width: 80%;
-}
-
-.control-btn {
- display: none;
- padding: 10px;
- font-size: 18px;
- background-color: rgba(0, 0, 0, 0.6);
- color: white;
- border: 1px solid #fff;
- border-radius: 5px;
- cursor: pointer;
- flex-grow: 1;
- margin: 0 5px;
-}
-
-@media (max-width: 600px) {
- .control-btn {
- display: block;
- font-size: 16px;
- padding: 12px;
- }
-}
diff --git a/secret/asteroidDestroyer/styles.css b/secret/asteroidDestroyer/styles.css
deleted file mode 100644
index 7d92d64..0000000
--- a/secret/asteroidDestroyer/styles.css
+++ /dev/null
@@ -1,76 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-body,
-html {
- height: 100%;
- font-family: Arial, sans-serif;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: #000;
- color: white;
- overflow: hidden;
-}
-
-.landing-page {
- position: relative;
- width: 100%;
- height: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.game-background {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.7); /* Dark overlay */
- backdrop-filter: blur(8px); /* Apply blur effect to the background */
- z-index: -1; /* Ensures it's in the background */
- pointer-events: none; /* Prevent interaction with the blurred background */
-}
-
-.content {
- text-align: center;
- z-index: 1; /* Ensure content appears above the game background */
- padding: 20px;
- max-width: 600px; /* Limit the width of the content */
- position: relative;
- color: white;
- backdrop-filter: blur(
- 8px
- ); /* Ensure content has some blur as well for contrast */
-}
-
-h1 {
- font-size: 2rem;
- margin-bottom: 20px;
-}
-
-p {
- font-size: 1.2rem;
- margin-bottom: 30px;
-}
-
-button {
- padding: 12px 24px;
- background-color: #ffcc00;
- color: black;
- border: none;
- font-size: 18px;
- cursor: pointer;
- border-radius: 5px;
- text-transform: uppercase;
- transition: background-color 0.3s ease;
-}
-
-button:hover {
- background-color: #ff9900;
-}
diff --git a/secret/endlessRunner/index.html b/secret/endlessRunner/index.html
deleted file mode 100644
index c2feb26..0000000
--- a/secret/endlessRunner/index.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
Endless runner
-
-
-
-
-
-
-
-
- Restart
-
-
-
-
diff --git a/secret/endlessRunner/script.js b/secret/endlessRunner/script.js
deleted file mode 100644
index 59df696..0000000
--- a/secret/endlessRunner/script.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-
-export default function EndlessRunner() {
- const canvasRef = useRef(null);
- const [running, setRunning] = useState(true);
- const player = { x: 50, y: 150, width: 20, height: 20, dy: 0 };
- const gravity = 0.5;
- let obstacles = [];
- let score = 0;
-
- useEffect(() => {
- const canvas = canvasRef.current;
- const ctx = canvas.getContext("2d");
- canvas.width = window.innerWidth;
- canvas.height = 300;
-
- function update() {
- if (!running) return;
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- // Player physics
- player.dy += gravity;
- player.y += player.dy;
- if (player.y > 150) {
- player.y = 150;
- player.dy = 0;
- }
-
- // Draw player
- ctx.fillStyle = "blue";
- ctx.fillRect(player.x, player.y, player.width, player.height);
-
- // Obstacles
- if (Math.random() < 0.02) {
- obstacles.push({ x: canvas.width, y: 150, width: 20, height: 20 });
- }
- obstacles = obstacles.map((obstacle) => ({
- ...obstacle,
- x: obstacle.x - 5,
- }));
- obstacles = obstacles.filter(
- (obstacle) => obstacle.x + obstacle.width > 0
- );
-
- obstacles.forEach((obstacle) => {
- ctx.fillStyle = "red";
- ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
-
- // Collision detection
- if (
- player.x < obstacle.x + obstacle.width &&
- player.x + player.width > obstacle.x &&
- player.y < obstacle.y + obstacle.height &&
- player.y + player.height > obstacle.y
- ) {
- setRunning(false);
- }
- });
-
- // Score
- score++;
- ctx.fillStyle = "black";
- ctx.fillText("Score: " + score, 10, 20);
-
- requestAnimationFrame(update);
- }
-
- update();
- }, [running]);
-
- function jump() {
- if (player.y >= 150) {
- player.dy = -10;
- }
- }
-
- return (
-
-
- {!running && (
- window.location.reload()}
- className="mt-4 bg-blue-500 text-white px-4 py-2 rounded"
- >
- Restart
-
- )}
-
- );
-}
diff --git a/secret/endlessRunner/styles.css b/secret/endlessRunner/styles.css
deleted file mode 100644
index b8850fc..0000000
--- a/secret/endlessRunner/styles.css
+++ /dev/null
@@ -1,34 +0,0 @@
-body {
- margin: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- background-color: #f4f4f4;
-}
-
-.game-container {
- position: relative;
- text-align: center;
-}
-
-canvas {
- border: 2px solid black;
- background-color: white;
- display: block;
-}
-
-#restartBtn {
- margin-top: 10px;
- padding: 10px 20px;
- font-size: 16px;
- background-color: #007bff;
- color: white;
- border: none;
- cursor: pointer;
- display: none;
-}
-
-#restartBtn:hover {
- background-color: #0056b3;
-}
diff --git a/secret/game.js b/secret/game.js
deleted file mode 100644
index 36185f6..0000000
--- a/secret/game.js
+++ /dev/null
@@ -1,404 +0,0 @@
-"use strict";
-// Canvas setup
-const canvas = document.getElementById("gameCanvas");
-const ctx = canvas.getContext("2d");
-canvas.width = window.innerWidth;
-canvas.height = window.innerHeight;
-
-// Game elements
-const player = {
- x: canvas.width / 2,
- y: canvas.height - 60,
- width: 40,
- height: 40,
- color: "white",
- speed: 5,
- dx: 0,
-};
-
-let bullets = [];
-let asteroids = [];
-let items = [];
-let score = 0;
-let totalBulletsFired = 0;
-let isGameOver = false;
-let lastBulletTime = 0;
-let ammo = 100; // Ammo counter
-
-// Difficulty control
-let asteroidSpawnInterval = 800; // Faster spawn rate
-let asteroidSpeedMultiplier = 1.5; // Faster asteroids from the start
-let difficultyIncreaseRate = 0.2; // Faster scaling every 10 seconds
-
-// Controls
-let canShoot = true; // Flag to control shooting
-let rapidFireActive = false;
-let shotgunActive = false;
-let rainbowActive = false;
-let lastShotgunTime = 0;
-
-// Controls for sphere effects
-let blueSphereCooldown = 0;
-let yellowSphereCooldown = 0;
-let greenSphereCooldown = 0;
-let rainbowSphereCooldown = 0;
-
-// Sphere types
-const sphereTypes = ["blue", "yellow", "green", "rainbow"];
-
-/// Control for left button press and release
-function btnMoveLeft(isPressed) {
- if (isPressed) {
- player.dx = -player.speed; // Start moving left
- } else {
- player.dx = 0; // Stop moving when button is released
- }
-}
-
-// Control for shoot button click (simulates spacebar press)
-function btnShoot() {
- if (canShoot && !isGameOver) {
- shootBullet();
- canShoot = false; // Prevent shooting until the button is "released"
- }
-}
-
-// Control for right button press and release
-function btnMoveRight(isPressed) {
- if (isPressed) {
- player.dx = player.speed; // Start moving right
- } else {
- player.dx = 0; // Stop moving when button is released
- }
-}
-
-document.getElementById("shootBtn").addEventListener("mouseup", () => {
- canShoot = true; // Allow shooting again when button is released
-});
-
-window.addEventListener("keydown", (e) => {
- if (e.key === "ArrowLeft" || e.key === "a") player.dx = -player.speed;
- if (e.key === "ArrowRight" || e.key === "d") player.dx = player.speed;
-
- // Shoot only if it's not a hold, and we can shoot
- if (e.key === " " && canShoot && !isGameOver) {
- shootBullet();
- canShoot = false; // Prevent shooting until the key is released
- }
-
- if (e.key === "r" && isGameOver) restartGame();
-});
-
-window.addEventListener("keyup", (e) => {
- // Stop moving when either the arrow keys or the 'a'/'d' keys are released
- if (
- e.key === "ArrowLeft" ||
- e.key === "ArrowRight" ||
- e.key === "a" ||
- e.key === "d"
- ) {
- player.dx = 0;
- }
-
- // Allow shooting again when the space key is released
- if (e.key === " ") {
- canShoot = true;
- }
-});
-
-// Bullet mechanics with cooldown
-function shootBullet() {
- const now = Date.now();
- if (now - lastBulletTime < 100) return; // Enforce cooldown of 0.1 seconds
- if (ammo <= 0) return; // Prevent shooting if ammo is empty
- lastBulletTime = now;
- ammo--; // Decrease ammo
-
- totalBulletsFired++; // Increment total bullets fired
-
- if (rapidFireActive) {
- // If rapid fire is active, fire bullets continuously with a short delay
- for (let i = 0; i < 3; i++) {
- setTimeout(() => {
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- });
- }, i * 50); // Fire bullets with 50ms delay between shots
- }
- } else if (shotgunActive) {
- // Shotgun effect, firing 3 bullets with a spread
- for (let i = -1; i <= 1; i++) {
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- angle: i * 10, // Spray the bullets at different angles
- });
- }
- } else {
- // Normal bullet
- bullets.push({
- x: player.x + player.width / 2 - 2.5,
- y: player.y,
- width: 5,
- height: 10,
- color: "yellow",
- speed: 7,
- });
- }
-}
-
-// Generate random color
-function getRandomColor() {
- const colors = ["red", "blue", "green", "orange", "purple", "pink"];
- return colors[Math.floor(Math.random() * colors.length)];
-}
-
-// Asteroid mechanics
-function createAsteroid() {
- const size = Math.random() * 40 + 30; // Bigger asteroids (min: 30, max: 70)
- asteroids.push({
- x: Math.random() * canvas.width,
- y: -size,
- width: size,
- height: size,
- color: getRandomColor(),
- speed: (Math.random() * 3 + 2) * asteroidSpeedMultiplier, // Faster initial speed
- });
-}
-
-// Item mechanics
-function createItem() {
- const randomType =
- sphereTypes[Math.floor(Math.random() * sphereTypes.length)];
- const size = 30;
- const x = Math.random() * canvas.width;
- items.push({
- x: x,
- y: -size,
- width: size,
- height: size,
- type: randomType,
- color:
- randomType === "blue"
- ? "blue"
- : randomType === "yellow"
- ? "yellow"
- : randomType === "green"
- ? "green"
- : "rainbow",
- speed: 3,
- });
-}
-
-// Update game elements
-function updatePlayer() {
- player.x += player.dx;
- if (player.x < 0) player.x = 0;
- if (player.x + player.width > canvas.width)
- player.x = canvas.width - player.width;
-}
-
-function updateBullets() {
- bullets.forEach((bullet, index) => {
- bullet.y -= bullet.speed;
- if (bullet.y + bullet.height < 0) bullets.splice(index, 1);
- });
-}
-
-function updateAsteroids() {
- asteroids.forEach((asteroid, index) => {
- asteroid.y += asteroid.speed;
- if (asteroid.y > canvas.height) asteroids.splice(index, 1);
- });
-}
-
-function updateItems() {
- items.forEach((item, index) => {
- item.y += item.speed;
- if (item.y > canvas.height) items.splice(index, 1);
- // Check if player collects the item
- if (
- player.x < item.x + item.width &&
- player.x + player.width > item.x &&
- player.y < item.y + item.height &&
- player.y + player.height > item.y
- ) {
- applyItemEffect(item.type);
- items.splice(index, 1); // Remove the item after it is collected
- }
- });
-}
-
-function applyItemEffect(type) {
- let points = Math.floor(Math.random() * 5) + 1; // Random points between 1 and 5
- if (type === "blue") {
- rapidFireActive = true;
- setTimeout(() => (rapidFireActive = false), 15000); // 15 seconds of rapid fire
- } else if (type === "yellow") {
- shotgunActive = true;
- setTimeout(() => (shotgunActive = false), 30000); // 30 seconds of shotgun
- } else if (type === "green") {
- ammo = 100; // Refill ammo
- } else if (type === "rainbow") {
- rapidFireActive = true;
- shotgunActive = true;
- setTimeout(() => {
- rapidFireActive = false;
- shotgunActive = false;
- }, 15000); // 15 seconds with all effects
- }
- score += points; // Add points when an item is collected
-}
-
-// Collision detection
-function checkCollisions() {
- bullets.forEach((bullet, bIndex) => {
- asteroids.forEach((asteroid, aIndex) => {
- if (
- bullet.x < asteroid.x + asteroid.width &&
- bullet.x + bullet.width > asteroid.x &&
- bullet.y < asteroid.y + asteroid.height &&
- bullet.y + bullet.height > asteroid.y
- ) {
- bullets.splice(bIndex, 1);
- asteroids.splice(aIndex, 1);
- score += Math.floor(Math.random() * 5) + 1; // Add points when an asteroid is destroyed
- // Visual feedback for destroyed asteroid
- createExplosion(asteroid.x, asteroid.y);
- }
- });
- });
-
- asteroids.forEach((asteroid) => {
- if (
- player.x < asteroid.x + asteroid.width &&
- player.x + player.width > asteroid.x &&
- player.y < asteroid.y + asteroid.height &&
- player.y + player.height > asteroid.y
- ) {
- isGameOver = true;
- }
- });
-}
-
-// Explosion effect
-function createExplosion(x, y) {
- ctx.fillStyle = "yellow";
- ctx.beginPath();
- ctx.arc(x, y, 20, 0, Math.PI * 2);
- ctx.fill();
- setTimeout(() => ctx.clearRect(x - 20, y - 20, 40, 40), 200); // Clear explosion after 200ms
-}
-
-// Draw elements
-function drawPlayer() {
- ctx.fillStyle = player.color;
- ctx.fillRect(player.x, player.y, player.width, player.height);
-}
-
-function drawBullets() {
- bullets.forEach((bullet) => {
- ctx.fillStyle = bullet.color;
- ctx.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
- });
-}
-
-function drawAsteroids() {
- asteroids.forEach((asteroid) => {
- ctx.fillStyle = asteroid.color;
- ctx.fillRect(asteroid.x, asteroid.y, asteroid.width, asteroid.height);
- });
-}
-
-function drawItems() {
- items.forEach((item) => {
- ctx.fillStyle = item.color;
- ctx.beginPath();
- ctx.arc(
- item.x + item.width / 2,
- item.y + item.height / 2,
- item.width / 2,
- 0,
- Math.PI * 2
- );
- ctx.fill();
- });
-}
-
-function drawScore() {
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.fillText(`Score: ${score}`, 20, 40); // Score at top-left corner
-}
-
-function drawAmmo() {
- ctx.fillStyle = "white";
- ctx.font = "24px Arial";
- ctx.fillText(`Ammo: ${ammo}`, 20, 70); // Ammo at top-left corner
-}
-
-function drawGameOver() {
- if (isGameOver) {
- ctx.fillStyle = "white";
- ctx.font = "40px Arial";
- ctx.textAlign = "center";
- ctx.fillText("Game Over!", canvas.width / 2, canvas.height / 2 - 40);
- ctx.font = "24px Arial";
- ctx.fillText(`Total Score: ${score}`, canvas.width / 2, canvas.height / 2);
- ctx.fillText(
- `Bullets Fired: ${totalBulletsFired}`,
- canvas.width / 2,
- canvas.height / 2 + 40
- );
- ctx.fillText(
- 'Press "R" to Restart',
- canvas.width / 2,
- canvas.height / 2 + 80
- );
- }
-}
-
-// Restart game
-function restartGame() {
- window.location.reload();
-}
-
-// Main game loop
-function gameLoop() {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- if (!isGameOver) {
- updatePlayer();
- updateBullets();
- updateAsteroids();
- updateItems();
- checkCollisions();
- }
-
- drawPlayer();
- drawBullets();
- drawAsteroids();
- drawItems();
- drawScore();
- drawAmmo();
- drawGameOver();
-
- if (!isGameOver) {
- if (Math.random() < 0.01) createAsteroid(); // 1% chance every frame to spawn an asteroid
- if (Math.random() < 0.005) createItem(); // 0.5% chance to spawn an item
- }
-
- requestAnimationFrame(gameLoop);
-}
-
-// Start game loop
-gameLoop();
diff --git a/secret/guessMyNumber/game.js b/secret/guessMyNumber/game.js
deleted file mode 100644
index 9a3436d..0000000
--- a/secret/guessMyNumber/game.js
+++ /dev/null
@@ -1,65 +0,0 @@
-"use strict";
-
-const targetNum = Math.trunc(Math.random() * 20) + 1;
-let highScore = Number(localStorage.getItem("highscore")) || 0;
-let userGuess = 10; // Default guess
-let currScore = 20;
-
-const screenEl = document.querySelector(".screen");
-const msgEl = document.querySelector(".message");
-const guessInput = document.querySelector("#guess");
-const scoreEl = document.querySelector(".score");
-const highScoreEl = document.querySelector(".highScore");
-const checkBtn = document.querySelector("#check");
-const restartBtn = document.querySelector("#restart");
-const incBtn = document.querySelector("#up");
-const decBtn = document.querySelector("#down");
-
-const setMsg = (msg) => (msgEl.textContent = msg);
-const setScore = (score) =>
- (scoreEl.textContent = `Score: ${(currScore = score)}`);
-const setHighScore = () => {
- highScoreEl.textContent = `Highscore: ${highScore}`;
- localStorage.setItem("highscore", highScore);
-};
-const changeColor = (color) => (screenEl.style.backgroundColor = color);
-
-checkBtn.addEventListener("click", () => {
- userGuess = Number(guessInput.textContent);
- if (!userGuess || userGuess < 1 || userGuess > 20) {
- setMsg("Please enter a valid number between 1 and 20.");
- } else if (userGuess === targetNum) {
- highScore = Math.max(highScore, currScore);
- setHighScore();
- setMsg(
- currScore !== 20 ? "Correct Number!" : "Are you sure you didn't cheat?"
- );
- changeColor(currScore !== 20 ? "#1ba100" : "#FFC300");
- } else {
- setMsg(userGuess > targetNum ? "Too High!" : "Too Low!");
- if (currScore > 1) {
- setScore(currScore - 1);
- } else {
- setScore(1);
- setMsg("You lost the game!");
- changeColor("#a10000");
- }
- }
-});
-
-restartBtn.addEventListener("click", () => location.reload());
-incBtn.addEventListener(
- "click",
- () =>
- (guessInput.textContent = Math.min(Number(guessInput.textContent) + 1, 20))
-);
-decBtn.addEventListener(
- "click",
- () =>
- (guessInput.textContent = Math.max(Number(guessInput.textContent) - 1, 1))
-);
-
-guessInput.textContent = userGuess;
-setMsg("Guess a number");
-setScore(currScore);
-setHighScore();
diff --git a/secret/guessMyNumber/index.html b/secret/guessMyNumber/index.html
deleted file mode 100644
index 4e88eaa..0000000
--- a/secret/guessMyNumber/index.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
Guess My Number
-
-
-
-
-
-
-
-
-
-
-
- Guess My Number - Game
-
-
-
-
-
-
-
-
-
Description
-
Guess a number between 1 and 20
-
A = check
-
B = Reload
-
▲ = increases guess by one
-
▼ = decreases guess by one
-
-
-
-
-
-
-
-
-
-
-
diff --git a/secret/guessMyNumber/styles.css b/secret/guessMyNumber/styles.css
deleted file mode 100644
index 3a50aec..0000000
--- a/secret/guessMyNumber/styles.css
+++ /dev/null
@@ -1,189 +0,0 @@
-/* Base Reset */
-body,
-html {
- margin: 0;
- padding: 0;
- font-family: monospace;
- background-color: #3a2d56;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
-}
-
-/* GameBoy Layout */
-.gameboy {
- background-color: #5f4c82; /* Game Boy Color purple shell */
- width: 441px;
- height: 735px;
- border-radius: 20px;
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.6);
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 10px;
- position: relative;
-}
-
-@media (max-width: 768px) {
- .gameboy {
- width: 100vw;
- height: 100vh;
- border-radius: 0;
- }
-}
-
-/* Screen */
-.screen {
- background-color: #306230; /* Game Boy green screen */
- border: 4px solid #0f380f;
- width: 90%;
- height: 55%;
- margin-top: 20px;
- border-radius: 10px;
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.5);
- overflow: hidden;
-}
-
-.game {
- text-align: center;
- width: 90%;
-}
-
-/* Titles */
-h1 {
- font-size: 2rem; /* Increased font size */
- margin-bottom: 10px;
- text-transform: uppercase;
-}
-
-/* Guess Display */
-.guess-display {
- background-color: #9bbc0f;
- color: #0f380f;
- border: 2px solid #0f380f;
- font-size: 2rem; /* Increased font size */
- width: 80px; /* Increased width */
- text-align: center;
- margin: 10px auto;
- padding: 10px; /* Increased padding */
- border-radius: 4px;
-}
-
-/* Messages */
-.message,
-.score,
-.highScore {
- font-size: 1.4rem; /* Increased font size */
- margin: 5px 0;
-}
-
-.description,
-.description p {
- font-size: 1.2rem;
- margin: 0 auto;
- padding: 0 auto;
-}
-
-/* Controls Section */
-.controls {
- margin-top: 20px;
- display: flex;
- justify-content: space-between;
- width: 80%;
- align-items: center;
-}
-
-/* D-Pad */
-.dpad {
- position: relative;
- width: 120px; /* Increased size */
- height: 120px; /* Increased size */
-}
-
-/* Base Styling for D-Pad Buttons */
-.dpad-btn {
- background-color: #0f380f;
- color: #9bbc0f;
- border: none;
- border-radius: 5px;
- position: absolute;
- width: 42px;
- height: 42px;
- font-size: 1.5rem; /* Increased size */
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- z-index: 1;
-}
-
-.dpad-btn.up {
- top: 0;
- left: 50%;
- transform: translateX(-50%);
-}
-
-.dpad-btn.down {
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
-}
-
-.dpad-btn.left {
- top: 50%;
- left: 0;
- transform: translateY(-50%);
-}
-
-.dpad-btn.right {
- top: 50%;
- right: 0;
- transform: translateY(-50%);
-}
-
-/* D-Pad Center to Connect Buttons */
-.dpad-center {
- background-color: #0f380f;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 40px;
- height: 40px;
- border: 2px solid #9cbc0f00;
- z-index: 0;
- border-radius: 5px;
-}
-
-/* A and B Buttons */
-.action-buttons {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- height: 140px; /* Increased height */
-}
-
-.btn {
- background-color: #0f380f;
- color: #9bbc0f;
- border: 2px solid #9bbc0f;
- border-radius: 50%;
- width: 60px;
- height: 60px;
- font-size: 1.8rem; /* Increased font size */
- cursor: pointer;
- transition: transform 0.1s, background-color 0.2s;
-}
-
-.btn:hover {
- background-color: #9bbc0f;
- color: #0f380f;
-}
-
-.btn:active {
- transform: scale(0.9);
-}
diff --git a/secret/guessMyNumber/styles.js b/secret/guessMyNumber/styles.js
deleted file mode 100644
index 8ccae52..0000000
--- a/secret/guessMyNumber/styles.js
+++ /dev/null
@@ -1,148 +0,0 @@
-"use strict";
-const left = document.querySelector("#left");
-const right = document.querySelector("#right");
-const gameboy = document.querySelector(".gameboy");
-const html = document.documentElement;
-const body = document.body;
-const screen = document.querySelector(".screen");
-const dpadButtons = document.querySelectorAll(".dpad-btn");
-const dpadCenter = document.querySelector(".dpad-center"); // Darker variant
-const actionButtons = document.querySelectorAll(".btn");
-
-const colors = [
- {
- gameboyColor: "#B39DDB",
- htmlColor: "#D1C4E9",
- screenColor: "#E1BEE7",
- buttonColor: "#673AB7",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#5E35B1",
- },
- {
- gameboyColor: "#FFC107",
- htmlColor: "#FFF9C4",
- screenColor: "#FFEB3B",
- buttonColor: "#FF9800",
- buttonTextColor: "#000000",
- dpadCenterColor: "#EF6C00",
- },
- {
- gameboyColor: "#8BC34A",
- htmlColor: "#C5E1A5",
- screenColor: "#A5D6A7",
- buttonColor: "#FF5722",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#E64A19",
- },
- {
- gameboyColor: "#F44336",
- htmlColor: "#FFCDD2",
- screenColor: "#EF9A9A",
- buttonColor: "#E91E63",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#C2185B",
- },
- {
- gameboyColor: "#03A9F4",
- htmlColor: "#BBDEFB",
- screenColor: "#90CAF9",
- buttonColor: "#FFEB3B",
- buttonTextColor: "#000000",
- dpadCenterColor: "#0277BD",
- },
- {
- gameboyColor: "#FF7043",
- htmlColor: "#FFCCBC",
- screenColor: "#FFAB91",
- buttonColor: "#FF5722",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#D84315",
- },
- {
- gameboyColor: "#9C27B0",
- htmlColor: "#E1BEE7",
- screenColor: "#D1C4E9",
- buttonColor: "#7B1FA2",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#6A1B9A",
- },
- {
- gameboyColor: "#FFD700",
- htmlColor: "#FFF9C4",
- screenColor: "#FFF59D",
- buttonColor: "#FF9800",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#F57F17",
- },
- {
- gameboyColor: "#009688",
- htmlColor: "#B2DFDB",
- screenColor: "#80CBC4",
- buttonColor: "#4CAF50",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#00796B",
- },
- {
- gameboyColor: "#795548",
- htmlColor: "#D7CCC8",
- screenColor: "#A1887F",
- buttonColor: "#9E9E9E",
- buttonTextColor: "#000000",
- dpadCenterColor: "#5D4037",
- },
- {
- gameboyColor: "#FF5733",
- htmlColor: "#FFCCCB",
- screenColor: "#FFABAB",
- buttonColor: "#C70039",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#B71C1C",
- },
- {
- gameboyColor: "#00BCD4",
- htmlColor: "#B2EBF2",
- screenColor: "#80DEEA",
- buttonColor: "#00ACC1",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#00838F",
- },
-];
-
-let currentColorIndex = localStorage.getItem("gameboyColorIndex")
- ? parseInt(localStorage.getItem("gameboyColorIndex"))
- : 0;
-
-function updateGameBoyColor() {
- gameboy.style.backgroundColor = colors[currentColorIndex].gameboyColor;
- html.style.backgroundColor = colors[currentColorIndex].htmlColor;
- body.style.backgroundColor = colors[currentColorIndex].htmlColor;
- screen.style.backgroundColor = colors[currentColorIndex].screenColor;
-
- dpadButtons.forEach((button) => {
- button.style.backgroundColor = colors[currentColorIndex].buttonColor;
- button.style.color = colors[currentColorIndex].buttonTextColor;
- });
-
- // Using darker dpad center color
- dpadCenter.style.backgroundColor = colors[currentColorIndex].dpadCenterColor;
- dpadCenter.style.color = colors[currentColorIndex].buttonTextColor;
-
- actionButtons.forEach((button) => {
- button.style.backgroundColor = colors[currentColorIndex].buttonColor;
- button.style.color = colors[currentColorIndex].buttonTextColor;
- });
-}
-
-left.addEventListener("click", () => {
- currentColorIndex = (currentColorIndex - 1 + colors.length) % colors.length;
- localStorage.setItem("gameboyColorIndex", currentColorIndex);
- updateGameBoyColor();
-});
-
-right.addEventListener("click", () => {
- currentColorIndex = (currentColorIndex + 1) % colors.length;
- localStorage.setItem("gameboyColorIndex", currentColorIndex);
- updateGameBoyColor();
-});
-
-updateGameBoyColor();
diff --git a/secret/images/asteroid.png b/secret/images/asteroid.png
deleted file mode 100644
index 2859780..0000000
Binary files a/secret/images/asteroid.png and /dev/null differ
diff --git a/secret/images/background.jpg b/secret/images/background.jpg
deleted file mode 100644
index 63f85fe..0000000
Binary files a/secret/images/background.jpg and /dev/null differ
diff --git a/secret/images/blackjack.jpg b/secret/images/blackjack.jpg
deleted file mode 100644
index b20ee37..0000000
Binary files a/secret/images/blackjack.jpg and /dev/null differ
diff --git a/secret/images/default.jpeg b/secret/images/default.jpeg
deleted file mode 100644
index 610df27..0000000
Binary files a/secret/images/default.jpeg and /dev/null differ
diff --git a/secret/images/endless_runner.png b/secret/images/endless_runner.png
deleted file mode 100644
index 5d153d7..0000000
Binary files a/secret/images/endless_runner.png and /dev/null differ
diff --git a/secret/images/minesweeper.png b/secret/images/minesweeper.png
deleted file mode 100644
index e7d7376..0000000
Binary files a/secret/images/minesweeper.png and /dev/null differ
diff --git a/secret/images/number.jpeg b/secret/images/number.jpeg
deleted file mode 100644
index c6dbdd3..0000000
Binary files a/secret/images/number.jpeg and /dev/null differ
diff --git a/secret/images/snake.png b/secret/images/snake.png
deleted file mode 100644
index 572f201..0000000
Binary files a/secret/images/snake.png and /dev/null differ
diff --git a/secret/images/solitaire.png b/secret/images/solitaire.png
deleted file mode 100644
index 6393bde..0000000
Binary files a/secret/images/solitaire.png and /dev/null differ
diff --git a/secret/index.html b/secret/index.html
deleted file mode 100644
index dc45d69..0000000
--- a/secret/index.html
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
-
-
-
Secret Game Collection
-
-
-
-
-
-
-
-
- Secret Game Collection
-
-
-
-
-
-
-
- © 2025 Game Collection
-
-
-
diff --git a/secret/mineSweeper/index.html b/secret/mineSweeper/index.html
deleted file mode 100644
index 5794679..0000000
--- a/secret/mineSweeper/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
Minesweeper
-
-
-
-
-
-
-
-
-
-
Minesweeper
- Grid Size:
-
-
- Number of Bombs:
-
-
- Start Game
-
-
-
-
-
-
-
-
-
diff --git a/secret/mineSweeper/script.js b/secret/mineSweeper/script.js
deleted file mode 100644
index f30f685..0000000
--- a/secret/mineSweeper/script.js
+++ /dev/null
@@ -1,192 +0,0 @@
-document.getElementById("startGame").addEventListener("click", function () {
- const gridSize = parseInt(document.getElementById("gridSize").value);
- const bombs = parseInt(document.getElementById("bombs").value);
-
- document.getElementById("settings").style.display = "none";
- document.getElementById("game").style.display = "block";
-
- renderGame(gridSize, bombs);
-});
-
-const canvas = document.getElementById("game");
-const ctx = canvas.getContext("2d");
-
-class Minesweeper {
- constructor(width, height, bombs) {
- this.size = 25;
- this.field = new Array(width);
- this.bombs = new Array(width);
- for (let x = 0; x < this.field.length; x++) {
- this.field[x] = new Array(height);
- this.bombs[x] = new Array(height);
- for (let y = 0; y < this.field[x].length; y++) {
- this.field[x][y] = 1;
- this.bombs[x][y] = false;
- }
- }
-
- this.bombAmount =
- bombs > (width * height) / 2 ? (width * height) / 2 : bombs;
- this.width = width;
- this.height = height;
- this.firstClick = false;
- this.drawField();
- }
-
- generateBombs() {
- for (let i = 0; i < this.bombAmount; i++) {
- let x = Math.floor(Math.random() * this.width);
- let y = Math.floor(Math.random() * this.height);
- this.bombs[x][y] || this.field[x][y] == 0
- ? i--
- : (this.bombs[x][y] = true);
- }
- this.firstClick = true;
- }
-
- getNearbyBombs(x, y) {
- let counter = 0;
- for (let newX = x - 1; newX <= x + 1; newX++) {
- for (let newY = y - 1; newY <= y + 1; newY++) {
- if (
- newX < this.field.length &&
- newX >= 0 &&
- newY < this.field[0].length &&
- newY >= 0
- ) {
- this.bombs[newX][newY] ? counter++ : {};
- }
- }
- }
- return counter;
- }
-
- checkWin() {
- for (let x = 0; x < this.field.length; x++) {
- for (let y = 0; y < this.field[x].length; y++) {
- if (this.field[x][y] != 0 && !this.bombs[x][y]) {
- return;
- } else if (this.field[x][y] == 0 && this.bombs[x][y]) {
- alert(`[ERROR]: Square (${x}|${y}) should not be a bomb!`);
- this.bombs[x][y] = false;
- }
- }
- }
- this.drawField();
- alert("You won!");
- window.location.reload();
- }
-
- markSquare(x, y) {
- if (x < this.field.length && y < this.field[0].length) {
- switch (this.field[x][y]) {
- case 1:
- this.field[x][y]++;
- break;
- case 2:
- this.field[x][y]++;
- break;
- case 3:
- this.field[x][y] = 1;
- break;
- default:
- break;
- }
- this.drawField();
- }
- }
-
- uncoverSquare(x, y) {
- if (x < this.field.length && x >= 0 && y < this.field[0].length && y >= 0) {
- if (this.bombs[x][y] && this.field[x][y] == 1) {
- alert("You lost!");
- window.location.reload();
- } else if (this.field[x][y] == 1) {
- this.field[x][y] = 0;
- !this.firstClick ? this.generateBombs() : {};
- if (this.getNearbyBombs(x, y) == 0) {
- for (let newX = x - 1; newX <= x + 1; newX++) {
- for (let newY = y - 1; newY <= y + 1; newY++) {
- if (
- newX < this.field.length &&
- newX >= 0 &&
- newY < this.field[0].length &&
- newY >= 0
- ) {
- this.field[newX][newY] == 1
- ? this.uncoverSquare(newX, newY)
- : {};
- }
- }
- }
- }
- }
- this.checkWin();
- this.drawField();
- }
- }
-
- drawSquare(x, y, type) {
- ctx.lineWidth = 3;
- let uncovered = (x + y) % 2 === 0 ? "#D3D3D3" : "#A9A9A9";
- let covered = (x + y) % 2 === 0 ? "#4CAF50" : "#81C784";
- ctx.fillStyle = type != 0 ? covered : uncovered;
- ctx.fillRect(x * this.size, y * this.size, this.size, this.size);
- ctx.strokeStyle = "#000";
- ctx.strokeRect(x * this.size, y * this.size, this.size, this.size);
-
- if (type != 1) {
- const fontSize = this.size / 2;
- const number = this.getNearbyBombs(x, y);
- let finalPrint;
- ctx.font = `${fontSize}px sans-serif`;
- ctx.fillStyle = "#000";
- type == 0 ? (finalPrint = number ? number : " ") : {};
- type == 2 ? (finalPrint = "🚩") : {};
- type == 3 ? (finalPrint = "❓") : {};
- ctx.fillText(
- finalPrint,
- x * this.size + fontSize / (type == 0 ? 1.5 : 1.8),
- y * this.size + fontSize * 1.3
- );
- }
- }
-
- drawField() {
- if (window.innerWidth > window.innerHeight) {
- this.size = window.innerHeight / (this.field[0].length + 4);
- } else {
- this.size = window.innerWidth / (this.field.length + 4);
- }
-
- canvas.width = this.size * this.field.length;
- canvas.height = this.size * this.field[0].length;
-
- const offsetX = (canvas.width - this.field.length * this.size) / 2;
- const offsetY = (canvas.height - this.field[0].length * this.size) / 2;
-
- for (let x = 0; x < this.field.length; x++) {
- for (let y = 0; y < this.field[x].length; y++) {
- this.drawSquare(x, y, this.field[x][y], offsetX, offsetY);
- }
- }
- }
-}
-
-const renderGame = (gridSize, bombs) => {
- let field = new Minesweeper(gridSize, gridSize, bombs);
- window.addEventListener("resize", () => field.drawField());
- canvas.addEventListener("click", (event) => {
- const rect = canvas.getBoundingClientRect();
- const x = Math.floor((event.clientX - rect.left) / field.size);
- const y = Math.floor((event.clientY - rect.top) / field.size);
- field.uncoverSquare(x, y);
- });
- canvas.addEventListener("contextmenu", (event) => {
- event.preventDefault();
- const rect = canvas.getBoundingClientRect();
- const x = Math.floor((event.clientX - rect.left) / field.size);
- const y = Math.floor((event.clientY - rect.top) / field.size);
- field.markSquare(x, y);
- });
-};
diff --git a/secret/mineSweeper/styles.css b/secret/mineSweeper/styles.css
deleted file mode 100644
index 8468965..0000000
--- a/secret/mineSweeper/styles.css
+++ /dev/null
@@ -1,104 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-body,
-html {
- height: 100%;
- margin: 0;
- font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- background-color: #121212;
- color: #e0e0e0;
-}
-
-#settings {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- text-align: center;
- margin: auto;
- background-color: #1e1e1e;
- padding: 40px;
- border-radius: 12px;
- box-shadow: 0 6px 15px rgba(0, 0, 0, 0.5);
- width: 100%;
- max-width: 600px;
-}
-
-h1 {
- font-size: 2.5em;
- margin-bottom: 20px;
- color: #007bff;
-}
-
-label {
- margin-bottom: 12px;
- font-size: 20px;
- color: #d1d1d1;
-}
-
-input[type="number"],
-input[type="range"],
-span {
- padding: 12px;
- margin-bottom: 20px;
- width: 100%;
- max-width: 400px;
- text-align: center;
- border: 1px solid #444;
- border-radius: 6px;
- background-color: #333;
- color: #e0e0e0;
- font-size: 18px;
- transition: border-color 0.3s ease;
-}
-
-input[type="number"]:focus,
-input[type="range"]:focus {
- border-color: #007bff;
- outline: none;
-}
-
-button {
- padding: 12px 24px;
- background-color: #007bff;
- color: white;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- transition: background-color 0.3s ease, transform 0.2s ease;
- font-size: 18px;
-}
-
-button:hover {
- background-color: #0056b3;
- transform: translateY(-2px);
-}
-
-button:active {
- transform: translateY(0);
-}
-
-canvas {
- display: none;
-}
-
-@media (max-width: 600px) {
- #settings {
- font-size: 16px;
- }
-
- input[type="number"],
- input[type="range"],
- button {
- width: 90%;
- max-width: none;
- }
-}
diff --git a/secret/snake/audio/dead.mp3 b/secret/snake/audio/dead.mp3
deleted file mode 100644
index 414bf65..0000000
Binary files a/secret/snake/audio/dead.mp3 and /dev/null differ
diff --git a/secret/snake/audio/down.mp3 b/secret/snake/audio/down.mp3
deleted file mode 100644
index 03533a0..0000000
Binary files a/secret/snake/audio/down.mp3 and /dev/null differ
diff --git a/secret/snake/audio/eat.mp3 b/secret/snake/audio/eat.mp3
deleted file mode 100644
index 076198c..0000000
Binary files a/secret/snake/audio/eat.mp3 and /dev/null differ
diff --git a/secret/snake/audio/left.mp3 b/secret/snake/audio/left.mp3
deleted file mode 100644
index 4d3d245..0000000
Binary files a/secret/snake/audio/left.mp3 and /dev/null differ
diff --git a/secret/snake/audio/right.mp3 b/secret/snake/audio/right.mp3
deleted file mode 100644
index 64408ea..0000000
Binary files a/secret/snake/audio/right.mp3 and /dev/null differ
diff --git a/secret/snake/audio/up.mp3 b/secret/snake/audio/up.mp3
deleted file mode 100644
index 97cfbe9..0000000
Binary files a/secret/snake/audio/up.mp3 and /dev/null differ
diff --git a/secret/snake/game.js b/secret/snake/game.js
deleted file mode 100644
index f94dc2e..0000000
--- a/secret/snake/game.js
+++ /dev/null
@@ -1,95 +0,0 @@
-"use strict";
-
-const cvs = document.getElementById("snake");
-const ctx = cvs.getContext("2d");
-const box = 20;
-
-let snake = [{ x: 9 * box, y: 10 * box }];
-let food = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box,
-};
-let score = 0;
-let d;
-let game;
-
-document.addEventListener("keydown", direction);
-function direction(event) {
- let key = event.keyCode;
- if ((key == 37 || key == 65) && d != "RIGHT") d = "LEFT";
- else if ((key == 38 || key == 87) && d != "DOWN") d = "UP";
- else if ((key == 39 || key == 68) && d != "LEFT") d = "RIGHT";
- else if ((key == 40 || key == 83) && d != "UP") d = "DOWN";
-}
-
-function collision(head, array) {
- return array.some((part) => head.x == part.x && head.y == part.y);
-}
-
-function draw() {
- ctx.fillStyle = "#0f380f";
- ctx.fillRect(0, 0, cvs.width, cvs.height);
-
- ctx.fillStyle = "red";
- ctx.fillRect(food.x, food.y, box, box);
-
- for (let i = 0; i < snake.length; i++) {
- ctx.fillStyle = i == 0 ? "lime" : "white";
- ctx.fillRect(snake[i].x, snake[i].y, box, box);
- ctx.strokeStyle = "black";
- ctx.strokeRect(snake[i].x, snake[i].y, box, box);
- }
-
- let snakeX = snake[0].x;
- let snakeY = snake[0].y;
-
- if (d == "LEFT") snakeX -= box;
- if (d == "UP") snakeY -= box;
- if (d == "RIGHT") snakeX += box;
- if (d == "DOWN") snakeY += box;
-
- if (snakeX == food.x && snakeY == food.y) {
- score++;
- food = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box,
- };
- } else {
- snake.pop();
- }
-
- let newHead = { x: snakeX, y: snakeY };
-
- if (
- snakeX < 0 ||
- snakeX >= cvs.width ||
- snakeY < 0 ||
- snakeY >= cvs.height ||
- collision(newHead, snake)
- ) {
- clearInterval(game);
- document.getElementById("restartBtn").style.display = "block";
- return;
- }
-
- snake.unshift(newHead);
-
- ctx.fillStyle = "white";
- ctx.font = "20px Arial";
- ctx.fillText("Score: " + score, 10, 20);
-}
-
-function restartGame() {
- snake = [{ x: 9 * box, y: 10 * box }];
- food = {
- x: Math.floor(Math.random() * 19 + 1) * box,
- y: Math.floor(Math.random() * 19 + 1) * box,
- };
- score = 0;
- d = "";
- document.getElementById("restartBtn").style.display = "none";
- game = setInterval(draw, 150);
-}
-
-document.getElementById("restartBtn").addEventListener("click", restartGame);
-game = setInterval(draw, 150);
diff --git a/secret/snake/img/food.png b/secret/snake/img/food.png
deleted file mode 100644
index 921fe78..0000000
Binary files a/secret/snake/img/food.png and /dev/null differ
diff --git a/secret/snake/img/ground.png b/secret/snake/img/ground.png
deleted file mode 100644
index 218b190..0000000
Binary files a/secret/snake/img/ground.png and /dev/null differ
diff --git a/secret/snake/index.html b/secret/snake/index.html
deleted file mode 100644
index 7f81ed2..0000000
--- a/secret/snake/index.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
Snake - Game
-
-
-
-
-
-
-
-
-
-
-
- Snake - Game
-
-
Description
-
Eat as many apples and grow as much as possible
-
◀ or A or arrow left = move left
-
▶ or D or arrow right = move right
-
▲ or W or arrow up = move up
-
▼ or S or arrow down = move down
-
-
-
-
-
-
-
-
-
-
-
-
- Start
- A
- B
-
-
-
-
-
-
-
diff --git a/secret/snake/styles.css b/secret/snake/styles.css
deleted file mode 100644
index 2454d67..0000000
--- a/secret/snake/styles.css
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Base Reset */
-body,
-html {
- margin: 0;
- padding: 0;
- font-family: monospace;
- background-color: #3a2d56;
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
-}
-
-/* GameBoy Layout */
-.gameboy {
- background-color: #5f4c82;
- width: 441px;
- height: 735px;
- border-radius: 20px;
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.6);
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 10px;
- position: relative;
-}
-
-@media (max-width: 768px) {
- .gameboy {
- width: 100vw;
- height: 100vh;
- border-radius: 0;
- }
-}
-
-/* Screen */
-.screen {
- background-color: black;
- border: 4px solid #0f380f;
- width: 90%;
- height: 55%;
- margin-top: 20px;
- border-radius: 10px;
- display: flex;
- justify-content: center;
- align-items: center;
- box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.5);
- overflow: hidden;
-}
-
-.game {
- text-align: center;
- width: 90%;
-}
-
-/* Titles */
-h1 {
- font-size: 2rem;
- margin-bottom: 10px;
- text-transform: uppercase;
- color: #9bbc0f;
-}
-
-.description,
-.description p {
- font-size: 1.2rem;
- margin: 0 auto;
- padding: 0 auto;
- color: white;
-}
-
-/* Grid container */
-#grid {
- display: grid;
- grid-template-columns: repeat(10, 1fr); /* Adjust to match gridSize */
- grid-template-rows: repeat(10, 1fr); /* Adjust to match gridSize */
- width: 400px; /* Adjust as needed */
- height: 400px; /* Adjust as needed */
- border: 2px solid #0f380f;
- margin: 20px auto;
- /* initially hide */
- display: none;
-}
-
-/* Individual cells */
-.cell {
- width: 100%;
- height: 100%;
-}
-
-.cell.light-green {
- background-color: #9bbc0f;
-}
-
-.cell.dark-green {
- background-color: #0f380f;
-}
-
-/* Snake styling */
-.snake {
- background-color: #e600ff; /* Snake color */
- z-index: 1000;
-}
-
-/* Apple styling */
-.apple {
- background-color: red; /* Apple color */
- z-index: 999;
-}
-
-/* Controls Section */
-.controls {
- margin-top: 20px;
- display: flex;
- justify-content: space-between;
- width: 80%;
- align-items: center;
-}
-
-/* D-Pad */
-.dpad {
- position: relative;
- width: 120px;
- height: 120px;
-}
-
-/* Base Styling for D-Pad Buttons */
-.dpad-btn {
- background-color: #0f380f;
- color: #9bbc0f;
- border: none;
- border-radius: 5px;
- position: absolute;
- width: 42px;
- height: 42px;
- font-size: 1.5rem;
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- z-index: 1;
-}
-
-.dpad-btn.up {
- top: 0;
- left: 50%;
- transform: translateX(-50%);
-}
-
-.dpad-btn.down {
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
-}
-
-.dpad-btn.left {
- top: 50%;
- left: 0;
- transform: translateY(-50%);
-}
-
-.dpad-btn.right {
- top: 50%;
- right: 0;
- transform: translateY(-50%);
-}
-
-/* D-Pad Center to Connect Buttons */
-.dpad-center {
- background-color: #0f380f;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 40px;
- height: 40px;
- border: 2px solid transparent;
- z-index: 0;
- border-radius: 5px;
-}
-
-/* A and B Buttons */
-.action-buttons {
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- height: 200px;
-}
-
-.btn {
- background-color: #0f380f;
- color: #9bbc0f;
- border: 2px solid #9bbc0f;
- border-radius: 50%;
- width: 60px;
- height: 60px;
- font-size: 1.8rem;
- cursor: pointer;
- transition: transform 0.1s, background-color 0.2s;
-}
-
-.btn:hover {
- background-color: #9bbc0f;
- color: #0f380f;
-}
-
-.btn:active {
- transform: scale(0.9);
-}
-
-/* Start Button */
-.start-btn {
- background-color: #0f380f;
- color: #9bbc0f;
- border: 2px solid #9bbc0f;
- border-radius: 5px;
- width: 100px;
- height: 40px;
- font-size: 1.2rem;
- cursor: pointer;
- transition: transform 0.1s, background-color 0.2s;
- margin-bottom: 20px;
-}
-
-.start-btn:hover {
- background-color: #9bbc0f;
- color: #0f380f;
-}
-
-.start-btn:active {
- transform: scale(0.9);
-}
-
-/* Hidden Canvas for Debugging or Fallback */
-canvas {
- display: none;
- z-index: 1000;
-}
diff --git a/secret/snake/styles.js b/secret/snake/styles.js
deleted file mode 100644
index 231d5b3..0000000
--- a/secret/snake/styles.js
+++ /dev/null
@@ -1,134 +0,0 @@
-"use strict";
-const aBtn = document.querySelector("#a");
-const bBtn = document.querySelector("#b");
-const gameboy = document.querySelector(".gameboy");
-const html = document.documentElement;
-const body = document.body;
-const dpadButtons = document.querySelectorAll(".dpad-btn");
-const dpadCenter = document.querySelector(".dpad-center"); // Darker variant
-const actionButtons = document.querySelectorAll(".btn");
-
-const colors = [
- {
- gameboyColor: "#B39DDB",
- htmlColor: "#D1C4E9",
- buttonColor: "#673AB7",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#5E35B1",
- },
- {
- gameboyColor: "#FFC107",
- htmlColor: "#FFF9C4",
- buttonColor: "#FF9800",
- buttonTextColor: "#000000",
- dpadCenterColor: "#EF6C00",
- },
- {
- gameboyColor: "#8BC34A",
- htmlColor: "#C5E1A5",
- buttonColor: "#FF5722",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#E64A19",
- },
- {
- gameboyColor: "#F44336",
- htmlColor: "#FFCDD2",
- buttonColor: "#E91E63",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#C2185B",
- },
- {
- gameboyColor: "#03A9F4",
- htmlColor: "#BBDEFB",
- buttonColor: "#FFEB3B",
- buttonTextColor: "#000000",
- dpadCenterColor: "#0277BD",
- },
- {
- gameboyColor: "#FF7043",
- htmlColor: "#FFCCBC",
- buttonColor: "#FF5722",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#D84315",
- },
- {
- gameboyColor: "#9C27B0",
- htmlColor: "#E1BEE7",
- buttonColor: "#7B1FA2",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#6A1B9A",
- },
- {
- gameboyColor: "#FFD700",
- htmlColor: "#FFF9C4",
- buttonColor: "#FF9800",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#F57F17",
- },
- {
- gameboyColor: "#009688",
- htmlColor: "#B2DFDB",
- buttonColor: "#4CAF50",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#00796B",
- },
- {
- gameboyColor: "#795548",
- htmlColor: "#D7CCC8",
- buttonColor: "#9E9E9E",
- buttonTextColor: "#000000",
- dpadCenterColor: "#5D4037",
- },
- {
- gameboyColor: "#FF5733",
- htmlColor: "#FFCCCB",
- buttonColor: "#C70039",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#B71C1C",
- },
- {
- gameboyColor: "#00BCD4",
- htmlColor: "#B2EBF2",
- buttonColor: "#00ACC1",
- buttonTextColor: "#FFFFFF",
- dpadCenterColor: "#00838F",
- },
-];
-
-let currentColorIndex = localStorage.getItem("gameboyColorIndex")
- ? parseInt(localStorage.getItem("gameboyColorIndex"))
- : 0;
-
-function updateGameBoyColor() {
- gameboy.style.backgroundColor = colors[currentColorIndex].gameboyColor;
- html.style.backgroundColor = colors[currentColorIndex].htmlColor;
- body.style.backgroundColor = colors[currentColorIndex].htmlColor;
-
- dpadButtons.forEach((button) => {
- button.style.backgroundColor = colors[currentColorIndex].buttonColor;
- button.style.color = colors[currentColorIndex].buttonTextColor;
- });
-
- // Using darker dpad center color
- dpadCenter.style.backgroundColor = colors[currentColorIndex].dpadCenterColor;
- dpadCenter.style.color = colors[currentColorIndex].buttonTextColor;
-
- actionButtons.forEach((button) => {
- button.style.backgroundColor = colors[currentColorIndex].buttonColor;
- button.style.color = colors[currentColorIndex].buttonTextColor;
- });
-}
-
-aBtn.addEventListener("click", () => {
- currentColorIndex = (currentColorIndex - 1 + colors.length) % colors.length;
- localStorage.setItem("gameboyColorIndex", currentColorIndex);
- updateGameBoyColor();
-});
-
-bBtn.addEventListener("click", () => {
- currentColorIndex = (currentColorIndex + 1) % colors.length;
- localStorage.setItem("gameboyColorIndex", currentColorIndex);
- updateGameBoyColor();
-});
-
-updateGameBoyColor();
diff --git a/secret/snake/test.html b/secret/snake/test.html
deleted file mode 100644
index 12a5cfb..0000000
--- a/secret/snake/test.html
+++ /dev/null
@@ -1,197 +0,0 @@
-
-
-
-
-
-
Snake Game - GameBoy Style
-
-
-
-
-
Snake Game
-
-
-
-
Restart
-
-
-
-
-
diff --git a/secret/styles.css b/secret/styles.css
deleted file mode 100644
index b25a85c..0000000
--- a/secret/styles.css
+++ /dev/null
@@ -1,145 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-body {
- font-family: "Courier New", Courier, monospace;
- background-color: #0d0d0d;
- color: #b0b0b0;
- margin: 0;
- line-height: 1.6;
- background-image: url("images/background.jpg");
- background-size: cover; /* Adjust size for tape appearance */
-}
-
-header {
- background-color: #222; /* Fully opaque background */
- color: #b0b0b0;
- text-align: center;
- padding: 1em 0;
- font-size: 2rem;
- text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7);
- animation: neonFlicker 1.5s infinite;
-}
-
-/* Create the flickering neon light effect */
-@keyframes neonFlicker {
- 0% {
- text-shadow: 0 0 5px #ffcc00, 0 0 10px #ffcc00, 0 0 15px #ffcc00,
- 0 0 20px #ffcc00, 0 0 30px #ffcc00, 0 0 40px #ffcc00, 0 0 50px #ffcc00;
- }
- 20% {
- text-shadow: 0 0 3px #ffcc00, 0 0 7px #ffcc00, 0 0 10px #ffcc00,
- 0 0 15px #ffcc00, 0 0 20px #ffcc00;
- }
- 40% {
- text-shadow: 0 0 5px #ffcc00, 0 0 15px #ffcc00, 0 0 25px #ffcc00;
- }
- 60% {
- text-shadow: 0 0 5px #ffcc00, 0 0 10px #ffcc00, 0 0 15px #ffcc00,
- 0 0 20px #ffcc00, 0 0 30px #ffcc00;
- }
- 80% {
- text-shadow: 0 0 3px #ffcc00, 0 0 7px #ffcc00, 0 0 10px #ffcc00;
- }
- 100% {
- text-shadow: 0 0 5px #ffcc00, 0 0 10px #ffcc00, 0 0 15px #ffcc00,
- 0 0 20px #ffcc00, 0 0 30px #ffcc00, 0 0 40px #ffcc00;
- }
-}
-
-footer {
- background-color: #111;
- color: #b0b0b0;
- text-align: center;
- padding: 1em 0;
- margin-top: 20px;
-}
-
-.grid-container {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 20px;
- padding: 20px;
-}
-
-.item {
- position: relative;
- background-color: #1a1a1a;
- border-radius: 10px;
- overflow: hidden;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.8);
- transition: transform 0.3s ease, box-shadow 0.3s ease, filter 0.3s ease;
- width: 100%;
- height: 400px;
- display: flex;
- flex-direction: column;
-}
-
-.item img {
- width: 100%;
- height: 100%;
- object-fit: cover;
- filter: brightness(0.6);
-}
-
-.item .description {
- padding: 30px;
- font-size: 1rem;
- color: #ccc;
- background-color: rgba(0, 0, 0, 0.8);
- border-radius: 0 0 10px 10px;
- flex-grow: 1;
-}
-
-p {
- text-decoration: none;
-}
-
-.item:hover {
- transform: scale(1.05);
- box-shadow: 0 8px 30px rgba(0, 0, 0, 0.9);
- filter: brightness(1.1);
-}
-
-.item:hover img {
- transform: scale(1.1);
- filter: brightness(1.1);
-}
-
-.item h2 {
- position: absolute;
- top: 10%;
- left: 50%;
- transform: translateX(-50%);
- color: #ffffff;
- font-size: 1.8rem;
- background-color: rgba(0, 0, 0, 0.9);
- padding: 5px 15px;
- border-radius: 5px;
- text-align: center;
- opacity: 0;
- transition: opacity 0.3s ease, transform 0.3s ease;
-}
-
-.item:hover h2 {
- opacity: 1;
- transform: translateX(-50%) translateY(-10px);
-}
-
-@media (max-width: 800px) {
- header {
- font-size: 1.5rem;
- }
-
- .item {
- height: auto;
- width: auto;
- }
-
- .grid-container {
- grid-template-columns: repeat(1, 1fr);
- }
-}
diff --git a/src/favicon/android-chrome-192x192.png b/src/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000..e636383
Binary files /dev/null and b/src/favicon/android-chrome-192x192.png differ
diff --git a/src/favicon/android-chrome-512x512.png b/src/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000..65f6ef4
Binary files /dev/null and b/src/favicon/android-chrome-512x512.png differ
diff --git a/src/favicon/apple-touch-icon.png b/src/favicon/apple-touch-icon.png
new file mode 100644
index 0000000..42de221
Binary files /dev/null and b/src/favicon/apple-touch-icon.png differ
diff --git a/src/favicon/favicon-16x16.png b/src/favicon/favicon-16x16.png
new file mode 100644
index 0000000..e736fae
Binary files /dev/null and b/src/favicon/favicon-16x16.png differ
diff --git a/src/favicon/favicon-32x32.png b/src/favicon/favicon-32x32.png
new file mode 100644
index 0000000..74501cd
Binary files /dev/null and b/src/favicon/favicon-32x32.png differ
diff --git a/src/favicon/favicon.ico b/src/favicon/favicon.ico
new file mode 100644
index 0000000..4de4913
Binary files /dev/null and b/src/favicon/favicon.ico differ
diff --git a/images/Patrick.png b/src/images/Patrick.png
similarity index 100%
rename from images/Patrick.png
rename to src/images/Patrick.png
diff --git a/images/sage.png b/src/images/sage.png
similarity index 100%
rename from images/sage.png
rename to src/images/sage.png
diff --git a/src/js/animation/Meteor.js b/src/js/animation/Meteor.js
new file mode 100644
index 0000000..a141e80
--- /dev/null
+++ b/src/js/animation/Meteor.js
@@ -0,0 +1,311 @@
+class Meteor {
+ constructor(container) {
+ this.element = document.createElement("div");
+ this.element.style.position = "absolute";
+ this.container = container;
+ this.speed = Math.random() * 3 + 4;
+ this.life = 1.0;
+ this.particles = [];
+
+ this.colorType = Math.floor(Math.random() * 4);
+ this.colors = this.getMeteorColors();
+
+ this.containerRect = container.getBoundingClientRect();
+
+ // Start from random edge with PIXEL-based positioning
+ const edge = Math.floor(Math.random() * 4);
+ switch (edge) {
+ case 0:
+ // Top
+ this.x = Math.random() * this.containerRect.width;
+ this.y = -20;
+ case 1:
+ // Right
+ this.x = this.containerRect.width + 20;
+ this.y = Math.random() * this.containerRect.height;
+ case 2:
+ // Bottom
+ this.x = Math.random() * this.containerRect.width;
+ this.y = this.containerRect.height + 20;
+ case 3:
+ // Left
+ this.x = -20;
+ this.y = Math.random() * this.containerRect.height;
+ default:
+ console.log("Error creating Meteor direction");
+ }
+
+ const centerX = this.containerRect.width / 2 + (Math.random() - 0.5) * 200;
+ const centerY = this.containerRect.height / 2 + (Math.random() - 0.5) * 200;
+ this.angle =
+ Math.atan2(centerY - this.y, centerX - this.x) +
+ (Math.random() - 0.5) * 0.8;
+ this.dx = Math.cos(this.angle) * this.speed;
+ this.dy = Math.sin(this.angle) * this.speed;
+
+ this.init();
+ }
+
+ getMeteorColors() {
+ const colorSchemes = [
+ {
+ head: "rgba(255, 255, 255, 1)",
+ core: "rgba(255, 230, 150, 0.9)",
+ mid: "rgba(255, 180, 80, 0.7)",
+ outer: "rgba(255, 100, 50, 0.5)",
+ glow: "rgba(255, 200, 100, 0.9)",
+ },
+ {
+ head: "rgba(255, 255, 255, 1)",
+ core: "rgba(180, 220, 255, 0.9)",
+ mid: "rgba(100, 180, 255, 0.7)",
+ outer: "rgba(50, 100, 255, 0.5)",
+ glow: "rgba(100, 180, 255, 0.9)",
+ },
+ {
+ head: "rgba(255, 255, 255, 1)",
+ core: "rgba(220, 180, 255, 0.9)",
+ mid: "rgba(200, 100, 255, 0.7)",
+ outer: "rgba(180, 50, 255, 0.5)",
+ glow: "rgba(200, 150, 255, 0.9)",
+ },
+ {
+ head: "rgba(255, 255, 255, 1)",
+ core: "rgba(180, 255, 200, 0.9)",
+ mid: "rgba(80, 255, 150, 0.7)",
+ outer: "rgba(50, 200, 100, 0.5)",
+ glow: "rgba(150, 255, 180, 0.9)",
+ },
+ ];
+ return colorSchemes[this.colorType];
+ }
+
+ init() {
+ const size = Math.random() * 4 + 10;
+ const colors = this.colors;
+
+ const head = document.createElement("div");
+ head.style.width = `${size}px`;
+ head.style.height = `${size}px`;
+ head.style.borderRadius = "50%";
+ head.style.background = `
+ radial-gradient(
+ circle at 30% 30%,
+ ${colors.head} 0%,
+ ${colors.core} 30%,
+ ${colors.mid} 60%,
+ ${colors.outer} 100%
+ )
+ `;
+ head.style.boxShadow = `
+ 0 0 ${size * 4}px ${colors.glow},
+ 0 0 ${size * 2}px rgba(255, 255, 255, 0.8),
+ inset 0 0 ${size * 0.5}px rgba(255, 255, 255, 0.9)
+ `;
+ head.style.position = "absolute";
+ head.style.left = "50%";
+ head.style.top = "50%";
+ head.style.transform = "translate(-50%, -50%)";
+ head.style.zIndex = "3";
+ head.style.filter = "blur(0.5px)";
+
+ // Create multi-layer tail
+ this.createTailLayer(size * 3, size * 1.2, colors.core, 1, "1px");
+ this.createTailLayer(size * 5, size * 2, colors.mid, 0.6, "2px");
+ this.createTailLayer(size * 8, size * 3, colors.outer, 0.3, "3px");
+
+ // Assemble meteor
+ this.element.appendChild(head);
+ this.element.style.left = `${this.x}px`;
+ this.element.style.top = `${this.y}px`;
+ this.element.style.zIndex = "10";
+ this.element.style.filter = "blur(0.5px)";
+
+ this.head = head;
+ this.size = size;
+
+ this.container.appendChild(this.element);
+
+ this.createTrailParticles();
+ }
+
+ createTailLayer(length, width, color, opacity, blur) {
+ const tail = document.createElement("div");
+ const tailAngle = Math.atan2(this.dy, this.dx) + Math.PI;
+
+ tail.style.width = `${length}px`;
+ tail.style.height = `${width}px`;
+ tail.style.position = "absolute";
+ tail.style.left = "50%";
+ tail.style.top = "50%";
+ tail.style.transformOrigin = "left center";
+ tail.style.transform = `translate(0, -50%) rotate(${tailAngle}rad)`;
+ tail.style.background = `linear-gradient(to right,
+ ${color} 0%,
+ ${color.replace(")", ", 0.8)").replace("rgba", "rgba")} 20%,
+ ${color.replace(")", ", 0.4)").replace("rgba", "rgba")} 50%,
+ ${color.replace(")", ", 0.1)").replace("rgba", "rgba")} 80%,
+ transparent 100%)`;
+ tail.style.opacity = opacity;
+ tail.style.filter = `blur(${blur})`;
+ tail.style.pointerEvents = "none";
+ tail.style.zIndex = "2";
+ tail.style.borderRadius = "0 50% 50% 0";
+
+ this.element.appendChild(tail);
+ this.tail = tail;
+ }
+
+ createTrailParticles() {
+ for (let i = 0; i < 5; i++) {
+ this.addTrailParticle();
+ }
+ }
+
+ addTrailParticle() {
+ const particle = document.createElement("div");
+ const size = Math.random() * 2 + 1;
+ const colors = this.colors;
+
+ particle.style.width = `${size}px`;
+ particle.style.height = `${size}px`;
+ particle.style.borderRadius = "50%";
+ particle.style.background = colors.mid;
+ particle.style.position = "absolute";
+ particle.style.left = `${this.x}px`;
+ particle.style.top = `${this.y}px`;
+ particle.style.boxShadow = `0 0 ${size * 3}px ${colors.glow}`;
+ particle.style.opacity = "0.7";
+ particle.style.zIndex = "1";
+ particle.style.pointerEvents = "none";
+
+ this.container.appendChild(particle);
+
+ this.particles.push({
+ element: particle,
+ life: 1.0,
+ x: this.x,
+ y: this.y,
+ vx: (Math.random() - 0.5) * 0.5,
+ vy: (Math.random() - 0.5) * 0.5,
+ size: size,
+ });
+ }
+
+ update() {
+ this.x += this.dx;
+ this.y += this.dy;
+ this.life -= 0.005;
+
+ this.element.style.left = `${this.x}px`;
+ this.element.style.top = `${this.y}px`;
+ this.element.style.opacity = this.life;
+
+ // Update tail direction
+ const tailAngle = Math.atan2(this.dy, this.dx) + Math.PI;
+ const tails = this.element.querySelectorAll("div:not(.particle)");
+ tails.forEach((tail) => {
+ if (tail !== this.head) {
+ tail.style.transform = `translate(0, -50%) rotate(${tailAngle}rad)`;
+ tail.style.opacity = this.life;
+ }
+ });
+
+ if (Math.random() < 0.3) {
+ this.addTrailParticle();
+ }
+
+ // Update existing particles with pixel positioning
+ for (let i = this.particles.length - 1; i >= 0; i--) {
+ const p = this.particles[i];
+ p.life -= 0.02;
+ p.x += p.vx;
+ p.y += p.vy;
+
+ p.element.style.left = `${p.x}px`;
+ p.element.style.top = `${p.y}px`;
+ p.element.style.opacity = p.life;
+ p.element.style.transform = `scale(${p.life})`;
+
+ if (p.life <= 0) {
+ p.element.remove();
+ this.particles.splice(i, 1);
+ }
+ }
+
+ if (
+ this.x < -50 ||
+ this.x > this.containerRect.width + 50 ||
+ this.y < -50 ||
+ this.y > this.containerRect.height + 50 ||
+ this.life <= 0
+ ) {
+ // Fade out particles
+ this.particles.forEach((p) => {
+ p.element.style.transition = "opacity 0.5s";
+ p.element.style.opacity = "0";
+ setTimeout(() => p.element.remove(), 500);
+ });
+ this.remove();
+ return false;
+ }
+ return true;
+ }
+
+ remove() {
+ if (this.life > 0.3) {
+ this.createExplosion();
+ }
+
+ setTimeout(() => {
+ this.element.remove();
+ }, 300);
+ }
+
+ createExplosion() {
+ for (let i = 0; i < 8; i++) {
+ const particle = document.createElement("div");
+ const size = Math.random() * 3 + 2;
+ const colors = this.colors;
+
+ particle.style.width = `${size}px`;
+ particle.style.height = `${size}px`;
+ particle.style.borderRadius = "50%";
+ particle.style.background = colors.core;
+ particle.style.position = "absolute";
+ particle.style.left = `${this.x}px`;
+ particle.style.top = `${this.y}px`;
+ particle.style.boxShadow = `0 0 ${size * 4}px ${colors.glow}`;
+ particle.style.opacity = "0.8";
+ particle.style.zIndex = "2";
+
+ this.container.appendChild(particle);
+
+ // Animate explosion
+ const angle = (i / 8) * Math.PI * 2;
+ const distance = Math.random() * 20 + 10;
+ const duration = Math.random() * 500 + 500;
+
+ particle.animate(
+ [
+ {
+ transform: "translate(0, 0) scale(1)",
+ opacity: 0.8,
+ },
+ {
+ transform: `translate(${Math.cos(angle) * distance}px, ${
+ Math.sin(angle) * distance
+ }px) scale(0.1)`,
+ opacity: 0,
+ },
+ ],
+ {
+ duration: duration,
+ easing: "cubic-bezier(0.4, 0, 0.2, 1)",
+ }
+ ).onfinish = () => particle.remove();
+ }
+ }
+}
+
+export default Meteor;
diff --git a/src/js/animation/Star.js b/src/js/animation/Star.js
new file mode 100644
index 0000000..53b21f2
--- /dev/null
+++ b/src/js/animation/Star.js
@@ -0,0 +1,63 @@
+class Star {
+ constructor(container) {
+ this.element = document.createElement("div");
+ this.element.classList.add("star");
+ this.container = container;
+ this.speed = Math.random() * 0.5 + 0.1;
+
+ // Random direction angle (0 to 360 degrees)
+ this.angle = Math.random() * Math.PI * 2;
+ this.dx = Math.cos(this.angle) * this.speed;
+ this.dy = Math.sin(this.angle) * this.speed;
+
+ this.x = Math.random() * 100;
+ this.y = Math.random() * 100;
+
+ this.color = this.getRandomStarColor();
+ this.init();
+ }
+
+ getRandomStarColor() {
+ const colors = [
+ "rgba(255, 255, 255, 0.9)", // Pure white
+ "rgba(255, 250, 200, 0.9)", // Warm white
+ "rgba(200, 220, 255, 0.9)", // Cool blue-white
+ "rgba(255, 220, 180, 0.9)", // Yellow-white
+ "rgba(180, 200, 255, 0.9)", // Blue-white
+ ];
+ return colors[Math.floor(Math.random() * colors.length)];
+ }
+
+ init() {
+ const size = Math.random() * 3 + 0.5;
+ this.element.style.width = `${size}px`;
+ this.element.style.height = `${size}px`;
+ this.element.style.left = `${this.x}%`;
+ this.element.style.top = `${this.y}%`;
+ this.element.style.background = this.color;
+ this.element.style.boxShadow = `0 0 ${size * 2}px ${this.color}`;
+ this.element.style.animationDelay = `${Math.random() * 5}s`;
+ this.element.style.animationDuration = `${3 + Math.random() * 4}s`;
+ this.container.appendChild(this.element);
+ }
+
+ update() {
+ this.x += this.dx * 0.05;
+ this.y += this.dy * 0.05;
+
+ // Wrap around when star goes off screen
+ if (this.y > 100) this.y = 0;
+ if (this.y < 0) this.y = 100;
+ if (this.x > 100) this.x = 0;
+ if (this.x < 0) this.x = 100;
+
+ this.element.style.left = `${this.x}%`;
+ this.element.style.top = `${this.y}%`;
+ }
+
+ remove() {
+ this.element.remove();
+ }
+}
+
+export default Star;
diff --git a/src/js/animation/starBackground.js b/src/js/animation/starBackground.js
new file mode 100644
index 0000000..42b0d0d
--- /dev/null
+++ b/src/js/animation/starBackground.js
@@ -0,0 +1,81 @@
+import Star from "./Star.js";
+import Meteor from "./Meteor.js";
+
+const starInstances = [];
+const meteorInstances = [];
+
+function createStars() {
+ const stars = document.getElementById("stars");
+ const count = 400;
+ stars.innerHTML = "";
+ starInstances.length = 0;
+
+ for (let i = 0; i < count; i++) {
+ const star = new Star(stars);
+ starInstances.push(star);
+ }
+}
+
+function injectStarCSS() {
+ const style = document.createElement("style");
+ style.textContent = `
+ .star {
+ position: absolute;
+ border-radius: 50%;
+ animation: twinkle ease-in-out infinite;
+ }
+
+ @keyframes twinkle {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.3; }
+ }
+ `;
+ document.head.appendChild(style);
+}
+
+function trySpawnMeteor() {
+ const spawnChance = 0.12;
+ if (Math.random() < spawnChance) {
+ const stars = document.getElementById("stars");
+ const newMeteor = new Meteor(stars);
+ meteorInstances.push(newMeteor);
+ }
+}
+
+function animateStars() {
+ starInstances.forEach((star) => star.update());
+
+ // Update meteors and remove dead ones
+ for (let i = meteorInstances.length - 1; i >= 0; i--) {
+ if (!meteorInstances[i].update()) {
+ meteorInstances.splice(i, 1);
+ }
+ }
+
+ requestAnimationFrame(animateStars);
+}
+
+function createMeteorBurst() {
+ for (let i = 0; i < 3; i++) {
+ setTimeout(() => {
+ const stars = document.getElementById("stars");
+ const newMeteor = new Meteor(stars);
+ meteorInstances.push(newMeteor);
+ }, i * 200);
+ }
+}
+
+function init() {
+ injectStarCSS();
+ createStars();
+ animateStars();
+
+ setInterval(trySpawnMeteor, 2000);
+ setInterval(createMeteorBurst, 15000);
+}
+
+if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", init);
+} else {
+ init();
+}
diff --git a/src/js/form.js b/src/js/form.js
new file mode 100644
index 0000000..4dbfa2e
--- /dev/null
+++ b/src/js/form.js
@@ -0,0 +1,22 @@
+// Form submission
+function setupForm() {
+ const form = document.getElementById("contact-form");
+ if (form) {
+ form.addEventListener("submit", function (e) {
+ e.preventDefault();
+
+ // Simple form validation
+ const name = document.getElementById("name").value;
+ const email = document.getElementById("email").value;
+ const message = document.getElementById("message").value;
+
+ if (name && email && message) {
+ // In a real implementation, you would send the form data to a server
+ alert("Thank you for your message! We will get back to you soon.");
+ form.reset();
+ } else {
+ alert("Please fill in all required fields.");
+ }
+ });
+ }
+}
diff --git a/src/js/main.js b/src/js/main.js
new file mode 100644
index 0000000..bd2f14a
--- /dev/null
+++ b/src/js/main.js
@@ -0,0 +1,27 @@
+// Initialize everything when DOM is loaded
+document.addEventListener("DOMContentLoaded", function () {
+ // Initialize components
+ if (typeof createStars === "function") createStars();
+ if (typeof updateNavigation === "function") updateNavigation();
+ if (typeof setupForm === "function") setupForm();
+ if (typeof setupMobileNavigation === "function") setupMobileNavigation();
+
+ // Set up event listeners
+ window.addEventListener("scroll", updateNavigation);
+
+ // Smooth scrolling for navigation links
+ document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
+ anchor.addEventListener("click", function (e) {
+ e.preventDefault();
+ const targetId = this.getAttribute("href");
+ if (targetId === "#") return;
+
+ const targetElement = document.querySelector(targetId);
+ if (targetElement) {
+ targetElement.scrollIntoView({
+ behavior: "smooth",
+ });
+ }
+ });
+ });
+});
diff --git a/src/js/navigation.js b/src/js/navigation.js
new file mode 100644
index 0000000..974476d
--- /dev/null
+++ b/src/js/navigation.js
@@ -0,0 +1,106 @@
+// Navigation JavaScript
+let lastScrollY = window.scrollY;
+let ticking = false;
+
+function updateNavigation() {
+ const navigation = document.getElementById("navigation");
+ const scrolled = window.scrollY > 50;
+
+ if (scrolled) {
+ navigation.classList.add("scrolled");
+
+ // Hide/show nav on scroll
+ if (window.scrollY > lastScrollY && window.scrollY > 100) {
+ navigation.classList.add("hidden");
+ } else {
+ navigation.classList.remove("hidden");
+ }
+ } else {
+ navigation.classList.remove("scrolled", "hidden");
+ }
+
+ lastScrollY = window.scrollY;
+ ticking = false;
+}
+
+function requestTick() {
+ if (!ticking) {
+ requestAnimationFrame(updateNavigation);
+ ticking = true;
+ }
+}
+
+// Mobile navigation functionality
+function setupMobileNavigation() {
+ const burgerMenu = document.getElementById("burger-menu");
+ const mainNav = document.getElementById("main-nav");
+ const body = document.body;
+
+ // Create overlay for mobile menu
+ const overlay = document.createElement("div");
+ overlay.className = "nav-overlay";
+ document.body.appendChild(overlay);
+
+ if (burgerMenu && mainNav) {
+ burgerMenu.addEventListener("click", function () {
+ const isActive = mainNav.classList.contains("active");
+
+ if (isActive) {
+ // Close menu
+ mainNav.classList.remove("active");
+ burgerMenu.classList.remove("active");
+ overlay.classList.remove("active");
+ body.classList.remove("nav-open");
+ } else {
+ // Open menu
+ mainNav.classList.add("active");
+ burgerMenu.classList.add("active");
+ overlay.classList.add("active");
+ body.classList.add("nav-open");
+ }
+ });
+
+ // Close menu when clicking on overlay
+ overlay.addEventListener("click", function () {
+ mainNav.classList.remove("active");
+ burgerMenu.classList.remove("active");
+ overlay.classList.remove("active");
+ body.classList.remove("nav-open");
+ });
+
+ // Close menu when clicking on a link
+ const navLinks = mainNav.querySelectorAll("a");
+ navLinks.forEach((link) => {
+ link.addEventListener("click", function () {
+ mainNav.classList.remove("active");
+ burgerMenu.classList.remove("active");
+ overlay.classList.remove("active");
+ body.classList.remove("nav-open");
+
+ // Update active state
+ navLinks.forEach((l) => l.classList.remove("active"));
+ this.classList.add("active");
+ });
+ });
+
+ // Set initial active state based on current hash
+ function setActiveNavLink() {
+ const currentHash = window.location.hash || "#home";
+ navLinks.forEach((link) => {
+ if (link.getAttribute("href") === currentHash) {
+ link.classList.add("active");
+ } else {
+ link.classList.remove("active");
+ }
+ });
+ }
+
+ // Update active state on hash change
+ window.addEventListener("hashchange", setActiveNavLink);
+ setActiveNavLink();
+ }
+}
+
+// Initialize navigation
+window.addEventListener("scroll", requestTick);
+window.addEventListener("load", updateNavigation);
diff --git a/src/js/overview.js b/src/js/overview.js
new file mode 100644
index 0000000..9dd7bf2
--- /dev/null
+++ b/src/js/overview.js
@@ -0,0 +1,57 @@
+// Counter animation for stats
+document.addEventListener("DOMContentLoaded", function () {
+ const counters = document.querySelectorAll(".stat-number");
+ let hasCounted = false;
+
+ function animateCounters() {
+ if (hasCounted) return;
+
+ counters.forEach((counter) => {
+ const target = parseInt(counter.getAttribute("data-count"));
+ const duration = 2000; // 2 seconds
+ const frameDuration = 1000 / 60; // 60 frames per second
+ const totalFrames = Math.round(duration / frameDuration);
+ let frame = 0;
+
+ const counterInterval = setInterval(() => {
+ frame++;
+ const progress = frame / totalFrames;
+ const currentCount = Math.round(target * progress);
+
+ counter.textContent = currentCount;
+
+ if (frame === totalFrames) {
+ clearInterval(counterInterval);
+ }
+ }, frameDuration);
+
+ counter.classList.add("animated");
+ });
+
+ hasCounted = true;
+ }
+
+ // Check if element is in viewport
+ function isInViewport(element) {
+ const rect = element.getBoundingClientRect();
+ return (
+ rect.top >= 0 &&
+ rect.left >= 0 &&
+ rect.bottom <=
+ (window.innerHeight || document.documentElement.clientHeight) &&
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+ );
+ }
+
+ // Check on scroll and on load
+ function checkCounters() {
+ const statsContainer = document.querySelector(".stats-container");
+ if (statsContainer && isInViewport(statsContainer)) {
+ animateCounters();
+ window.removeEventListener("scroll", checkCounters);
+ }
+ }
+
+ window.addEventListener("scroll", checkCounters);
+ checkCounters(); // Check on page load
+});
diff --git a/src/js/portfolioCard.js b/src/js/portfolioCard.js
new file mode 100644
index 0000000..2fd2d79
--- /dev/null
+++ b/src/js/portfolioCard.js
@@ -0,0 +1,228 @@
+class PortfolioCard extends HTMLElement {
+ constructor() {
+ super();
+ const shadow = this.attachShadow({ mode: "open" });
+
+ const icon = this.getAttribute("icon") || "fas fa-code";
+ const title = this.getAttribute("title") || "Project Title";
+ const desc = this.getAttribute("desc") || "Project description goes here.";
+ const tags = (this.getAttribute("tags") || "").split(",");
+ const link = this.getAttribute("link") || "#";
+ const collaboration = this.getAttribute("collaboration") || "";
+
+ shadow.innerHTML = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${title}
+
+
${desc}
+ ${
+ collaboration
+ ? `
+
+ ${collaboration}
+
+ `
+ : ""
+ }
+
+ ${tags
+ .map((tag) => `${tag.trim()} `)
+ .join("")}
+
+
+
+
+ `;
+ }
+}
+
+customElements.define("portfolio-card", PortfolioCard);
diff --git a/src/js/portfolioFilter.js b/src/js/portfolioFilter.js
new file mode 100644
index 0000000..7779c87
--- /dev/null
+++ b/src/js/portfolioFilter.js
@@ -0,0 +1,95 @@
+// Portfolio filtering functionality
+document.addEventListener("DOMContentLoaded", function () {
+ // Get all portfolio items
+ const portfolioItems = document.querySelectorAll("portfolio-card");
+ const filterButtons = document.querySelectorAll(".filter-btn");
+ const searchInput = document.getElementById("project-search");
+
+ // Create a container for no results message
+ const noResults = document.createElement("div");
+ noResults.className = "no-results";
+ noResults.innerHTML = `
+
+
No projects found
+
Try adjusting your search or filter criteria
+ `;
+
+ // Function to filter portfolio items
+ function filterPortfolio() {
+ const activeFilter =
+ document.querySelector(".filter-btn.active").dataset.filter;
+ const searchTerm = searchInput.value.toLowerCase();
+ let visibleItems = 0;
+
+ portfolioItems.forEach((item) => {
+ const tags = item.getAttribute("tags").toLowerCase();
+ const title = item.getAttribute("title").toLowerCase();
+ const desc = item.getAttribute("desc").toLowerCase();
+
+ // Check if item matches the active filter
+ const matchesFilter =
+ activeFilter === "all" ||
+ tags.includes(activeFilter) ||
+ title.includes(activeFilter) ||
+ desc.includes(activeFilter);
+
+ // Check if item matches the search term
+ const matchesSearch =
+ searchTerm === "" ||
+ title.includes(searchTerm) ||
+ desc.includes(searchTerm) ||
+ tags.includes(searchTerm);
+
+ // Show or hide the item based on filters
+ if (matchesFilter && matchesSearch) {
+ item.style.display = "block";
+ visibleItems++;
+
+ // Add animation for appearing items
+ item.style.animation = "fadeInUp 0.5s ease forwards";
+ } else {
+ item.style.display = "none";
+ }
+ });
+
+ // Show no results message if needed
+ const portfolioGrid = document.querySelector(".portfolio-grid");
+ const existingNoResults = portfolioGrid.querySelector(".no-results");
+
+ if (visibleItems === 0) {
+ if (!existingNoResults) {
+ portfolioGrid.appendChild(noResults);
+ }
+ } else if (existingNoResults) {
+ portfolioGrid.removeChild(existingNoResults);
+ }
+ }
+
+ // Add click event listeners to filter buttons
+ filterButtons.forEach((button) => {
+ button.addEventListener("click", function () {
+ // Remove active class from all buttons
+ filterButtons.forEach((btn) => btn.classList.remove("active"));
+
+ // Add active class to clicked button
+ this.classList.add("active");
+
+ // Filter portfolio items
+ filterPortfolio();
+ });
+ });
+
+ // Add input event listener to search field
+ searchInput.addEventListener("input", filterPortfolio);
+
+ // Add keyboard shortcut for search (Ctrl/Cmd + F)
+ document.addEventListener("keydown", function (e) {
+ if ((e.ctrlKey || e.metaKey) && e.key === "f") {
+ e.preventDefault();
+ searchInput.focus();
+ }
+ });
+
+ // Initialize filter on page load
+ filterPortfolio();
+});
diff --git a/src/js/sectionTracker.js b/src/js/sectionTracker.js
new file mode 100644
index 0000000..e392724
--- /dev/null
+++ b/src/js/sectionTracker.js
@@ -0,0 +1,111 @@
+// Section tracking and navigation highlighting
+document.addEventListener("DOMContentLoaded", function () {
+ const sections = document.querySelectorAll("section[id]");
+ const navLinks = document.querySelectorAll(".nav-links a");
+
+ // Configuration
+ const offset = 100; // Offset for when section becomes "active" (accounts for fixed nav)
+ let isScrolling = false;
+
+ function getCurrentSection() {
+ let currentSection = "";
+ const scrollPosition = window.scrollY + offset;
+
+ // Find which section we're currently in
+ sections.forEach((section) => {
+ const sectionTop = section.offsetTop;
+ const sectionHeight = section.offsetHeight;
+ const sectionId = section.getAttribute("id");
+
+ if (
+ scrollPosition >= sectionTop &&
+ scrollPosition < sectionTop + sectionHeight
+ ) {
+ currentSection = sectionId;
+ }
+ });
+
+ // Special case: if we're at the very top, activate the first section
+ if (window.scrollY < 100) {
+ currentSection = sections[0]?.getAttribute("id") || "";
+ }
+
+ return currentSection;
+ }
+
+ function updateActiveNavLink() {
+ const currentSection = getCurrentSection();
+
+ navLinks.forEach((link) => {
+ const href = link.getAttribute("href");
+
+ // Remove active class from all links
+ link.classList.remove("active");
+
+ // Add active class to matching link
+ if (href === `#${currentSection}`) {
+ link.classList.add("active");
+ }
+ });
+ }
+
+ // Throttle scroll events for better performance
+ function handleScroll() {
+ if (!isScrolling) {
+ window.requestAnimationFrame(() => {
+ updateActiveNavLink();
+ isScrolling = false;
+ });
+ isScrolling = true;
+ }
+ }
+
+ // Listen for scroll events
+ window.addEventListener("scroll", handleScroll);
+
+ // Update on page load
+ updateActiveNavLink();
+
+ // Also update when clicking nav links (for smooth scroll)
+ navLinks.forEach((link) => {
+ link.addEventListener("click", function (e) {
+ // Remove active from all
+ navLinks.forEach((l) => l.classList.remove("active"));
+ // Add active to clicked link
+ this.classList.add("active");
+
+ // Let the scroll handler update it properly after scroll completes
+ setTimeout(updateActiveNavLink, 100);
+ });
+ });
+
+ // Handle hash changes (browser back/forward)
+ window.addEventListener("hashchange", function () {
+ setTimeout(updateActiveNavLink, 100);
+ });
+
+ // Intersection Observer for more precise tracking (progressive enhancement)
+ if ("IntersectionObserver" in window) {
+ const observerOptions = {
+ rootMargin: "-20% 0px -70% 0px", // Trigger when section is roughly in the middle of viewport
+ threshold: 0,
+ };
+
+ const observer = new IntersectionObserver((entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ const sectionId = entry.target.getAttribute("id");
+ navLinks.forEach((link) => {
+ link.classList.remove("active");
+ if (link.getAttribute("href") === `#${sectionId}`) {
+ link.classList.add("active");
+ }
+ });
+ }
+ });
+ }, observerOptions);
+
+ // Observe all sections
+ sections.forEach((section) => observer.observe(section));
+ }
+});
diff --git a/src/styles/styles.css b/src/styles/styles.css
new file mode 100644
index 0000000..3229eb9
--- /dev/null
+++ b/src/styles/styles.css
@@ -0,0 +1,1943 @@
+/* Modern CSS Reset and Variables */
+:root {
+ /* Color System */
+ --bg-primary: #0a0a0a;
+ --bg-secondary: #111111;
+ --bg-tertiary: #1a1a1a;
+ --bg-card: #161616;
+ --bg-card-hover: #1e1e1e;
+
+ --text-primary: #ffffff;
+ --text-secondary: #b3b3b3;
+ --text-muted: #737373;
+
+ --accent-primary: #00f5ff;
+ --accent-secondary: #7c3aed;
+ --accent-gradient: linear-gradient(135deg, #00f5ff, #7c3aed);
+ --accent-gradient-reverse: linear-gradient(135deg, #7c3aed, #00f5ff);
+
+ --purple: #8b5cf6;
+ --purple-light: #a78bfa;
+ --purple-dark: #7c3aed;
+ --purple-muted: #6d28d9;
+ --shadow-purple: rgba(139, 92, 246, 0.3);
+
+ --border-subtle: #262626;
+ --border-accent: #333333;
+
+ /* Shadows */
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);
+ --shadow-glow: 0 0 20px rgba(0, 245, 255, 0.1);
+
+ /* Border Radius */
+ --radius-sm: 8px;
+ --radius-md: 12px;
+ --radius-lg: 16px;
+ --radius-xl: 24px;
+
+ /* Spacing */
+ --spacing-xs: 0.5rem;
+ --spacing-sm: 1rem;
+ --spacing-md: 1.5rem;
+ --spacing-lg: 2rem;
+ --spacing-xl: 3rem;
+ --spacing-2xl: 4rem;
+
+ /* Typography */
+ --font-primary: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
+ --font-mono: "JetBrains Mono", "Fira Code", Consolas, monospace;
+
+ /* Z-Index Scale */
+ --z-navigation: 1000;
+ --z-modal: 1100;
+ --z-tooltip: 1200;
+}
+
+/* Reset */
+*,
+*::before,
+*::after {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+ font-size: 16px;
+}
+
+body {
+ font-family: var(--font-primary);
+ background: var(--bg-primary);
+ color: var(--text-primary);
+ line-height: 1.6;
+ overflow-x: hidden;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body.nav-open {
+ overflow: hidden;
+}
+
+/* Links */
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+/* Lists */
+ul,
+ol {
+ list-style: none;
+}
+
+/* Images */
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Focus States */
+*:focus {
+ outline: 2px solid var(--accent-primary);
+ outline-offset: 2px;
+}
+
+/* Enhanced Background Effects */
+.animated-bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: -2;
+ background: radial-gradient(
+ circle at 20% 50%,
+ rgba(124, 58, 237, 0.15) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ circle at 80% 20%,
+ rgba(0, 245, 255, 0.12) 0%,
+ transparent 50%
+ ),
+ radial-gradient(
+ circle at 40% 80%,
+ rgba(124, 58, 237, 0.1) 0%,
+ transparent 50%
+ );
+ animation: gradientShift 15s ease infinite;
+}
+
+@keyframes gradientShift {
+ 0%,
+ 100% {
+ background-position: 0% 50%, 100% 50%, 50% 100%;
+ }
+ 50% {
+ background-position: 100% 50%, 0% 50%, 50% 0%;
+ }
+}
+
+.stars {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: -1;
+}
+
+.star {
+ position: absolute;
+ background: rgba(255, 255, 255, 0.8);
+ border-radius: 50%;
+ animation: twinkle 3s infinite ease-in-out;
+}
+
+@keyframes twinkle {
+ 0%,
+ 100% {
+ opacity: 0.3;
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 1;
+ transform: scale(1.2);
+ }
+}
+
+/* Enhanced Navigation with Fixed Background Animations */
+nav {
+ position: fixed;
+ top: 0;
+ width: 100%;
+ background: rgba(10, 10, 10, 0.95);
+ backdrop-filter: blur(20px) saturate(180%);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
+ z-index: var(--z-navigation);
+ transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ transform: translateY(0);
+}
+
+/* Hide nav on scroll down, show on scroll up */
+nav.hidden {
+ transform: translateY(-100%);
+}
+
+nav.scrolled {
+ background: rgba(10, 10, 10, 0.98);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ border-bottom-color: rgba(124, 58, 237, 0.2);
+}
+
+.nav-container {
+ max-width: 1400px;
+ margin: 0 auto;
+ padding: 0 var(--spacing-lg);
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 70px;
+}
+
+.logo {
+ font-weight: 800;
+ font-size: 1.5rem;
+ background: var(--accent-gradient);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ position: relative;
+ padding: var(--spacing-xs) 0;
+}
+
+.logo::after {
+ content: "";
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 0;
+ height: 2px;
+ background: var(--accent-gradient);
+ transition: width 0.3s ease;
+}
+
+.logo:hover::after {
+ width: 100%;
+}
+
+.nav-links {
+ display: flex;
+ gap: var(--spacing-md);
+ align-items: center;
+}
+
+.nav-links a {
+ color: var(--text-secondary);
+ font-weight: 500;
+ font-size: 0.9rem;
+ padding: var(--spacing-sm) var(--spacing-md);
+ border-radius: var(--radius-md);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ position: relative;
+ overflow: hidden;
+}
+
+/* Fixed background animation - only shows on hover */
+.nav-links a::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ z-index: -1;
+ border-radius: var(--radius-md);
+}
+
+.nav-links a:hover::before {
+ opacity: 0.1;
+}
+
+/* Underline animation */
+.nav-links a::after {
+ content: "";
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 0;
+ height: 2px;
+ background: var(--accent-primary);
+ transition: width 0.3s ease;
+ border-radius: 2px;
+}
+
+.nav-links a:hover {
+ color: var(--accent-primary);
+ transform: translateY(-1px);
+}
+
+.nav-links a:hover::after {
+ width: 80%;
+}
+
+/* Active state */
+.nav-links a.active {
+ color: var(--accent-primary);
+ background: rgba(0, 245, 255, 0.1);
+}
+
+.nav-links a.active::after {
+ width: 80%;
+}
+
+.nav-links a.active::before {
+ opacity: 0.1;
+}
+
+/* Mobile menu button */
+.mobile-menu-btn {
+ display: none;
+ background: none;
+ border: none;
+ color: var(--text-primary);
+ font-size: 1.5rem;
+ cursor: pointer;
+ padding: var(--spacing-sm);
+ border-radius: var(--radius-md);
+ transition: all 0.3s ease;
+ position: relative;
+ z-index: 1001;
+}
+
+.mobile-menu-btn:hover {
+ background: rgba(124, 58, 237, 0.1);
+ color: var(--accent-primary);
+}
+
+.mobile-menu-btn.active {
+ color: var(--accent-primary);
+}
+
+/* Mobile menu styles */
+@media (max-width: 768px) {
+ .mobile-menu-btn {
+ display: block;
+ }
+
+ .nav-links {
+ position: fixed;
+ top: 0;
+ right: -100%;
+ width: 280px;
+ height: 100vh;
+ background: rgba(10, 10, 10, 0.98);
+ backdrop-filter: blur(30px);
+ flex-direction: column;
+ padding: 80px var(--spacing-lg) var(--spacing-lg);
+ transition: right 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ border-left: 1px solid rgba(255, 255, 255, 0.1);
+ box-shadow: -10px 0 30px rgba(0, 0, 0, 0.3);
+ }
+
+ .nav-links.active {
+ right: 0;
+ }
+
+ .nav-links a {
+ width: 100%;
+ text-align: center;
+ padding: var(--spacing-md);
+ font-size: 1.1rem;
+ border-radius: var(--radius-lg);
+ margin-bottom: var(--spacing-xs);
+ }
+
+ .nav-links a::after {
+ display: none;
+ }
+
+ .nav-links a::before {
+ border-radius: var(--radius-lg);
+ }
+
+ /* Overlay for mobile menu */
+ .nav-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(5px);
+ z-index: 999;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.3s ease;
+ }
+
+ .nav-overlay.active {
+ opacity: 1;
+ visibility: visible;
+ }
+}
+
+/* Enhanced scroll behavior */
+.nav-scroll-hide {
+ animation: navHide 0.4s ease forwards;
+}
+
+.nav-scroll-show {
+ animation: navShow 0.4s ease forwards;
+}
+
+@keyframes navHide {
+ from {
+ transform: translateY(0);
+ }
+ to {
+ transform: translateY(-100%);
+ }
+}
+
+@keyframes navShow {
+ from {
+ transform: translateY(-100%);
+ }
+ to {
+ transform: translateY(0);
+ }
+}
+
+/* Container */
+.container {
+ max-width: 1400px;
+ margin: 0 auto;
+ padding: 0 var(--spacing-lg);
+}
+
+/* Enhanced Hero Section */
+.hero {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ padding-top: 80px;
+ position: relative;
+ overflow: hidden;
+}
+
+.hero::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 100%;
+ height: 100%;
+ background: radial-gradient(
+ circle at center,
+ rgba(124, 58, 237, 0.1) 0%,
+ transparent 70%
+ );
+ transform: translate(-50%, -50%);
+ animation: pulse 4s ease-in-out infinite;
+}
+
+@keyframes pulse {
+ 0%,
+ 100% {
+ opacity: 0.5;
+ transform: translate(-50%, -50%) scale(1);
+ }
+ 50% {
+ opacity: 0.8;
+ transform: translate(-50%, -50%) scale(1.1);
+ }
+}
+
+.hero-content {
+ max-width: 800px;
+ margin: 0 auto;
+ text-align: center;
+ padding: var(--spacing-lg) 0;
+ position: relative;
+ z-index: 1;
+}
+
+.hero h1 {
+ font-size: clamp(2.5rem, 6vw, 4rem);
+ font-weight: 800;
+ margin-bottom: var(--spacing-md);
+ line-height: 1.1;
+ letter-spacing: -0.02em;
+ animation: slideUp 1s ease-out;
+}
+
+@keyframes slideUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.hero h1 .highlight {
+ background: var(--accent-gradient);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ position: relative;
+ display: inline-block;
+}
+
+.hero h1 .highlight::after {
+ content: "";
+ position: absolute;
+ bottom: -5px;
+ left: 0;
+ width: 100%;
+ height: 3px;
+ background: var(--accent-gradient);
+ transform: scaleX(0);
+ transform-origin: left;
+ animation: expandLine 1s ease-out 0.5s forwards;
+}
+
+@keyframes expandLine {
+ to {
+ transform: scaleX(1);
+ }
+}
+
+.hero p {
+ font-size: 1.25rem;
+ color: var(--text-secondary);
+ margin-bottom: var(--spacing-xl);
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+ line-height: 1.6;
+ animation: slideUp 1s ease-out 0.2s both;
+}
+
+.hero-buttons {
+ display: flex;
+ gap: var(--spacing-sm);
+ justify-content: center;
+ flex-wrap: wrap;
+ animation: slideUp 1s ease-out 0.4s both;
+}
+
+/* Enhanced Buttons */
+.btn {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--spacing-xs);
+ padding: 0.875rem var(--spacing-lg);
+ border-radius: var(--radius-md);
+ font-weight: 600;
+ font-size: 0.9rem;
+ text-decoration: none;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ border: none;
+ cursor: pointer;
+ position: relative;
+ overflow: hidden;
+}
+
+.btn::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ rgba(255, 255, 255, 0.2),
+ transparent
+ );
+ transition: left 0.5s ease;
+}
+
+.btn:hover::before {
+ left: 100%;
+}
+
+.btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.btn-primary {
+ background: var(--accent-gradient);
+ color: var(--bg-primary);
+ box-shadow: var(--shadow-glow);
+}
+
+.btn-primary:hover:not(:disabled) {
+ transform: translateY(-3px);
+ box-shadow: 0 15px 30px rgba(0, 245, 255, 0.4);
+}
+
+.btn-secondary {
+ background: transparent;
+ color: var(--text-primary);
+ border: 2px solid var(--border-accent);
+ position: relative;
+ overflow: hidden;
+}
+
+.btn-secondary::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ opacity: 0.1;
+ transition: left 0.3s ease;
+ z-index: -1;
+}
+
+.btn-secondary:hover:not(:disabled) {
+ background: var(--bg-card);
+ border-color: var(--accent-primary);
+ transform: translateY(-3px);
+}
+
+.btn-secondary:hover::after {
+ left: 0;
+}
+
+/* Enhanced Sections */
+.section {
+ padding: 8rem 0;
+ position: relative;
+}
+
+.section::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 180deg,
+ transparent 0%,
+ rgba(124, 58, 237, 0.03) 50%,
+ transparent 100%
+ );
+ pointer-events: none;
+}
+
+.section-header {
+ text-align: center;
+ margin-bottom: var(--spacing-2xl);
+ position: relative;
+}
+
+.section-title {
+ font-size: clamp(2rem, 4vw, 3rem);
+ font-weight: 700;
+ margin-bottom: var(--spacing-sm);
+ letter-spacing: -0.02em;
+ position: relative;
+ display: inline-block;
+}
+
+.section-title::after {
+ content: "";
+ position: absolute;
+ bottom: -10px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 60px;
+ height: 3px;
+ background: var(--accent-gradient);
+ border-radius: 2px;
+}
+
+.section-subtitle {
+ font-size: 1.125rem;
+ color: var(--text-secondary);
+ max-width: 600px;
+ margin: 0 auto;
+ line-height: 1.6;
+}
+
+/* Enhanced Portfolio Controls */
+.portfolio-controls {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: var(--spacing-xl);
+ flex-wrap: wrap;
+ gap: var(--spacing-md);
+}
+
+.filter-buttons {
+ display: flex;
+ gap: var(--spacing-sm);
+ flex-wrap: wrap;
+}
+
+.filter-btn {
+ padding: 0.75rem 1.5rem;
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-md);
+ color: var(--text-secondary);
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ position: relative;
+ overflow: hidden;
+}
+
+.filter-btn::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ transition: left 0.3s ease;
+ z-index: -1;
+}
+
+.filter-btn:hover {
+ background: var(--bg-card-hover);
+ color: var(--text-primary);
+ transform: translateY(-2px);
+ border-color: var(--accent-primary);
+}
+
+.filter-btn.active {
+ background: var(--accent-gradient);
+ color: var(--bg-primary);
+ border-color: transparent;
+ box-shadow: var(--shadow-glow);
+}
+
+.search-box {
+ position: relative;
+ max-width: 300px;
+ width: 100%;
+}
+
+.search-box input {
+ width: 100%;
+ padding: 0.75rem 1rem 0.75rem 2.5rem;
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-md);
+ color: var(--text-primary);
+ font-size: 0.95rem;
+ transition: all 0.3s ease;
+}
+
+.search-box input:focus {
+ outline: none;
+ border-color: var(--accent-primary);
+ box-shadow: 0 0 0 3px rgba(0, 245, 255, 0.1);
+ background: var(--bg-card-hover);
+}
+
+.search-box i {
+ position: absolute;
+ left: 1rem;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--text-muted);
+ transition: color 0.3s ease;
+}
+
+.search-box input:focus + i {
+ color: var(--accent-primary);
+}
+
+/* Enhanced Portfolio Grid */
+.portfolio-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
+ gap: var(--spacing-lg);
+}
+
+portfolio-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+ transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ position: relative;
+ display: block;
+ opacity: 0;
+ transform: translateY(30px);
+ animation: fadeInUp 0.6s ease forwards;
+}
+
+@keyframes fadeInUp {
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+portfolio-card::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 3px;
+ background: var(--accent-gradient);
+ transform: scaleX(0);
+ transform-origin: left;
+ transition: transform 0.3s ease;
+}
+
+portfolio-card:hover::before {
+ transform: scaleX(1);
+}
+
+portfolio-card:hover {
+ transform: translateY(-10px) scale(1.02);
+ background: var(--bg-card-hover);
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3), 0 0 30px rgba(0, 245, 255, 0.1);
+ border-color: var(--border-accent);
+}
+
+.portfolio-img {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 120px;
+ background: var(--accent-gradient);
+ font-size: 2.5rem;
+ color: #ffffff;
+ position: relative;
+ overflow: hidden;
+}
+
+.portfolio-img::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ rgba(255, 255, 255, 0.2),
+ transparent
+ );
+ transition: left 0.5s ease;
+}
+
+portfolio-card:hover .portfolio-img::after {
+ left: 100%;
+}
+
+.portfolio-content {
+ padding: var(--spacing-lg);
+}
+
+.portfolio-title {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-sm);
+ font-size: 1.5rem;
+ font-weight: 600;
+ margin-bottom: var(--spacing-sm);
+ color: var(--text-primary);
+}
+
+.portfolio-desc {
+ color: var(--text-secondary);
+ margin-bottom: var(--spacing-md);
+ line-height: 1.6;
+}
+
+.portfolio-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--spacing-xs);
+ margin-bottom: var(--spacing-md);
+}
+
+.tag {
+ padding: 0.25rem 0.75rem;
+ background: rgba(0, 245, 255, 0.1);
+ color: var(--accent-primary);
+ border-radius: var(--radius-sm);
+ font-size: 0.8rem;
+ font-weight: 500;
+ font-family: var(--font-mono);
+ transition: all 0.3s ease;
+}
+
+.tag:hover {
+ background: rgba(0, 245, 255, 0.2);
+ transform: translateY(-1px);
+}
+
+/* Enhanced Portfolio Button */
+.portfolio-btn-container {
+ margin-top: auto;
+ padding: 0 1.5rem 1.5rem;
+}
+
+.portfolio-btn {
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+ z-index: 1;
+ padding: 1rem 1.8rem;
+ border-radius: 8px;
+ font-weight: 600;
+ letter-spacing: 0.5px;
+ text-transform: uppercase;
+ font-size: 0.9rem;
+ transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
+ border: 2px solid transparent;
+ background: linear-gradient(135deg, var(--purple), var(--purple-dark));
+ color: white;
+ box-shadow: 0 4px 15px var(--shadow-purple);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 0.8rem;
+ text-decoration: none;
+ text-align: center;
+}
+
+.portfolio-btn::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, var(--purple-dark), var(--purple-muted));
+ z-index: -1;
+ transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
+ transform: scaleX(0);
+ transform-origin: right;
+}
+
+.portfolio-btn:hover::before {
+ transform: scaleX(1);
+ transform-origin: left;
+}
+
+.portfolio-btn:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 8px 25px rgba(168, 85, 247, 0.4);
+ border-color: var(--purple-light);
+}
+
+.portfolio-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 4px 15px var(--shadow-purple);
+}
+
+.portfolio-btn i {
+ font-size: 1rem;
+ transition: transform 0.3s ease;
+}
+
+.portfolio-btn:hover i {
+ transform: translateX(4px);
+}
+
+.portfolio-btn::after {
+ content: "";
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: linear-gradient(
+ to bottom right,
+ rgba(255, 255, 255, 0.2),
+ rgba(255, 255, 255, 0.1) 20%,
+ rgba(255, 255, 255, 0) 50%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ transform: rotate(30deg) translateY(-150%);
+ transition: transform 0.6s cubic-bezier(0.165, 0.84, 0.44, 1);
+}
+
+.portfolio-btn:hover::after {
+ transform: rotate(30deg) translateY(150%);
+}
+
+.portfolio-btn:focus {
+ outline: 2px solid var(--purple-light);
+ outline-offset: 2px;
+}
+
+/* Enhanced Collaboration Badge */
+.collaboration-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ background: linear-gradient(135deg, #3b82f6, #2563eb);
+ color: white;
+ padding: 0.3rem 0.8rem;
+ border-radius: 20px;
+ font-size: 0.75rem;
+ margin-top: 0.5rem;
+ margin-bottom: 1rem;
+ animation: pulse 2s infinite;
+ position: relative;
+ overflow: hidden;
+}
+
+.collaboration-badge::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ rgba(255, 255, 255, 0.3),
+ transparent
+ );
+ transition: left 0.5s ease;
+}
+
+.collaboration-badge:hover::before {
+ left: 100%;
+}
+
+@keyframes pulse {
+ 0% {
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
+ }
+ 70% {
+ box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
+ }
+ 100% {
+ box-shadow: 0 0 0 0 rgba(59, 130, 246, 0);
+ }
+}
+
+/* Enhanced Stats Section */
+.stats-section {
+ background: var(--bg-secondary);
+ padding: var(--spacing-2xl) 0;
+ position: relative;
+ overflow: hidden;
+}
+
+.stats-section::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(
+ 45deg,
+ transparent 30%,
+ rgba(124, 58, 237, 0.05) 50%,
+ transparent 70%
+ );
+ animation: shimmer 3s ease-in-out infinite;
+}
+
+@keyframes shimmer {
+ 0%,
+ 100% {
+ transform: translateX(-100%);
+ }
+ 50% {
+ transform: translateX(100%);
+ }
+}
+
+.stats-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: var(--spacing-lg);
+ text-align: center;
+ position: relative;
+ z-index: 1;
+}
+
+.stat-item {
+ padding: var(--spacing-lg);
+ position: relative;
+}
+
+.stat-item::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ opacity: 0;
+ border-radius: var(--radius-lg);
+ transition: opacity 0.3s ease;
+ z-index: -1;
+}
+
+.stat-item:hover::before {
+ opacity: 0.05;
+}
+
+.stat-number {
+ font-size: 3rem;
+ font-weight: 800;
+ background: var(--accent-gradient);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ margin-bottom: var(--spacing-sm);
+}
+
+.stat-label {
+ color: var(--text-secondary);
+ font-weight: 500;
+ font-size: 1.1rem;
+}
+
+/* Enhanced Team Section */
+.team-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: var(--spacing-lg);
+ margin-top: var(--spacing-lg);
+}
+
+.team-member {
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-lg);
+ padding: var(--spacing-lg);
+ text-align: center;
+ transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ position: relative;
+ overflow: hidden;
+}
+
+.team-member::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ opacity: 0.05;
+ transition: left 0.3s ease;
+ z-index: -1;
+}
+
+.team-member:hover::before {
+ left: 0;
+}
+
+.team-member:hover {
+ transform: translateY(-8px) scale(1.02);
+ background: var(--bg-card-hover);
+ box-shadow: var(--shadow-xl);
+ border-color: var(--border-accent);
+}
+
+.member-avatar {
+ width: 120px;
+ height: 120px;
+ background: var(--accent-gradient);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 2.5rem;
+ color: #ffffff;
+ margin: 0 auto var(--spacing-md);
+ position: relative;
+ transition: all 0.3s ease;
+}
+
+.team-member:hover .member-avatar {
+ transform: scale(1.1) rotate(5deg);
+}
+
+.member-avatar::after {
+ content: "";
+ position: absolute;
+ inset: 3px;
+ background: var(--bg-card);
+ border-radius: 50%;
+ z-index: 1;
+}
+
+.member-avatar i {
+ z-index: 2;
+ position: relative;
+}
+
+.team-member h3 {
+ font-size: 1.5rem;
+ font-weight: 600;
+ margin-bottom: var(--spacing-xs);
+}
+
+.team-role {
+ color: var(--accent-primary);
+ font-weight: 500;
+ margin-bottom: var(--spacing-sm);
+ font-family: var(--font-mono);
+ font-size: 0.9rem;
+}
+
+.team-member p {
+ color: var(--text-secondary);
+ line-height: 1.6;
+}
+
+/* Enhanced About Section */
+.about-content {
+ max-width: 800px;
+ margin: 0 auto;
+ text-align: center;
+}
+
+.about-content p {
+ font-size: 1.125rem;
+ color: var(--text-secondary);
+ margin-bottom: var(--spacing-lg);
+ line-height: 1.7;
+ text-align: left;
+ position: relative;
+ padding-left: var(--spacing-lg);
+}
+
+.about-content p::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
+ width: 3px;
+ background: var(--accent-gradient);
+ border-radius: 2px;
+ transform: scaleY(0);
+ transition: transform 0.3s ease;
+}
+
+.about-content p:hover::before {
+ transform: scaleY(1);
+}
+
+.about-content p:last-child {
+ margin-bottom: 0;
+}
+
+/* Enhanced Vision Section */
+.vision-content {
+ max-width: 1000px;
+ margin: 0 auto;
+}
+
+.vision-text {
+ text-align: center;
+ margin-bottom: var(--spacing-2xl);
+}
+
+.vision-text p {
+ font-size: 1.125rem;
+ color: var(--text-secondary);
+ line-height: 1.7;
+ max-width: 700px;
+ margin: 0 auto;
+}
+
+.principles-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: var(--spacing-lg);
+}
+
+.principle-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-lg);
+ padding: var(--spacing-lg);
+ text-align: center;
+ transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ position: relative;
+ overflow: hidden;
+}
+
+.principle-card::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ opacity: 0.05;
+ transition: left 0.3s ease;
+ z-index: -1;
+}
+
+.principle-card:hover::before {
+ left: 0;
+}
+
+.principle-card:hover {
+ transform: translateY(-8px) scale(1.02);
+ background: var(--bg-card-hover);
+ box-shadow: var(--shadow-lg);
+ border-color: var(--border-accent);
+}
+
+.principle-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 80px;
+ height: 80px;
+ background: var(--accent-gradient);
+ border-radius: 50%;
+ margin: 0 auto var(--spacing-md);
+ font-size: 1.8rem;
+ color: #ffffff;
+ transition: all 0.3s ease;
+}
+
+.principle-card:hover .principle-icon {
+ transform: scale(1.1) rotate(10deg);
+}
+
+.principle-card h4 {
+ font-size: 1.25rem;
+ font-weight: 600;
+ margin-bottom: var(--spacing-sm);
+ color: var(--text-primary);
+}
+
+.principle-card p {
+ color: var(--text-secondary);
+ line-height: 1.6;
+}
+
+/* Enhanced Contact Section */
+.contact-container {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--spacing-2xl);
+ max-width: 1000px;
+ margin: 0 auto;
+}
+
+.contact-methods {
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacing-lg);
+}
+
+.contact-item {
+ display: flex;
+ align-items: flex-start;
+ gap: var(--spacing-sm);
+ transition: all 0.3s ease;
+ padding: var(--spacing-md);
+ border-radius: var(--radius-lg);
+}
+
+.contact-item:hover {
+ background: var(--bg-card);
+ transform: translateX(10px);
+}
+
+.contact-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 50px;
+ height: 50px;
+ background: var(--accent-gradient);
+ border-radius: var(--radius-md);
+ font-size: 1.2rem;
+ color: #ffffff;
+ flex-shrink: 0;
+ transition: all 0.3s ease;
+}
+
+.contact-item:hover .contact-icon {
+ transform: scale(1.1) rotate(5deg);
+}
+
+.contact-details h4 {
+ font-size: 1.1rem;
+ font-weight: 600;
+ margin-bottom: var(--spacing-xs);
+ color: var(--text-primary);
+}
+
+.contact-details a {
+ color: var(--text-secondary);
+ transition: color 0.3s ease;
+ position: relative;
+}
+
+.contact-details a::after {
+ content: "";
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ width: 0;
+ height: 1px;
+ background: var(--accent-primary);
+ transition: width 0.3s ease;
+}
+
+.contact-details a:hover {
+ color: var(--accent-primary);
+}
+
+.contact-details a:hover::after {
+ width: 100%;
+}
+
+/* Enhanced Contact Form */
+.contact-form {
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-lg);
+ padding: var(--spacing-xl);
+ transition: all 0.3s ease;
+}
+
+.contact-form:hover {
+ border-color: var(--accent-primary);
+ box-shadow: var(--shadow-glow);
+}
+
+.form-group {
+ margin-bottom: var(--spacing-md);
+ position: relative;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: var(--spacing-xs);
+ font-weight: 500;
+ color: var(--text-primary);
+ font-size: 0.9rem;
+ transition: color 0.3s ease;
+}
+
+.form-group input,
+.form-group select,
+.form-group textarea {
+ width: 100%;
+ padding: var(--spacing-sm);
+ background: var(--bg-tertiary);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-md);
+ color: var(--text-primary);
+ font-size: 0.95rem;
+ font-family: var(--font-primary);
+ transition: all 0.3s ease;
+}
+
+.form-group input:focus,
+.form-group select:focus,
+.form-group textarea:focus {
+ outline: none;
+ border-color: var(--accent-primary);
+ box-shadow: 0 0 0 3px rgba(0, 245, 255, 0.1);
+ background: var(--bg-card-hover);
+}
+
+.form-group textarea {
+ resize: vertical;
+ min-height: 120px;
+ font-family: var(--font-primary);
+}
+
+.form-group select {
+ cursor: pointer;
+}
+
+.contact-form .btn {
+ width: 100%;
+ justify-content: center;
+ margin-top: var(--spacing-sm);
+}
+
+/* Enhanced Footer */
+.footer {
+ background: var(--bg-secondary);
+ border-top: 1px solid var(--border-subtle);
+ padding: var(--spacing-2xl) 0 var(--spacing-lg);
+ position: relative;
+}
+
+.footer::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 1px;
+ background: var(--accent-gradient);
+}
+
+.footer-content {
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr 1fr;
+ gap: var(--spacing-xl);
+ margin-bottom: var(--spacing-xl);
+}
+
+.footer-brand .logo {
+ font-size: 1.5rem;
+ margin-bottom: var(--spacing-sm);
+ display: block;
+}
+
+.footer-brand p {
+ color: var(--text-secondary);
+ margin-bottom: var(--spacing-lg);
+ line-height: 1.6;
+ max-width: 300px;
+}
+
+.footer-social {
+ display: flex;
+ gap: var(--spacing-sm);
+}
+
+.social-link {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-md);
+ color: var(--text-secondary);
+ font-size: 1.1rem;
+ transition: all 0.3s ease;
+ position: relative;
+ overflow: hidden;
+}
+
+.social-link::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: var(--accent-gradient);
+ transition: left 0.3s ease;
+ z-index: -1;
+}
+
+.social-link:hover::before {
+ left: 0;
+}
+
+.social-link:hover {
+ background: var(--accent-gradient);
+ color: #ffffff;
+ transform: translateY(-3px) scale(1.1);
+ border-color: transparent;
+}
+
+.footer-links h4 {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--text-primary);
+ margin-bottom: var(--spacing-sm);
+ position: relative;
+}
+
+.footer-links h4::after {
+ content: "";
+ position: absolute;
+ bottom: -5px;
+ left: 0;
+ width: 30px;
+ height: 2px;
+ background: var(--accent-primary);
+}
+
+.footer-links ul {
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacing-xs);
+}
+
+.footer-links a {
+ color: var(--text-secondary);
+ font-size: 0.9rem;
+ transition: all 0.3s ease;
+ padding: 0.25rem 0;
+ position: relative;
+}
+
+.footer-links a::before {
+ content: "";
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 0;
+ height: 1px;
+ background: var(--accent-primary);
+ transition: width 0.3s ease;
+}
+
+.footer-links a:hover {
+ color: var(--accent-primary);
+ transform: translateX(5px);
+}
+
+.footer-links a:hover::before {
+ width: 100%;
+}
+
+.footer-bottom {
+ border-top: 1px solid var(--border-subtle);
+ padding-top: var(--spacing-lg);
+}
+
+.footer-bottom-content {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: var(--spacing-sm);
+}
+
+.footer-bottom p {
+ color: var(--text-muted);
+ font-size: 0.9rem;
+}
+
+.footer-badges {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-sm);
+}
+
+.badge {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-xs);
+ padding: var(--spacing-xs) var(--spacing-sm);
+ background: var(--bg-card);
+ border: 1px solid var(--border-subtle);
+ border-radius: var(--radius-sm);
+ font-size: 0.8rem;
+ color: var(--text-muted);
+ transition: all 0.3s ease;
+}
+
+.badge:hover {
+ background: var(--accent-gradient);
+ color: var(--bg-primary);
+ border-color: transparent;
+ transform: translateY(-2px);
+}
+
+.badge i {
+ color: var(--accent-primary);
+}
+
+.badge:hover i {
+ color: var(--bg-primary);
+}
+
+/* Enhanced No Results */
+.no-results {
+ grid-column: 1 / -1;
+ text-align: center;
+ padding: var(--spacing-2xl);
+ color: var(--text-muted);
+ position: relative;
+}
+
+.no-results i {
+ font-size: 3rem;
+ margin-bottom: var(--spacing-md);
+ opacity: 0.5;
+ animation: bounce 2s infinite;
+}
+
+@keyframes bounce {
+ 0%,
+ 20%,
+ 50%,
+ 80%,
+ 100% {
+ transform: translateY(0);
+ }
+ 40% {
+ transform: translateY(-10px);
+ }
+ 60% {
+ transform: translateY(-5px);
+ }
+}
+
+.no-results h3 {
+ font-size: 1.5rem;
+ margin-bottom: var(--spacing-sm);
+ color: var(--text-secondary);
+}
+
+.no-results p {
+ color: var(--text-muted);
+}
+
+/* Responsive Design */
+@media (max-width: 1024px) {
+ .nav-container {
+ padding: 0 var(--spacing-md);
+ }
+
+ .container {
+ padding: 0 var(--spacing-md);
+ }
+
+ .footer-content {
+ grid-template-columns: 1fr 1fr;
+ gap: var(--spacing-lg);
+ }
+
+ .contact-container {
+ grid-template-columns: 1fr;
+ gap: var(--spacing-xl);
+ }
+}
+
+@media (max-width: 768px) {
+ .mobile-menu-btn {
+ display: block;
+ }
+
+ .nav-links {
+ position: fixed;
+ top: 0;
+ right: -100%;
+ width: 280px;
+ height: 100vh;
+ background: rgba(10, 10, 10, 0.98);
+ backdrop-filter: blur(30px);
+ flex-direction: column;
+ padding: 80px var(--spacing-lg) var(--spacing-lg);
+ transition: right 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
+ border-left: 1px solid rgba(255, 255, 255, 0.1);
+ box-shadow: -10px 0 30px rgba(0, 0, 0, 0.3);
+ }
+
+ .nav-links.active {
+ right: 0;
+ }
+
+ .nav-links a {
+ width: 100%;
+ text-align: center;
+ padding: var(--spacing-md);
+ font-size: 1.1rem;
+ border-radius: var(--radius-lg);
+ margin-bottom: var(--spacing-xs);
+ }
+
+ .nav-links a::after {
+ display: none;
+ }
+
+ .nav-links a::before {
+ border-radius: var(--radius-lg);
+ }
+
+ .nav-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(5px);
+ z-index: 999;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.3s ease;
+ }
+
+ .nav-overlay.active {
+ opacity: 1;
+ visibility: visible;
+ }
+
+ .hero h1 {
+ font-size: clamp(2rem, 8vw, 3rem);
+ }
+
+ .hero p {
+ font-size: 1.1rem;
+ }
+
+ .hero-buttons {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .section {
+ padding: 4rem 0;
+ }
+
+ .portfolio-controls {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .filter-buttons {
+ justify-content: center;
+ }
+
+ .portfolio-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .team-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .principles-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .stats-container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .footer-content {
+ grid-template-columns: 1fr;
+ text-align: center;
+ gap: var(--spacing-lg);
+ }
+
+ .footer-brand p {
+ max-width: none;
+ }
+
+ .footer-social {
+ justify-content: center;
+ }
+
+ .footer-bottom-content {
+ flex-direction: column;
+ text-align: center;
+ gap: var(--spacing-sm);
+ }
+
+ .portfolio-btn {
+ padding: 0.9rem 1.5rem;
+ font-size: 0.85rem;
+ }
+}
+
+@media (max-width: 480px) {
+ .container {
+ padding: 0 var(--spacing-sm);
+ }
+
+ .nav-container {
+ padding: 0 var(--spacing-sm);
+ }
+
+ .hero-content {
+ padding: var(--spacing-sm) 0;
+ }
+
+ .project-card,
+ .team-member,
+ .principle-card,
+ .contact-form {
+ padding: var(--spacing-md);
+ }
+
+ .section-header {
+ margin-bottom: var(--spacing-xl);
+ }
+
+ .contact-form {
+ padding: var(--spacing-lg);
+ }
+
+ .stats-container {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Animations and Interactions */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ }
+
+ .star {
+ animation: none;
+ }
+}
+
+/* Print Styles */
+@media print {
+ .animated-bg,
+ .stars,
+ nav,
+ .hero-buttons,
+ .contact-form,
+ .footer-social {
+ display: none;
+ }
+
+ body {
+ background: white;
+ color: black;
+ }
+
+ .section {
+ padding: 2rem 0;
+ }
+}
diff --git a/styles.css b/styles.css
deleted file mode 100644
index d14c826..0000000
--- a/styles.css
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- interstellar_development website
- Copyright (C) 2024 interstellar_development
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
.
-*/
-
-:root {
- --background-color: #0b0c1d;
- --text-color: #c7d5e0;
- --accent-color: #ffdd55;
- --accent-hover-color: #ffd700;
- --dark-blue: rgba(31, 42, 64, 1);
- --dark-blue-translucent: rgba(31, 42, 64, 0.9);
- --light-blue: rgba(46, 58, 95, 0.8);
- --border-radius: 8px;
- --transition-speed: 0.3s;
- --box-shadow: 0 2px 15px rgba(0, 0, 0, 0.7);
- --font-size-large: 2.5em;
- --font-size-medium: 1.8em;
-}
-
-/* Reset and normalize */
-*,
-*::before,
-*::after {
- box-sizing: border-box;
- margin: 0;
- padding: 0;
-}
-
-/* Body styling */
-body {
- background-color: var(--background-color);
- color: var(--text-color);
- font-family: "Arial", sans-serif;
- line-height: 1.6;
- padding: 0 20px;
- background: url("images/star.jpg") no-repeat center center fixed;
- background-size: cover;
-}
-
-/* Header Styling */
-/* Header Styling */
-header {
- background-color: var(--dark-blue);
- height: 5em;
- position: fixed;
- width: 100%;
- top: 0;
- left: 0;
- padding: 15px 20px;
- box-shadow: var(--box-shadow);
- backdrop-filter: blur(5px);
- z-index: 100;
- margin-bottom: 0px;
-}
-
-/* Burger Menu Styling */
-.burger-menu {
- background: none;
- border: none;
- color: #ffffff;
- font-size: 1.8em;
- cursor: pointer;
- display: block;
- padding: 0;
- z-index: 110;
-}
-
-/* Dropdown Menu (Hidden by Default) */
-.div-menu {
- z-index: 1;
- background-color: var(--light-blue);
- width: 100%;
- position: fixed;
- top: 0;
- left: 0;
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
- padding: 0;
- margin-top: 0px;
- height: auto;
-}
-
-.div-menu li {
- margin: 0;
- padding: 1em;
- z-index: 1;
-}
-
-.div-menu a {
- width: 100%;
- padding: 8px 0;
- text-align: center;
- color: #ffffff;
- text-decoration: none;
- border-radius: 5px;
- transition: background-color 0.3s ease;
- display: block;
-}
-
-.div-menu a:hover {
- background-color: #34495e;
-}
-
-/* Menu Animation and Styling */
-.menu {
- display: flex;
- flex-direction: column;
- background-color: var(--light-blue);
- position: absolute;
- top: -50vh;
- left: 0;
- width: 100%;
- z-index: 5;
- padding: 0;
- margin: 0;
- list-style: none;
- justify-content: center;
- text-align: center;
- font-weight: bolder;
- font-size: large;
- transition: top 0.5s ease-in-out;
-}
-
-.menu.active {
- display: flex;
- top: 4em;
- z-index: 5;
-}
-
-/* Header Content Container */
-.header-content {
- display: flex;
- justify-content: space-between;
- align-items: center;
- max-width: 1200px;
- margin: 0 auto;
- padding: 0 20px;
- z-index: 10;
-}
-
-/* Project Name Styling */
-.project-name {
- font-size: 2em;
- color: var(--accent-color);
- text-decoration: none;
- transition: color var(--transition-speed), text-shadow var(--transition-speed);
-}
-
-.project-name:hover {
- color: var(--accent-hover-color);
- text-shadow: 0 0 10px var(--accent-hover-color);
-}
-
-/* Article styling */
-article {
- max-width: 800px;
- margin: 6.25em auto;
- padding: 20px;
- background-color: var(--dark-blue-translucent);
- border-radius: var(--border-radius);
- box-shadow: var(--box-shadow);
- backdrop-filter: blur(5px);
-}
-
-article h1 {
- font-size: var(--font-size-large);
- margin-bottom: 20px;
- color: var(--accent-color);
- text-shadow: 0 0 15px var(--accent-color);
-}
-
-article p {
- color: var(--text-color);
- margin-bottom: 20px;
- hyphens: auto;
-}
-
-/* Download list */
-article h2 {
- font-size: var(--font-size-medium);
- margin: 20px 0 10px;
- color: var(--accent-color);
- text-shadow: 0 0 10px var(--accent-color);
-}
-
-article ul {
- list-style-type: none;
- padding: 0;
-}
-
-article ul a li {
- background-color: var(--light-blue);
- margin-bottom: 10px;
- border-radius: var(--border-radius);
- padding: 10px;
- transition: background-color var(--transition-speed),
- box-shadow var(--transition-speed);
-}
-
-article ul a li:hover {
- background-color: rgba(68, 80, 124, 0.9);
- box-shadow: 0 0 10px var(--accent-color);
-}
-
-article ul a li {
- text-decoration: none;
- color: var(--accent-color);
- font-weight: bold;
-}
-
-/* Footer styling */
-footer {
- background-color: var(--dark-blue);
- padding: 10px 20px;
- color: var(--text-color);
- width: 100%;
- position: fixed;
- bottom: 0;
- left: 0;
- box-shadow: 0 -2px 15px rgba(0, 0, 0, 0.7);
- backdrop-filter: blur(5px);
-}
-
-.footer-content {
- text-align: center;
- font-size: 0.9em;
-}
-
-/* Card container styles */
-.cards {
- display: grid;
- grid-template-columns: repeat(3, 1fr); /* Display 3 cards per line */
- gap: 20px;
- margin-top: 50px;
-}
-
-/* Ensure the
tag covers the entire card */
-section .card a {
- display: flex; /* Use flex to make fill the card and align content */
- flex-direction: column;
- justify-content: center; /* Vertically center the content */
- align-items: center; /* Horizontally center the content */
- text-decoration: none;
- color: inherit;
- height: 100%;
- width: 100%;
- padding: 20px;
-}
-
-/* Card styles */
-section .card {
- text-align: center;
- list-style: none;
- background: linear-gradient(
- 180deg,
- rgba(0, 0, 50, 0.9),
- rgba(10, 10, 100, 0.9),
- rgba(30, 30, 150, 0.9)
- );
- border-radius: 12px;
- box-shadow: 0 5px 20px rgba(0, 0, 50, 0.8), 0 0 10px rgba(255, 255, 255, 0.1);
- border: 1px solid #2e3a60;
- position: relative;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- transition: background 0.5s ease, transform 0.4s ease, box-shadow 0.5s ease;
-}
-
-/* Hover effect */
-section .card:hover {
- transform: translateY(-8px);
- background: linear-gradient(
- 180deg,
- rgba(30, 30, 150, 0.9),
- rgba(40, 0, 100, 0.9),
- rgba(100, 0, 150, 0.9)
- );
- box-shadow: 0 10px 30px rgba(0, 0, 100, 0.7), 0 0 20px rgba(255, 221, 85, 0.8);
-}
-
-section .card img {
- height: 80px;
- width: 80px;
- object-fit: cover;
- border-radius: 50%;
- margin: 0 auto 15px;
- box-shadow: 0 0 15px rgba(255, 221, 85, 0.5);
-}
-
-section .card h3 {
- margin: 10px 0;
- font-size: 1.4em;
- font-weight: bold;
- color: rgba(255, 221, 85, 1);
- text-shadow: 0 0 15px rgba(255, 221, 85, 0.9);
-}
-
-section .card p {
- flex-grow: 1;
- color: rgba(200, 220, 255, 0.8);
- margin-bottom: 10px;
- text-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
-}
-
-section .card::before {
- content: "";
- position: absolute;
- top: -20px;
- right: -20px;
- width: 60px;
- height: 60px;
- border-radius: 50%;
- background: radial-gradient(
- circle,
- rgba(255, 255, 255, 0.1),
- rgba(255, 255, 255, 0.02)
- );
- box-shadow: 0 0 50px rgba(255, 255, 255, 0.5);
- animation: spin 8s linear infinite;
-}
-
-section .card .suit-icon {
- position: absolute;
- bottom: 10px;
- right: 10px;
- width: 24px;
- height: 24px;
- opacity: 0.7;
- transition: opacity var(--transition-speed);
-}
-
-section .card:hover .suit-icon {
- opacity: 1;
-}
-
-/* Keyframes for spinning element */
-@keyframes spin {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
-}
-
-/* Form styling */
-form {
- max-width: 600px;
- margin: 0 auto;
- background: var(--dark-blue-translucent);
- padding: 20px;
- border-radius: var(--border-radius);
- box-shadow: var(--box-shadow);
- backdrop-filter: blur(5px);
-}
-
-form label,
-form input,
-form textarea {
- color: var(--text-color);
- background-color: var(--light-blue);
- border: 1px solid #3a4b7f;
- border-radius: var(--border-radius);
- padding: 10px;
- margin: 10px 0;
- width: 100%;
-}
-
-form input[type="submit"] {
- background-color: var(--accent-color);
- color: #fff;
- border: none;
- cursor: pointer;
- transition: background-color var(--transition-speed);
-}
-
-form input[type="submit"]:hover {
- background-color: var(--accent-hover-color);
-}
-
-/* Footer Styling */
-footer {
- background-color: var(--dark-blue);
- padding: 10px 20px;
- color: var(--text-color);
- text-align: center;
- font-size: 0.9em;
-}
-
-@media (max-width: 768px) {
- .cards {
- grid-template-columns: 1fr; /* 1 card per line on smaller screens */
- }
-
- header ul {
- flex-direction: column;
- gap: 10px;
- }
-
- article {
- margin: 12em 10px;
- padding: 15px;
- }
-
- section .card {
- padding: 12px;
- }
-
- section .card img {
- height: 60px;
- width: 60px;
- }
-
- .project-name {
- font-size: 1.3em;
- }
-}
diff --git a/webGames/index.html b/webGames/index.html
deleted file mode 100644
index 7f1a0bf..0000000
--- a/webGames/index.html
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
- Game Collection
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- © 2025 Game Collection
-
-
-
diff --git a/webGames/styles.css b/webGames/styles.css
deleted file mode 100644
index e9a6fcf..0000000
--- a/webGames/styles.css
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Reset and box-sizing */
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-/* General Styles */
-body {
- font-family: Arial, sans-serif;
- background-color: #282c34;
- color: #ffffff;
- margin: 0;
-}
-
-header {
- background-color: #4caf50;
- color: white;
- text-align: center;
- padding: 1em 0;
- font-size: 1.5rem;
-}
-
-footer {
- background-color: #333;
- color: white;
- text-align: center;
- padding: 1em 0;
- margin-top: 20px;
-}
-
-/* Grid Styles */
-.grid-container {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 20px; /* Space between items */
- padding: 20px; /* Space around the grid */
-}
-
-/* Game Item */
-.item {
- position: relative;
- background-color: #444;
- border-radius: 10px;
- overflow: hidden;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
- transition: transform 0.3s ease, box-shadow 0.3s ease, filter 0.3s ease;
- width: 100%; /* Ensure it takes full width of the column */
- height: 400px; /* Set a fixed height for all items */
- display: flex;
- flex-direction: column; /* Stack children vertically */
-}
-
-/* Ensure the image takes the top part of the card */
-.item img {
- width: 100%;
- height: 100%; /* Set a height for the image */
- object-fit: cover;
-}
-
-.item .description {
- padding: 30px;
- font-size: 1rem;
- color: #ddd;
- background-color: rgba(0, 0, 0, 0.5);
- border-radius: 0 0 10px 10px;
- flex-grow: 1; /* Allow description to take remaining space */
-}
-
-p {
- text-decoration: none;
-}
-
-/* Hover effect for scaling and glowing */
-.item:hover {
- transform: scale(1.05);
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
- filter: brightness(1.2);
-}
-
-.item:hover img {
- transform: scale(1.1); /* Slight zoom-in effect for the image */
- filter: brightness(1.1); /* Increase image brightness */
-}
-
-.item h2 {
- position: absolute;
- top: 10%;
- left: 50%;
- transform: translateX(-50%);
- color: white;
- font-size: 1.5rem;
- background-color: rgba(0, 0, 0, 0.6);
- padding: 5px 15px;
- border-radius: 5px;
- text-align: center;
- opacity: 0;
- transition: opacity 0.3s ease, transform 0.3s ease;
-}
-
-.item:hover h2 {
- opacity: 1;
- transform: translateX(-50%) translateY(-10px); /* Move the title upwards with hover */
-}
-
-/* Mobile Optimization */
-@media (max-width: 600px) {
- header {
- font-size: 1.2rem;
- }
-
- .item {
- height: auto; /* Allow auto height on mobile for better responsiveness */
- width: auto;
- }
-
- .grid-container {
- grid-template-columns: repeat(1, 1fr);
- }
-}