ItsJayKee commited on
Commit
993c9ec
·
verified ·
1 Parent(s): 17ece03

now add the code snippets for the test

Browse files
Files changed (6) hide show
  1. README.md +8 -5
  2. components/footer.js +46 -0
  3. components/header.js +46 -0
  4. index.html +79 -19
  5. script.js +361 -0
  6. style.css +34 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Codeflow Typeracer
3
- emoji: 🔥
4
- colorFrom: red
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: CodeFlow TypeRacer 🚀
3
+ colorFrom: gray
4
+ colorTo: green
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ footer {
7
+ background-color: rgba(17, 24, 39, 0.8);
8
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
9
+ }
10
+ .social-link {
11
+ transition: all 0.2s;
12
+ }
13
+ .social-link:hover {
14
+ color: #818cf8;
15
+ transform: translateY(-2px);
16
+ }
17
+ </style>
18
+ <footer class="py-8 px-6 mt-12">
19
+ <div class="container mx-auto">
20
+ <div class="flex flex-col md:flex-row justify-between items-center">
21
+ <div class="mb-6 md:mb-0">
22
+ <h3 class="text-xl font-bold mb-2 text-indigo-400">CodeFlow</h3>
23
+ <p class="text-gray-400">Improve your coding speed and accuracy</p>
24
+ </div>
25
+ <div class="flex space-x-6">
26
+ <a href="#" class="social-link" aria-label="Twitter">
27
+ <i data-feather="twitter"></i>
28
+ </a>
29
+ <a href="#" class="social-link" aria-label="GitHub">
30
+ <i data-feather="github"></i>
31
+ </a>
32
+ <a href="#" class="social-link" aria-label="LinkedIn">
33
+ <i data-feather="linkedin"></i>
34
+ </a>
35
+ </div>
36
+ </div>
37
+ <div class="mt-8 pt-6 border-t border-gray-800 text-center text-gray-500 text-sm">
38
+ &copy; ${new Date().getFullYear()} CodeFlow Typing Challenge. All rights reserved.
39
+ </div>
40
+ </div>
41
+ </footer>
42
+ `;
43
+ }
44
+ }
45
+
46
+ customElements.define('custom-footer', CustomFooter);
components/header.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomHeader extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ header {
7
+ background-color: rgba(17, 24, 39, 0.8);
8
+ backdrop-filter: blur(10px);
9
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
10
+ }
11
+ .container {
12
+ max-width: 1200px;
13
+ }
14
+ .logo {
15
+ color: #818cf8;
16
+ font-weight: 700;
17
+ font-size: 1.5rem;
18
+ }
19
+ .nav-link {
20
+ transition: color 0.2s;
21
+ }
22
+ .nav-link:hover {
23
+ color: #818cf8;
24
+ }
25
+ </style>
26
+ <header class="py-4 px-6">
27
+ <div class="container mx-auto flex justify-between items-center">
28
+ <a href="/" class="logo flex items-center">
29
+ <i data-feather="code" class="mr-2"></i>
30
+ CodeFlow
31
+ </a>
32
+ <nav class="hidden md:flex space-x-6">
33
+ <a href="#" class="nav-link">Home</a>
34
+ <a href="#" class="nav-link">About</a>
35
+ <a href="#" class="nav-link">Leaderboard</a>
36
+ </nav>
37
+ <button class="md:hidden">
38
+ <i data-feather="menu"></i>
39
+ </button>
40
+ </div>
41
+ </header>
42
+ `;
43
+ }
44
+ }
45
+
46
+ customElements.define('custom-header', CustomHeader);
index.html CHANGED
@@ -1,19 +1,79 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CodeFlow Typing Challenge</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ </head>
12
+ <body class="bg-gray-900 text-gray-100 min-h-screen">
13
+ <custom-header></custom-header>
14
+
15
+ <main class="container mx-auto px-4 py-8 max-w-4xl">
16
+ <div class="text-center mb-12">
17
+ <h1 class="text-4xl font-bold mb-2 text-indigo-400">CodeFlow Typing Challenge</h1>
18
+ <p class="text-lg text-gray-400">Test your coding language typing speed & accuracy</p>
19
+ </div>
20
+
21
+ <div class="bg-gray-800 rounded-xl p-6 shadow-lg mb-8">
22
+ <div class="flex justify-between items-center mb-6">
23
+ <div class="flex space-x-4">
24
+ <div class="bg-gray-700 px-4 py-2 rounded-lg">
25
+ <span class="text-indigo-300">Time:</span>
26
+ <span id="timer" class="ml-2">60s</span>
27
+ </div>
28
+ <div class="bg-gray-700 px-4 py-2 rounded-lg">
29
+ <span class="text-indigo-300">Speed:</span>
30
+ <span id="speed" class="ml-2">0 WPM</span>
31
+ </div>
32
+ </div>
33
+ <button id="reset-btn" class="bg-indigo-600 hover:bg-indigo-700 px-4 py-2 rounded-lg transition">
34
+ <i data-feather="refresh-cw" class="inline mr-2"></i>Reset
35
+ </button>
36
+ </div>
37
+
38
+ <div id="typing-area" class="bg-gray-900 rounded-lg p-6 mb-6 h-48 overflow-y-auto">
39
+ <div id="code-display" class="font-mono text-lg leading-relaxed"></div>
40
+ </div>
41
+
42
+ <textarea id="input-field" class="w-full bg-gray-900 border-2 border-gray-700 rounded-lg p-4 font-mono text-lg focus:border-indigo-500 focus:outline-none" rows="6" placeholder="Start typing here..."></textarea>
43
+ </div>
44
+
45
+ <div id="results" class="hidden bg-gray-800 rounded-xl p-6 shadow-lg">
46
+ <h2 class="text-2xl font-bold mb-6 text-center text-indigo-400">Your Results</h2>
47
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
48
+ <div class="bg-gray-900 p-4 rounded-lg text-center">
49
+ <div class="text-4xl font-bold text-indigo-400 mb-2" id="final-wpm">0</div>
50
+ <div class="text-gray-400">Words Per Minute</div>
51
+ </div>
52
+ <div class="bg-gray-900 p-4 rounded-lg text-center">
53
+ <div class="text-4xl font-bold text-indigo-400 mb-2" id="final-accuracy">0%</div>
54
+ <div class="text-gray-400">Accuracy</div>
55
+ </div>
56
+ <div class="bg-gray-900 p-4 rounded-lg text-center">
57
+ <div class="text-4xl font-bold text-indigo-400 mb-2" id="final-time">0s</div>
58
+ <div class="text-gray-400">Time Taken</div>
59
+ </div>
60
+ </div>
61
+ <div class="mt-8 text-center">
62
+ <button id="try-again-btn" class="bg-indigo-600 hover:bg-indigo-700 px-6 py-3 rounded-lg text-lg transition">
63
+ <i data-feather="repeat" class="inline mr-2"></i>Try Again
64
+ </button>
65
+ </div>
66
+ </div>
67
+ </main>
68
+
69
+ <custom-footer></custom-footer>
70
+
71
+ <script src="components/header.js"></script>
72
+ <script src="components/footer.js"></script>
73
+ <script src="script.js"></script>
74
+ <script>
75
+ feather.replace();
76
+ </script>
77
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
78
+ </body>
79
+ </html>
script.js ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // Code snippets for typing test
3
+ const codeSnippets = [
4
+ // HTML
5
+ `<!DOCTYPE html>
6
+ <html>
7
+ <head>
8
+ <title>My Portfolio</title>
9
+ <link rel="stylesheet" href="styles.css">
10
+ </head>
11
+ <body>
12
+ <header>
13
+ <nav>
14
+ <ul>
15
+ <li><a href="#home">Home</a></li>
16
+ <li><a href="#projects">Projects</a></li>
17
+ <li><a href="#contact">Contact</a></li>
18
+ </ul>
19
+ </nav>
20
+ </header>
21
+ <main>
22
+ <section id="home">
23
+ <h1>Welcome to My Portfolio</h1>
24
+ <p>I build amazing web experiences</p>
25
+ </section>
26
+ </main>
27
+ <footer>
28
+ <p>&copy; ${new Date().getFullYear()}</p>
29
+ </footer>
30
+ </body>
31
+ </html>`,
32
+
33
+ // JavaScript
34
+ `class User {
35
+ constructor(name, email) {
36
+ this.name = name;
37
+ this.email = email;
38
+ this.score = 0;
39
+ }
40
+
41
+ login() {
42
+ console.log(this.name, 'just logged in');
43
+ return this;
44
+ }
45
+
46
+ logout() {
47
+ console.log(this.name, 'just logged out');
48
+ return this;
49
+ }
50
+
51
+ updateScore() {
52
+ this.score++;
53
+ console.log(this.name, 'score is now', this.score);
54
+ return this;
55
+ }
56
+ }
57
+
58
+ const user1 = new User('Alice', 'alice@example.com');
59
+ user1.login().updateScore().updateScore().logout();`,
60
+
61
+ // React Component
62
+ `import React, { useState, useEffect } from 'react';
63
+
64
+ function Counter() {
65
+ const [count, setCount] = useState(0);
66
+ const [isActive, setIsActive] = useState(false);
67
+
68
+ useEffect(() => {
69
+ let interval = null;
70
+ if (isActive) {
71
+ interval = setInterval(() => {
72
+ setCount(prev => prev + 1);
73
+ }, 1000);
74
+ }
75
+ return () => clearInterval(interval);
76
+ }, [isActive]);
77
+
78
+ return (
79
+ <div className="counter">
80
+ <h2>{count}</h2>
81
+ <button onClick={() => setIsActive(!isActive)}>
82
+ {isActive ? 'Pause' : 'Start'}
83
+ </button>
84
+ <button onClick={() => setCount(0)}>Reset</button>
85
+ </div>
86
+ );
87
+ }
88
+
89
+ export default Counter;`,
90
+
91
+ // Python
92
+ `def fibonacci(n):
93
+ """Return the first n Fibonacci numbers."""
94
+ fib_sequence = []
95
+ a, b = 0, 1
96
+ for _ in range(n):
97
+ fib_sequence.append(a)
98
+ a, b = b, a + b
99
+ return fib_sequence
100
+
101
+ def is_prime(num):
102
+ """Check if a number is prime."""
103
+ if num < 2:
104
+ return False
105
+ for i in range(2, int(num**0.5) + 1):
106
+ if num % i == 0:
107
+ return False
108
+ return True
109
+
110
+ if __name__ == "__main__":
111
+ print(fibonacci(10))
112
+ print([x for x in range(20) if is_prime(x)])`,
113
+
114
+ // CSS
115
+ `.card-container {
116
+ display: grid;
117
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
118
+ gap: 2rem;
119
+ padding: 2rem;
120
+ }
121
+
122
+ .card {
123
+ background: white;
124
+ border-radius: 8px;
125
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
126
+ transition: transform 0.3s ease;
127
+ }
128
+
129
+ .card:hover {
130
+ transform: translateY(-5px);
131
+ }
132
+
133
+ .card img {
134
+ width: 100%;
135
+ height: 200px;
136
+ object-fit: cover;
137
+ border-radius: 8px 8px 0 0;
138
+ }
139
+
140
+ .card-content {
141
+ padding: 1.5rem;
142
+ }
143
+
144
+ @media (max-width: 768px) {
145
+ .card-container {
146
+ grid-template-columns: 1fr;
147
+ }
148
+ }`,
149
+
150
+ // Node.js
151
+ `const express = require('express');
152
+ const mongoose = require('mongoose');
153
+ require('dotenv').config();
154
+
155
+ const app = express();
156
+ app.use(express.json());
157
+
158
+ // Connect to MongoDB
159
+ mongoose.connect(process.env.MONGODB_URI, {
160
+ useNewUrlParser: true,
161
+ useUnifiedTopology: true
162
+ })
163
+ .then(() => console.log('Connected to MongoDB'))
164
+ .catch(err => console.error('Connection error:', err));
165
+
166
+ // Routes
167
+ app.get('/', (req, res) => {
168
+ res.send('API is running');
169
+ });
170
+
171
+ // Error handling middleware
172
+ app.use((err, req, res, next) => {
173
+ console.error(err.stack);
174
+ res.status(500).send('Something broke!');
175
+ });
176
+
177
+ const PORT = process.env.PORT || 5000;
178
+ app.listen(PORT, () => {
179
+ console.log(\`Server running on port \${PORT}\`);
180
+ });`,
181
+
182
+ // SQL
183
+ `-- Create users table
184
+ CREATE TABLE users (
185
+ id INT AUTO_INCREMENT PRIMARY KEY,
186
+ username VARCHAR(50) NOT NULL UNIQUE,
187
+ email VARCHAR(100) NOT NULL UNIQUE,
188
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
189
+ );
190
+
191
+ -- Insert sample data
192
+ INSERT INTO users (username, email) VALUES
193
+ ('johndoe', 'john@example.com'),
194
+ ('janedoe', 'jane@example.com');
195
+
196
+ -- Query with join
197
+ SELECT
198
+ p.id,
199
+ p.title,
200
+ p.content,
201
+ u.username AS author,
202
+ COUNT(c.id) AS comment_count
203
+ FROM
204
+ posts p
205
+ JOIN
206
+ users u ON p.user_id = u.id
207
+ LEFT JOIN
208
+ comments c ON p.id = c.post_id
209
+ GROUP BY
210
+ p.id
211
+ ORDER BY
212
+ p.created_at DESC
213
+ LIMIT 10;`
214
+ ];
215
+ // DOM elements
216
+ const codeDisplay = document.getElementById('code-display');
217
+ const inputField = document.getElementById('input-field');
218
+ const timerElement = document.getElementById('timer');
219
+ const speedElement = document.getElementById('speed');
220
+ const resetBtn = document.getElementById('reset-btn');
221
+ const resultsSection = document.getElementById('results');
222
+ const finalWPM = document.getElementById('final-wpm');
223
+ const finalAccuracy = document.getElementById('final-accuracy');
224
+ const finalTime = document.getElementById('final-time');
225
+ const tryAgainBtn = document.getElementById('try-again-btn');
226
+
227
+ // Game variables
228
+ let timeLeft = 60;
229
+ let timer;
230
+ let isPlaying = false;
231
+ let startTime;
232
+ let endTime;
233
+ let correctChars = 0;
234
+ let totalChars = 0;
235
+
236
+ // Initialize the game
237
+ function initGame() {
238
+ // Select a random code snippet
239
+ const randomSnippet = codeSnippets[Math.floor(Math.random() * codeSnippets.length)];
240
+ totalChars = randomSnippet.length;
241
+
242
+ // Display the code with spans for each character
243
+ codeDisplay.innerHTML = '';
244
+ randomSnippet.split('').forEach(char => {
245
+ const span = document.createElement('span');
246
+ span.textContent = char;
247
+ codeDisplay.appendChild(span);
248
+ });
249
+
250
+ // Highlight the first character
251
+ codeDisplay.children[0].classList.add('current');
252
+
253
+ // Reset game state
254
+ inputField.value = '';
255
+ inputField.disabled = false;
256
+ inputField.focus();
257
+ timeLeft = 60;
258
+ timerElement.textContent = `${timeLeft}s`;
259
+ correctChars = 0;
260
+ isPlaying = false;
261
+ resultsSection.classList.add('hidden');
262
+ }
263
+
264
+ // Start the game
265
+ function startGame() {
266
+ if (isPlaying) return;
267
+
268
+ isPlaying = true;
269
+ startTime = new Date();
270
+
271
+ timer = setInterval(() => {
272
+ timeLeft--;
273
+ timerElement.textContent = `${timeLeft}s`;
274
+
275
+ if (timeLeft <= 0) {
276
+ endGame();
277
+ }
278
+ }, 1000);
279
+ }
280
+
281
+ // Update the display as user types
282
+ function updateDisplay() {
283
+ const inputText = inputField.value;
284
+ const codeSpans = codeDisplay.children;
285
+
286
+ // Reset all spans
287
+ for (let i = 0; i < codeSpans.length; i++) {
288
+ codeSpans[i].className = '';
289
+ }
290
+
291
+ // Mark correct/incorrect characters
292
+ let allCorrect = true;
293
+ for (let i = 0; i < inputText.length; i++) {
294
+ if (i < codeSpans.length) {
295
+ if (inputText[i] === codeSpans[i].textContent) {
296
+ codeSpans[i].classList.add('correct');
297
+ if (i === inputText.length - 1) {
298
+ codeSpans[i].classList.add('current');
299
+ }
300
+ } else {
301
+ codeSpans[i].classList.add('incorrect');
302
+ allCorrect = false;
303
+ }
304
+ }
305
+ }
306
+
307
+ // Highlight next character if all correct so far
308
+ if (allCorrect && inputText.length < codeSpans.length) {
309
+ codeSpans[inputText.length].classList.add('current');
310
+ }
311
+
312
+ // Calculate and display typing speed
313
+ if (isPlaying) {
314
+ const elapsedTime = (new Date() - startTime) / 60000; // in minutes
315
+ const wordsTyped = inputText.length / 5; // standard word length
316
+ const wpm = Math.round(wordsTyped / elapsedTime) || 0;
317
+ speedElement.textContent = `${wpm} WPM`;
318
+ }
319
+
320
+ // Count correct characters for accuracy
321
+ correctChars = 0;
322
+ for (let i = 0; i < inputText.length && i < codeSpans.length; i++) {
323
+ if (inputText[i] === codeSpans[i].textContent) {
324
+ correctChars++;
325
+ }
326
+ }
327
+
328
+ // End game if all characters are typed correctly
329
+ if (inputText.length === codeSpans.length && allCorrect) {
330
+ endGame();
331
+ }
332
+ }
333
+
334
+ // End the game
335
+ function endGame() {
336
+ clearInterval(timer);
337
+ isPlaying = false;
338
+ inputField.disabled = true;
339
+ endTime = new Date();
340
+
341
+ // Calculate results
342
+ const timeTaken = Math.max(1, 60 - timeLeft); // at least 1 second to avoid division by zero
343
+ const wordsTyped = correctChars / 5;
344
+ const wpm = Math.round((wordsTyped / timeTaken) * 60);
345
+ const accuracy = Math.round((correctChars / totalChars) * 100);
346
+
347
+ // Display results
348
+ finalWPM.textContent = wpm;
349
+ finalAccuracy.textContent = `${accuracy}%`;
350
+ finalTime.textContent = `${timeTaken}s`;
351
+ resultsSection.classList.remove('hidden');
352
+ }
353
+
354
+ // Event listeners
355
+ inputField.addEventListener('input', updateDisplay);
356
+ inputField.addEventListener('focus', startGame);
357
+ resetBtn.addEventListener('click', initGame);
358
+ tryAgainBtn.addEventListener('click', initGame);
359
+
360
+ // Initialize the game on page load
361
+ document.addEventListener('DOMContentLoaded', initGame);
style.css CHANGED
@@ -1,28 +1,43 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom styles for code highlighting */
2
+ .correct {
3
+ color: #a3e635; /* lime-400 */
4
  }
5
 
6
+ .incorrect {
7
+ color: #f87171; /* red-400 */
8
+ text-decoration: underline;
9
  }
10
 
11
+ .current {
12
+ background-color: rgba(129, 140, 248, 0.3); /* indigo-400 with opacity */
13
+ border-left: 2px solid #818cf8; /* indigo-400 */
 
 
14
  }
15
 
16
+ /* Custom scrollbar */
17
+ ::-webkit-scrollbar {
18
+ width: 8px;
19
+ height: 8px;
 
 
20
  }
21
 
22
+ ::-webkit-scrollbar-track {
23
+ background: #1f2937; /* gray-800 */
24
  }
25
+
26
+ ::-webkit-scrollbar-thumb {
27
+ background: #4b5563; /* gray-600 */
28
+ border-radius: 4px;
29
+ }
30
+
31
+ ::-webkit-scrollbar-thumb:hover {
32
+ background: #6b7280; /* gray-500 */
33
+ }
34
+
35
+ /* Animation for current character */
36
+ @keyframes blink {
37
+ 0%, 100% { opacity: 1; }
38
+ 50% { opacity: 0.5; }
39
+ }
40
+
41
+ .current {
42
+ animation: blink 1s infinite;
43
+ }