diff --git a/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/README.md b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/README.md
new file mode 100644
index 00000000..22ec1b89
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/README.md
@@ -0,0 +1,171 @@
+# ๐ Typing Speed Race Game
+
+**Contributor:** Soham-Gadekar
+**Domain:** Frontend
+**Difficulty:** Intermediate
+**Tech Stack:** HTML, CSS, JavaScript (ES6+), LocalStorage API
+
+---
+
+## ๐ Description
+
+A fun and interactive **Typing Speed Race Game** that challenges players to type as fast and accurately as possible.
+The app displays random paragraphs and measures typing speed (WPM), accuracy, and time taken.
+It also features a **ghost racer** based on your best WPM for an extra challenge!
+
+Perfect for improving typing speed and practicing JavaScript DOM manipulation, event handling, and local storage integration.
+
+---
+
+## ๐ฏ Features
+
+* ๐๏ธ Random paragraph generation
+* โก Real-time WPM (Words Per Minute) and accuracy tracking
+* ๐ฎ Ghost racer feature (race against your previous best speed)
+* ๐ง LocalStorage for best score persistence
+* ๐ Live timer display
+* ๐งน Reset and restart functionality
+* ๐ Progress bars for player and ghost
+* ๐ฅ Animated result modal with โNew Recordโ badge
+* ๐ฑ Fully responsive design
+
+---
+
+## ๐ ๏ธ Tech Stack
+
+* **HTML5** - Semantic structure
+* **CSS3** - Responsive and modern UI
+* **JavaScript (ES6+)** - Game logic, DOM updates
+* **LocalStorage API** - Store best WPM
+
+---
+
+## ๐ How to Run
+
+### Method 1: Direct Browser
+
+1. Download or clone the repository
+2. Open `index.html` in your browser
+3. Click โStart Raceโ and begin typing!
+
+### Method 2: Live Server (Recommended)
+
+1. Install VS Code and Live Server extension
+2. Right-click `index.html` โ **Open with Live Server**
+3. The app will open at `http://localhost:5500`
+
+---
+
+## ๐ Project Structure
+
+```
+TypingRace/
+โโโ index.html # Main HTML structure
+โโโ styles.css # Styling and layout
+โโโ script.js # Game logic
+โโโ README.md # Project documentation
+```
+
+---
+
+## ๐ป Code Highlights
+
+### Random Paragraph Selection
+
+```javascript
+currentText = paragraphs[Math.floor(Math.random() * paragraphs.length)];
+displayText();
+```
+
+### Ghost Racer Logic
+
+```javascript
+const charsPerSecond = (bestWpm * 5) / 60;
+ghostInterval = setInterval(() => {
+ const elapsed = (Date.now() - ghostStartTime) / 1000;
+ const ghostChars = Math.floor(charsPerSecond * elapsed);
+ const ghostProgressPercent = Math.min((ghostChars / textLength) * 100, 100);
+ ghostProgress.style.width = ghostProgressPercent + '%';
+}, 100);
+```
+
+### LocalStorage Integration
+
+```javascript
+if (wpm > bestWpm) {
+ bestWpm = wpm;
+ localStorage.setItem('typingRaceBestWpm', wpm);
+}
+```
+
+---
+
+## ๐ Learning Outcomes
+
+### Skills Practiced
+
+* โ
DOM Manipulation
+* โ
Real-time event handling
+* โ
JavaScript timing functions
+* โ
Dynamic progress visualization
+* โ
LocalStorage API usage
+* โ
Responsive UI design
+
+### Concepts Learned
+
+* Handling and visualizing live data
+* Optimizing UI updates
+* Persisting user data in browser
+* Building mini-games with pure JavaScript
+
+---
+
+## ๐จ Customization Ideas
+
+1. **Dark/Light Theme Toggle**
+2. **Leaderboard** - Global or local high scores
+3. **Multiple Difficulty Levels**
+4. **Sound Effects** for typing and completion
+5. **Multiplayer Mode** (Socket.io or Firebase)
+6. **Animated Ghost Character**
+7. **Typing Error Highlighting with Suggestions**
+8. **Countdown Timer before start**
+
+---
+
+## ๐ Known Issues
+
+* None currently.
+* If the progress bar desyncs, refresh the page.
+
+---
+
+## ๐ Future Enhancements
+
+* [ ] Add difficulty modes
+* [ ] Include typing statistics history
+* [ ] Introduce multiplayer ghost race
+* [ ] Add customizable typing texts
+* [ ] Enhance animations and UI polish
+
+---
+
+## ๐ License
+
+MIT License โ Free to use, modify, and share!
+
+---
+
+## ๐ค Contributing
+
+This project is open for contributions!
+Feel free to:
+
+* Fork and improve
+* Report issues
+* Add new features
+* Submit pull requests
+
+---
+
+**Happy Typing! โจ๏ธ๐ฅ**
diff --git a/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/index.html b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/index.html
new file mode 100644
index 00000000..aa7feec9
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/index.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+ Typing Speed Race Game
+
+
+
+
+
+
+
+
+
+ ๐ You
+ 0%
+
+
+
+
+ ๐ป Ghost (Best)
+ 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
๐ Race Complete!
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/script.js b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/script.js
new file mode 100644
index 00000000..8538ca51
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/script.js
@@ -0,0 +1,208 @@
+const paragraphs = [
+ "The quick brown fox jumps over the lazy dog while the sun sets behind the mountains painting the sky in shades of orange and purple.",
+ "Technology advances rapidly changing how we live and work. Innovation drives progress and creates new opportunities for everyone to explore and grow.",
+ "Practice makes perfect when learning new skills. Consistent effort and dedication lead to mastery over time with patience and perseverance.",
+ "Nature provides endless inspiration with its beauty and complexity. From tiny insects to massive mountains everything connects in harmony.",
+ "Music transcends language barriers bringing people together through rhythm and melody. Every culture contributes unique sounds to our world.",
+ "Reading opens doors to new worlds and perspectives. Books transport us across time and space teaching valuable lessons along the journey.",
+ "Creativity flourishes when we allow ourselves to think differently. Breaking free from conventional patterns leads to innovative solutions.",
+ "Friendship enriches our lives with shared experiences and support. True connections withstand the test of time through ups and downs."
+];
+
+let currentText = '';
+let startTime = null;
+let isRacing = false;
+let bestWpm = localStorage.getItem('typingRaceBestWpm') ? parseInt(localStorage.getItem('typingRaceBestWpm')) : 0;
+let ghostInterval = null;
+let ghostStartTime = null;
+
+const textDisplay = document.getElementById('textDisplay');
+const inputArea = document.getElementById('inputArea');
+const startBtn = document.getElementById('startBtn');
+const resetBtn = document.getElementById('resetBtn');
+const wpmDisplay = document.getElementById('wpmDisplay');
+const accuracyDisplay = document.getElementById('accuracyDisplay');
+const timeDisplay = document.getElementById('timeDisplay');
+const bestWpmDisplay = document.getElementById('bestWpmDisplay');
+const resultsModal = document.getElementById('resultsModal');
+const raceAgainBtn = document.getElementById('raceAgainBtn');
+const playerProgress = document.getElementById('playerProgress');
+const ghostProgress = document.getElementById('ghostProgress');
+const playerPercent = document.getElementById('playerPercent');
+const ghostPercent = document.getElementById('ghostPercent');
+
+function initGame() {
+ currentText = paragraphs[Math.floor(Math.random() * paragraphs.length)];
+ displayText();
+ updateBestDisplay();
+}
+
+function displayText() {
+ textDisplay.innerHTML = currentText
+ .split('')
+ .map((char, i) => `${char}`)
+ .join('');
+}
+
+function startRace() {
+ isRacing = true;
+ startTime = Date.now();
+ ghostStartTime = Date.now();
+ inputArea.disabled = false;
+ inputArea.value = '';
+ inputArea.focus();
+ startBtn.disabled = true;
+ resetBtn.disabled = false;
+ playerProgress.style.width = '0%';
+ ghostProgress.style.width = '0%';
+
+ if (bestWpm > 0) {
+ startGhostRace();
+ }
+}
+
+function startGhostRace() {
+ const textLength = currentText.length;
+ const charsPerSecond = (bestWpm * 5) / 60;
+
+ ghostInterval = setInterval(() => {
+ if (!isRacing) {
+ clearInterval(ghostInterval);
+ return;
+ }
+
+ const elapsed = (Date.now() - ghostStartTime) / 1000;
+ const ghostChars = Math.floor(charsPerSecond * elapsed);
+ const ghostProgressPercent = Math.min((ghostChars / textLength) * 100, 100);
+
+ ghostProgress.style.width = ghostProgressPercent + '%';
+ ghostPercent.textContent = Math.round(ghostProgressPercent) + '%';
+
+ if (ghostProgressPercent >= 100) {
+ clearInterval(ghostInterval);
+ }
+ }, 100);
+}
+
+function updateStats() {
+ const typedText = inputArea.value;
+ const elapsed = (Date.now() - startTime) / 1000;
+ const chars = textDisplay.querySelectorAll('.char');
+
+ let correctChars = 0;
+ let totalTyped = typedText.length;
+
+ chars.forEach((char, i) => {
+ char.classList.remove('correct', 'incorrect', 'current');
+
+ if (i < typedText.length) {
+ if (typedText[i] === currentText[i]) {
+ char.classList.add('correct');
+ correctChars++;
+ } else {
+ char.classList.add('incorrect');
+ }
+ } else if (i === typedText.length) {
+ char.classList.add('current');
+ }
+ });
+
+ const words = correctChars / 5;
+ const minutes = elapsed / 60;
+ const wpm = Math.round(words / minutes) || 0;
+ const accuracy = totalTyped > 0 ? Math.round((correctChars / totalTyped) * 100) : 100;
+
+ wpmDisplay.textContent = wpm;
+ accuracyDisplay.textContent = accuracy + '%';
+ timeDisplay.textContent = elapsed.toFixed(1) + 's';
+
+ const progressPercent = (typedText.length / currentText.length) * 100;
+ playerProgress.style.width = progressPercent + '%';
+ playerPercent.textContent = Math.round(progressPercent) + '%';
+
+ if (typedText === currentText) {
+ finishRace(wpm, accuracy);
+ }
+}
+
+function finishRace(wpm, accuracy) {
+ isRacing = false;
+ inputArea.disabled = true;
+ startBtn.disabled = false;
+ resetBtn.disabled = false;
+
+ if (ghostInterval) {
+ clearInterval(ghostInterval);
+ }
+
+ const isNewRecord = wpm > bestWpm;
+ if (isNewRecord) {
+ bestWpm = wpm;
+ localStorage.setItem('typingRaceBestWpm', wpm);
+ updateBestDisplay();
+ }
+
+ showResults(wpm, accuracy, isNewRecord);
+}
+
+function showResults(wpm, accuracy, isNewRecord) {
+ document.getElementById('finalWpm').textContent = wpm;
+ document.getElementById('finalAccuracy').textContent = accuracy + '%';
+
+ const badge = document.getElementById('newRecordBadge');
+ if (isNewRecord) {
+ badge.innerHTML = '๐ New Record!
';
+ } else {
+ badge.innerHTML = '';
+ }
+
+ resultsModal.classList.add('active');
+}
+
+function resetRace() {
+ isRacing = false;
+ startTime = null;
+ ghostStartTime = null;
+ inputArea.value = '';
+ inputArea.disabled = true;
+ startBtn.disabled = false;
+ resetBtn.disabled = true;
+ wpmDisplay.textContent = '0';
+ accuracyDisplay.textContent = '100%';
+ timeDisplay.textContent = '0s';
+ playerProgress.style.width = '0%';
+ ghostProgress.style.width = '0%';
+ playerPercent.textContent = '0%';
+ ghostPercent.textContent = '0%';
+
+ if (ghostInterval) {
+ clearInterval(ghostInterval);
+ }
+
+ initGame();
+}
+
+function updateBestDisplay() {
+ bestWpmDisplay.textContent = bestWpm > 0 ? bestWpm : '--';
+}
+
+startBtn.addEventListener('click', startRace);
+resetBtn.addEventListener('click', resetRace);
+raceAgainBtn.addEventListener('click', () => {
+ resultsModal.classList.remove('active');
+ resetRace();
+});
+
+inputArea.addEventListener('input', () => {
+ if (isRacing) {
+ updateStats();
+ }
+});
+
+resultsModal.addEventListener('click', (e) => {
+ if (e.target === resultsModal) {
+ resultsModal.classList.remove('active');
+ }
+});
+
+initGame();
\ No newline at end of file
diff --git a/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/style.css b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/style.css
new file mode 100644
index 00000000..89ec5fb9
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/TypingSpeedRaceGame/style.css
@@ -0,0 +1,337 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+:root {
+ --primary: #6366f1;
+ --primary-dark: #4f46e5;
+ --success: #10b981;
+ --error: #ef4444;
+ --bg-dark: #0f172a;
+ --bg-card: #1e293b;
+ --text: #f1f5f9;
+ --text-dim: #94a3b8;
+ --ghost: #8b5cf6;
+}
+
+body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background: linear-gradient(135deg, var(--bg-dark) 0%, #1a1a2e 100%);
+ color: var(--text);
+ min-height: 100vh;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.container {
+ max-width: 900px;
+ width: 100%;
+}
+
+header {
+ text-align: center;
+ margin-bottom: 40px;
+ animation: fadeInDown 0.6s ease;
+}
+
+h1 {
+ font-size: 2.5rem;
+ background: linear-gradient(135deg, var(--primary), var(--ghost));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ margin-bottom: 10px;
+}
+
+.tagline {
+ color: var(--text-dim);
+ font-size: 1.1rem;
+}
+
+.race-track {
+ background: var(--bg-card);
+ border-radius: 16px;
+ padding: 30px;
+ margin-bottom: 30px;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
+ animation: fadeInUp 0.6s ease;
+}
+
+.progress-section {
+ margin-bottom: 30px;
+}
+
+.progress-label {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+ font-size: 0.9rem;
+}
+
+.racer-name {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-weight: 600;
+}
+
+.progress-bar-container {
+ height: 40px;
+ background: rgba(0, 0, 0, 0.3);
+ border-radius: 20px;
+ overflow: hidden;
+ position: relative;
+ margin-bottom: 15px;
+}
+
+.progress-bar {
+ height: 100%;
+ transition: width 0.3s ease;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ padding-right: 15px;
+ font-weight: 600;
+ position: relative;
+}
+
+.player-progress {
+ background: linear-gradient(90deg, var(--primary), var(--primary-dark));
+ box-shadow: 0 0 20px rgba(99, 102, 241, 0.5);
+}
+
+.ghost-progress {
+ background: linear-gradient(90deg, rgba(139, 92, 246, 0.6), rgba(139, 92, 246, 0.4));
+ box-shadow: 0 0 20px rgba(139, 92, 246, 0.3);
+}
+
+.racer-icon {
+ font-size: 1.5rem;
+}
+
+.text-display {
+ background: rgba(0, 0, 0, 0.3);
+ padding: 30px;
+ border-radius: 12px;
+ font-size: 1.5rem;
+ line-height: 2;
+ letter-spacing: 0.5px;
+ margin-bottom: 25px;
+ min-height: 150px;
+ font-family: 'Courier New', monospace;
+}
+
+.char {
+ transition: all 0.1s ease;
+}
+
+.char.correct {
+ color: var(--success);
+ text-shadow: 0 0 8px rgba(16, 185, 129, 0.5);
+}
+
+.char.incorrect {
+ color: var(--error);
+ background: rgba(239, 68, 68, 0.2);
+ text-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
+}
+
+.char.current {
+ background: var(--primary);
+ animation: pulse 1s infinite;
+}
+
+@keyframes pulse {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.5; }
+}
+
+.input-area {
+ width: 100%;
+ padding: 20px;
+ font-size: 1.3rem;
+ background: rgba(0, 0, 0, 0.3);
+ border: 2px solid transparent;
+ border-radius: 12px;
+ color: var(--text);
+ font-family: 'Courier New', monospace;
+ transition: all 0.3s ease;
+ margin-bottom: 25px;
+}
+
+.input-area:focus {
+ outline: none;
+ border-color: var(--primary);
+ box-shadow: 0 0 20px rgba(99, 102, 241, 0.3);
+}
+
+.input-area:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.stats-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
+ gap: 20px;
+ margin-bottom: 25px;
+}
+
+.stat-card {
+ background: rgba(0, 0, 0, 0.3);
+ padding: 20px;
+ border-radius: 12px;
+ text-align: center;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.stat-label {
+ font-size: 0.9rem;
+ color: var(--text-dim);
+ margin-bottom: 8px;
+}
+
+.stat-value {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--primary);
+}
+
+.stat-value.accuracy {
+ color: var(--success);
+}
+
+.stat-value.best {
+ color: var(--ghost);
+}
+
+.controls {
+ display: flex;
+ gap: 15px;
+ justify-content: center;
+}
+
+.btn {
+ padding: 15px 40px;
+ font-size: 1.1rem;
+ font-weight: 600;
+ border: none;
+ border-radius: 12px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+}
+
+.btn-primary {
+ background: linear-gradient(135deg, var(--primary), var(--primary-dark));
+ color: white;
+ box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4);
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(99, 102, 241, 0.6);
+}
+
+.btn-secondary {
+ background: rgba(255, 255, 255, 0.1);
+ color: var(--text);
+ border: 2px solid rgba(255, 255, 255, 0.2);
+}
+
+.btn-secondary:hover {
+ background: rgba(255, 255, 255, 0.15);
+ transform: translateY(-2px);
+}
+
+.btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ transform: none !important;
+}
+
+.results-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.8);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+ padding: 20px;
+}
+
+.results-modal.active {
+ display: flex;
+ animation: fadeIn 0.3s ease;
+}
+
+.results-content {
+ background: var(--bg-card);
+ padding: 40px;
+ border-radius: 20px;
+ max-width: 500px;
+ width: 100%;
+ text-align: center;
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
+ animation: scaleIn 0.3s ease;
+}
+
+.results-content h2 {
+ font-size: 2rem;
+ margin-bottom: 30px;
+ color: var(--primary);
+}
+
+.new-record {
+ background: linear-gradient(135deg, var(--success), #059669);
+ color: white;
+ padding: 10px 20px;
+ border-radius: 8px;
+ margin-bottom: 20px;
+ font-weight: 600;
+ animation: bounce 0.6s ease;
+}
+
+@keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes fadeInUp {
+ from { opacity: 0; transform: translateY(30px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+@keyframes fadeInDown {
+ from { opacity: 0; transform: translateY(-30px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+@keyframes scaleIn {
+ from { transform: scale(0.9); opacity: 0; }
+ to { transform: scale(1); opacity: 1; }
+}
+
+@keyframes bounce {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-10px); }
+}
+
+@media (max-width: 768px) {
+ h1 { font-size: 2rem; }
+ .text-display { font-size: 1.2rem; padding: 20px; }
+ .input-area { font-size: 1.1rem; }
+ .controls { flex-direction: column; }
+ .btn { width: 100%; }
+ .stats-grid { grid-template-columns: 1fr 1fr; }
+}
\ No newline at end of file