create-template-html-css 1.8.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +179 -2
  3. package/bin/cli.js +20 -2
  4. package/package.json +1 -1
  5. package/templates/blackjack/index.html +97 -0
  6. package/templates/blackjack/script.js +381 -0
  7. package/templates/blackjack/style.css +452 -0
  8. package/templates/breakout/index.html +56 -0
  9. package/templates/breakout/script.js +387 -0
  10. package/templates/breakout/style.css +239 -0
  11. package/templates/connect-four/index.html +78 -0
  12. package/templates/connect-four/script.js +413 -0
  13. package/templates/connect-four/style.css +426 -0
  14. package/templates/dice-game/index.html +99 -0
  15. package/templates/dice-game/script.js +291 -0
  16. package/templates/dice-game/style.css +403 -0
  17. package/templates/flappy-bird/index.html +47 -0
  18. package/templates/flappy-bird/script.js +394 -0
  19. package/templates/flappy-bird/style.css +243 -0
  20. package/templates/game-2048/index.html +59 -0
  21. package/templates/game-2048/script.js +269 -0
  22. package/templates/game-2048/style.css +281 -0
  23. package/templates/guess-number/index.html +71 -0
  24. package/templates/guess-number/script.js +216 -0
  25. package/templates/guess-number/style.css +337 -0
  26. package/templates/memory-game/index.html +50 -0
  27. package/templates/memory-game/script.js +216 -0
  28. package/templates/memory-game/style.css +288 -0
  29. package/templates/pong/index.html +90 -0
  30. package/templates/pong/script.js +364 -0
  31. package/templates/pong/style.css +371 -0
  32. package/templates/rock-paper-scissors/index.html +84 -0
  33. package/templates/rock-paper-scissors/script.js +199 -0
  34. package/templates/rock-paper-scissors/style.css +295 -0
  35. package/templates/simon-says/index.html +64 -0
  36. package/templates/simon-says/script.js +206 -0
  37. package/templates/simon-says/style.css +250 -0
  38. package/templates/slot-machine/index.html +112 -0
  39. package/templates/slot-machine/script.js +238 -0
  40. package/templates/slot-machine/style.css +464 -0
  41. package/templates/snake-game/index.html +61 -0
  42. package/templates/snake-game/script.js +360 -0
  43. package/templates/snake-game/style.css +246 -0
  44. package/templates/tetris/index.html +84 -0
  45. package/templates/tetris/script.js +447 -0
  46. package/templates/tetris/style.css +286 -0
  47. package/templates/tic-tac-toe/index.html +57 -0
  48. package/templates/tic-tac-toe/script.js +156 -0
  49. package/templates/tic-tac-toe/style.css +244 -0
  50. package/templates/whack-a-mole/index.html +85 -0
  51. package/templates/whack-a-mole/script.js +172 -0
  52. package/templates/whack-a-mole/style.css +263 -0
  53. package/COMPONENTS-GALLERY.html +0 -773
  54. package/PUBLISH-GUIDE.md +0 -112
  55. package/create-template-html-css-1.8.0.tgz +0 -0
@@ -0,0 +1,364 @@
1
+ // Canvas setup
2
+ const canvas = document.getElementById('gameCanvas');
3
+ const ctx = canvas.getContext('2d');
4
+
5
+ canvas.width = 800;
6
+ canvas.height = 500;
7
+
8
+ // Game state
9
+ let gameState = {
10
+ running: false,
11
+ paused: false,
12
+ gameMode: 'pvc', // 'pvc' or 'pvp'
13
+ difficulty: 'medium',
14
+ score1: 0,
15
+ score2: 0,
16
+ winningScore: 10
17
+ };
18
+
19
+ // Paddle properties
20
+ const paddleWidth = 12;
21
+ const paddleHeight = 80;
22
+ const paddleSpeed = 6;
23
+
24
+ const paddle1 = {
25
+ x: 20,
26
+ y: canvas.height / 2 - paddleHeight / 2,
27
+ width: paddleWidth,
28
+ height: paddleHeight,
29
+ dy: 0
30
+ };
31
+
32
+ const paddle2 = {
33
+ x: canvas.width - 20 - paddleWidth,
34
+ y: canvas.height / 2 - paddleHeight / 2,
35
+ width: paddleWidth,
36
+ height: paddleHeight,
37
+ dy: 0
38
+ };
39
+
40
+ // Ball properties
41
+ const ball = {
42
+ x: canvas.width / 2,
43
+ y: canvas.height / 2,
44
+ radius: 8,
45
+ dx: 5,
46
+ dy: 5,
47
+ speed: 5
48
+ };
49
+
50
+ // AI settings
51
+ const aiSettings = {
52
+ easy: { speed: 0.5, accuracy: 0.6 },
53
+ medium: { speed: 0.7, accuracy: 0.8 },
54
+ hard: { speed: 0.9, accuracy: 0.95 },
55
+ impossible: { speed: 1.2, accuracy: 1 }
56
+ };
57
+
58
+ // Keyboard state
59
+ const keys = {
60
+ w: false,
61
+ s: false,
62
+ ArrowUp: false,
63
+ ArrowDown: false
64
+ };
65
+
66
+ // Event listeners
67
+ document.addEventListener('keydown', (e) => {
68
+ if (e.key in keys) {
69
+ keys[e.key] = true;
70
+ }
71
+ if (e.key === ' ' && gameState.running && !gameState.paused) {
72
+ pauseGame();
73
+ }
74
+ });
75
+
76
+ document.addEventListener('keyup', (e) => {
77
+ if (e.key in keys) {
78
+ keys[e.key] = false;
79
+ }
80
+ });
81
+
82
+ // Game mode selection
83
+ document.querySelectorAll('.mode-btn').forEach(btn => {
84
+ btn.addEventListener('click', () => {
85
+ document.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active'));
86
+ btn.classList.add('active');
87
+
88
+ gameState.gameMode = btn.dataset.mode;
89
+
90
+ // Update player 2 name
91
+ if (gameState.gameMode === 'pvc') {
92
+ document.getElementById('player2Name').textContent = '🤖 מחשב';
93
+ document.querySelector('.difficulty-selector').style.display = 'flex';
94
+ } else {
95
+ document.getElementById('player2Name').textContent = '👤 שחקן 2';
96
+ document.querySelector('.difficulty-selector').style.display = 'none';
97
+ }
98
+ });
99
+ });
100
+
101
+ // Difficulty selection
102
+ document.getElementById('difficulty').addEventListener('change', (e) => {
103
+ gameState.difficulty = e.target.value;
104
+ });
105
+
106
+ // Reset ball
107
+ function resetBall() {
108
+ ball.x = canvas.width / 2;
109
+ ball.y = canvas.height / 2;
110
+
111
+ // Random direction
112
+ const angle = (Math.random() * Math.PI / 4) - Math.PI / 8;
113
+ const direction = Math.random() < 0.5 ? 1 : -1;
114
+
115
+ ball.dx = Math.cos(angle) * ball.speed * direction;
116
+ ball.dy = Math.sin(angle) * ball.speed;
117
+ }
118
+
119
+ // Update paddles
120
+ function updatePaddles() {
121
+ // Player 1
122
+ if (keys.w && paddle1.y > 0) {
123
+ paddle1.y -= paddleSpeed;
124
+ }
125
+ if (keys.s && paddle1.y < canvas.height - paddle1.height) {
126
+ paddle1.y += paddleSpeed;
127
+ }
128
+
129
+ // Player 2 / AI
130
+ if (gameState.gameMode === 'pvc') {
131
+ updateAI();
132
+ } else {
133
+ if (keys.ArrowUp && paddle2.y > 0) {
134
+ paddle2.y -= paddleSpeed;
135
+ }
136
+ if (keys.ArrowDown && paddle2.y < canvas.height - paddle2.height) {
137
+ paddle2.y += paddleSpeed;
138
+ }
139
+ }
140
+ }
141
+
142
+ // AI logic
143
+ function updateAI() {
144
+ const ai = aiSettings[gameState.difficulty];
145
+ const paddleCenter = paddle2.y + paddle2.height / 2;
146
+ const targetY = ball.y;
147
+
148
+ // Add some randomness for realism
149
+ const errorMargin = (1 - ai.accuracy) * paddle2.height;
150
+ const target = targetY + (Math.random() - 0.5) * errorMargin;
151
+
152
+ if (paddleCenter < target - 10) {
153
+ paddle2.y += paddleSpeed * ai.speed;
154
+ } else if (paddleCenter > target + 10) {
155
+ paddle2.y -= paddleSpeed * ai.speed;
156
+ }
157
+
158
+ // Keep in bounds
159
+ paddle2.y = Math.max(0, Math.min(canvas.height - paddle2.height, paddle2.y));
160
+ }
161
+
162
+ // Update ball
163
+ function updateBall() {
164
+ ball.x += ball.dx;
165
+ ball.y += ball.dy;
166
+
167
+ // Top and bottom collision
168
+ if (ball.y - ball.radius < 0 || ball.y + ball.radius > canvas.height) {
169
+ ball.dy = -ball.dy;
170
+ }
171
+
172
+ // Paddle 1 collision
173
+ if (ball.x - ball.radius < paddle1.x + paddle1.width &&
174
+ ball.x + ball.radius > paddle1.x &&
175
+ ball.y > paddle1.y &&
176
+ ball.y < paddle1.y + paddle1.height) {
177
+
178
+ // Calculate hit position
179
+ const hitPos = (ball.y - paddle1.y) / paddle1.height - 0.5;
180
+ ball.dy = hitPos * ball.speed * 2;
181
+ ball.dx = Math.abs(ball.dx) * 1.05; // Speed up
182
+ ball.speed *= 1.02;
183
+ }
184
+
185
+ // Paddle 2 collision
186
+ if (ball.x + ball.radius > paddle2.x &&
187
+ ball.x - ball.radius < paddle2.x + paddle2.width &&
188
+ ball.y > paddle2.y &&
189
+ ball.y < paddle2.y + paddle2.height) {
190
+
191
+ const hitPos = (ball.y - paddle2.y) / paddle2.height - 0.5;
192
+ ball.dy = hitPos * ball.speed * 2;
193
+ ball.dx = -Math.abs(ball.dx) * 1.05;
194
+ ball.speed *= 1.02;
195
+ }
196
+
197
+ // Score
198
+ if (ball.x - ball.radius < 0) {
199
+ gameState.score2++;
200
+ updateScore();
201
+ checkWin();
202
+ resetBall();
203
+ }
204
+
205
+ if (ball.x + ball.radius > canvas.width) {
206
+ gameState.score1++;
207
+ updateScore();
208
+ checkWin();
209
+ resetBall();
210
+ }
211
+ }
212
+
213
+ // Draw everything
214
+ function draw() {
215
+ // Clear canvas
216
+ ctx.fillStyle = '#1a202c';
217
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
218
+
219
+ // Draw center line
220
+ ctx.setLineDash([10, 10]);
221
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
222
+ ctx.lineWidth = 2;
223
+ ctx.beginPath();
224
+ ctx.moveTo(canvas.width / 2, 0);
225
+ ctx.lineTo(canvas.width / 2, canvas.height);
226
+ ctx.stroke();
227
+ ctx.setLineDash([]);
228
+
229
+ // Draw paddles
230
+ ctx.fillStyle = '#667EEA';
231
+ ctx.shadowBlur = 15;
232
+ ctx.shadowColor = '#667EEA';
233
+ ctx.fillRect(paddle1.x, paddle1.y, paddle1.width, paddle1.height);
234
+
235
+ ctx.fillStyle = '#F56565';
236
+ ctx.shadowColor = '#F56565';
237
+ ctx.fillRect(paddle2.x, paddle2.y, paddle2.width, paddle2.height);
238
+
239
+ // Draw ball
240
+ ctx.fillStyle = '#F6E05E';
241
+ ctx.shadowColor = '#F6E05E';
242
+ ctx.beginPath();
243
+ ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
244
+ ctx.fill();
245
+ ctx.shadowBlur = 0;
246
+
247
+ // Draw pause overlay
248
+ if (gameState.paused) {
249
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
250
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
251
+ ctx.fillStyle = '#FFFFFF';
252
+ ctx.font = 'bold 36px Arial';
253
+ ctx.textAlign = 'center';
254
+ ctx.fillText('משחק מושהה', canvas.width / 2, canvas.height / 2);
255
+ }
256
+ }
257
+
258
+ // Game loop
259
+ function gameLoop() {
260
+ if (!gameState.running) return;
261
+
262
+ if (!gameState.paused) {
263
+ updatePaddles();
264
+ updateBall();
265
+ }
266
+
267
+ draw();
268
+ requestAnimationFrame(gameLoop);
269
+ }
270
+
271
+ // Update score display
272
+ function updateScore() {
273
+ document.getElementById('player1Score').textContent = gameState.score1;
274
+ document.getElementById('player2Score').textContent = gameState.score2;
275
+ }
276
+
277
+ // Check win
278
+ function checkWin() {
279
+ if (gameState.score1 >= gameState.winningScore) {
280
+ endGame(1);
281
+ } else if (gameState.score2 >= gameState.winningScore) {
282
+ endGame(2);
283
+ }
284
+ }
285
+
286
+ // End game
287
+ function endGame(winner) {
288
+ gameState.running = false;
289
+
290
+ const winnerName = winner === 1 ?
291
+ 'שחקן 1' :
292
+ (gameState.gameMode === 'pvc' ? 'המחשב' : 'שחקן 2');
293
+
294
+ showMessage(`🎉 ${winnerName} ניצח ${gameState.winningScore} - ${winner === 1 ? gameState.score2 : gameState.score1}!`, 'success');
295
+
296
+ document.getElementById('startBtn').disabled = false;
297
+ document.getElementById('pauseBtn').disabled = true;
298
+ }
299
+
300
+ // Start game
301
+ document.getElementById('startBtn').addEventListener('click', startGame);
302
+
303
+ function startGame() {
304
+ gameState.running = true;
305
+ gameState.paused = false;
306
+ gameState.score1 = 0;
307
+ gameState.score2 = 0;
308
+ ball.speed = 5;
309
+
310
+ paddle1.y = canvas.height / 2 - paddleHeight / 2;
311
+ paddle2.y = canvas.height / 2 - paddleHeight / 2;
312
+
313
+ resetBall();
314
+ updateScore();
315
+
316
+ document.getElementById('startBtn').disabled = true;
317
+ document.getElementById('pauseBtn').disabled = false;
318
+ document.getElementById('resultMessage').textContent = '';
319
+
320
+ gameLoop();
321
+ }
322
+
323
+ // Pause game
324
+ document.getElementById('pauseBtn').addEventListener('click', pauseGame);
325
+
326
+ function pauseGame() {
327
+ gameState.paused = !gameState.paused;
328
+ document.getElementById('pauseBtn').textContent = gameState.paused ? 'המשך' : 'השהה';
329
+ }
330
+
331
+ // Reset game
332
+ document.getElementById('resetBtn').addEventListener('click', resetGame);
333
+
334
+ function resetGame() {
335
+ gameState.running = false;
336
+ gameState.paused = false;
337
+ gameState.score1 = 0;
338
+ gameState.score2 = 0;
339
+ ball.speed = 5;
340
+
341
+ paddle1.y = canvas.height / 2 - paddleHeight / 2;
342
+ paddle2.y = canvas.height / 2 - paddleHeight / 2;
343
+
344
+ resetBall();
345
+ updateScore();
346
+ draw();
347
+
348
+ document.getElementById('startBtn').disabled = false;
349
+ document.getElementById('pauseBtn').disabled = true;
350
+ document.getElementById('pauseBtn').textContent = 'השהה';
351
+ document.getElementById('resultMessage').textContent = '';
352
+ }
353
+
354
+ // Show message
355
+ function showMessage(text, type = 'info') {
356
+ const messageEl = document.getElementById('resultMessage');
357
+ messageEl.textContent = text;
358
+ messageEl.className = `result-message ${type}`;
359
+ messageEl.style.display = 'block';
360
+ }
361
+
362
+ // Initialize
363
+ updateScore();
364
+ draw();
@@ -0,0 +1,371 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body {
8
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
10
+ min-height: 100vh;
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ padding: 20px;
15
+ }
16
+
17
+ .container {
18
+ background: white;
19
+ border-radius: 20px;
20
+ padding: 30px;
21
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
22
+ max-width: 900px;
23
+ width: 100%;
24
+ }
25
+
26
+ .header {
27
+ text-align: center;
28
+ margin-bottom: 20px;
29
+ }
30
+
31
+ .header h1 {
32
+ color: #2d3748;
33
+ font-size: 2.5rem;
34
+ margin-bottom: 5px;
35
+ }
36
+
37
+ .subtitle {
38
+ color: #718096;
39
+ font-size: 1.1rem;
40
+ }
41
+
42
+ .game-mode {
43
+ display: flex;
44
+ gap: 15px;
45
+ justify-content: center;
46
+ margin-bottom: 20px;
47
+ flex-wrap: wrap;
48
+ }
49
+
50
+ .mode-btn {
51
+ padding: 12px 30px;
52
+ font-size: 1rem;
53
+ font-weight: 600;
54
+ border: 3px solid #e2e8f0;
55
+ background: white;
56
+ color: #4a5568;
57
+ border-radius: 10px;
58
+ cursor: pointer;
59
+ transition: all 0.3s ease;
60
+ }
61
+
62
+ .mode-btn:hover {
63
+ border-color: #667eea;
64
+ color: #667eea;
65
+ }
66
+
67
+ .mode-btn.active {
68
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
69
+ color: white;
70
+ border-color: #667eea;
71
+ }
72
+
73
+ .difficulty-selector {
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ gap: 10px;
78
+ margin-bottom: 20px;
79
+ }
80
+
81
+ .difficulty-selector label {
82
+ font-weight: 600;
83
+ color: #2d3748;
84
+ }
85
+
86
+ .difficulty-selector select {
87
+ padding: 8px 15px;
88
+ border: 2px solid #e2e8f0;
89
+ border-radius: 8px;
90
+ background: white;
91
+ font-size: 1rem;
92
+ cursor: pointer;
93
+ transition: border-color 0.3s ease;
94
+ }
95
+
96
+ .difficulty-selector select:focus {
97
+ outline: none;
98
+ border-color: #667eea;
99
+ }
100
+
101
+ .score-board {
102
+ display: flex;
103
+ justify-content: space-around;
104
+ align-items: center;
105
+ gap: 20px;
106
+ margin-bottom: 20px;
107
+ padding: 20px;
108
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
109
+ border-radius: 15px;
110
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
111
+ }
112
+
113
+ .player-score {
114
+ text-align: center;
115
+ }
116
+
117
+ .player-score h3 {
118
+ color: rgba(255, 255, 255, 0.9);
119
+ font-size: 1rem;
120
+ margin-bottom: 8px;
121
+ }
122
+
123
+ .score {
124
+ color: white;
125
+ font-size: 3rem;
126
+ font-weight: bold;
127
+ font-family: 'Courier New', monospace;
128
+ }
129
+
130
+ .divider {
131
+ color: white;
132
+ font-size: 3rem;
133
+ font-weight: bold;
134
+ }
135
+
136
+ #gameCanvas {
137
+ display: block;
138
+ width: 100%;
139
+ max-width: 800px;
140
+ height: auto;
141
+ aspect-ratio: 8/5;
142
+ margin: 0 auto 20px;
143
+ border-radius: 10px;
144
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
145
+ }
146
+
147
+ .controls {
148
+ display: flex;
149
+ gap: 15px;
150
+ justify-content: center;
151
+ margin-bottom: 20px;
152
+ flex-wrap: wrap;
153
+ }
154
+
155
+ .btn {
156
+ padding: 12px 30px;
157
+ font-size: 1rem;
158
+ font-weight: 600;
159
+ border: none;
160
+ border-radius: 8px;
161
+ cursor: pointer;
162
+ transition: all 0.3s ease;
163
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
164
+ min-width: 120px;
165
+ }
166
+
167
+ .btn:hover:not(:disabled) {
168
+ transform: translateY(-2px);
169
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
170
+ }
171
+
172
+ .btn:active:not(:disabled) {
173
+ transform: translateY(0);
174
+ }
175
+
176
+ .btn:disabled {
177
+ opacity: 0.5;
178
+ cursor: not-allowed;
179
+ }
180
+
181
+ .btn-primary {
182
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
183
+ color: white;
184
+ }
185
+
186
+ .btn-secondary {
187
+ background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
188
+ color: white;
189
+ }
190
+
191
+ .btn-danger {
192
+ background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
193
+ color: white;
194
+ }
195
+
196
+ .result-message {
197
+ text-align: center;
198
+ padding: 15px;
199
+ border-radius: 10px;
200
+ font-size: 1.3rem;
201
+ font-weight: bold;
202
+ margin-bottom: 20px;
203
+ display: none;
204
+ }
205
+
206
+ .result-message.success {
207
+ background: #c6f6d5;
208
+ color: #22543d;
209
+ border: 2px solid #9ae6b4;
210
+ }
211
+
212
+ .result-message.error {
213
+ background: #fed7d7;
214
+ color: #742a2a;
215
+ border: 2px solid #fc8181;
216
+ }
217
+
218
+ .result-message.info {
219
+ background: #bee3f8;
220
+ color: #2c5282;
221
+ border: 2px solid #90cdf4;
222
+ }
223
+
224
+ .instructions {
225
+ background: #f7fafc;
226
+ padding: 20px;
227
+ border-radius: 10px;
228
+ border: 2px solid #e2e8f0;
229
+ }
230
+
231
+ .instructions h3 {
232
+ color: #2d3748;
233
+ margin-bottom: 15px;
234
+ font-size: 1.1rem;
235
+ text-align: center;
236
+ }
237
+
238
+ .controls-grid {
239
+ display: grid;
240
+ grid-template-columns: 1fr 1fr;
241
+ gap: 20px;
242
+ margin-bottom: 15px;
243
+ }
244
+
245
+ .control-item {
246
+ text-align: center;
247
+ }
248
+
249
+ .control-item strong {
250
+ display: block;
251
+ margin-bottom: 10px;
252
+ color: #2d3748;
253
+ }
254
+
255
+ .keys {
256
+ display: flex;
257
+ align-items: center;
258
+ justify-content: center;
259
+ gap: 10px;
260
+ margin-bottom: 8px;
261
+ }
262
+
263
+ .key {
264
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
265
+ color: white;
266
+ padding: 8px 12px;
267
+ border-radius: 6px;
268
+ font-weight: bold;
269
+ min-width: 40px;
270
+ text-align: center;
271
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
272
+ }
273
+
274
+ .keys span:last-child {
275
+ color: #4a5568;
276
+ font-size: 0.9rem;
277
+ }
278
+
279
+ .rules {
280
+ list-style: none;
281
+ padding-right: 0;
282
+ margin-top: 15px;
283
+ }
284
+
285
+ .rules li {
286
+ color: #4a5568;
287
+ margin-bottom: 8px;
288
+ padding-right: 20px;
289
+ position: relative;
290
+ line-height: 1.6;
291
+ }
292
+
293
+ .rules li:before {
294
+ content: "•";
295
+ color: #667eea;
296
+ font-weight: bold;
297
+ position: absolute;
298
+ right: 0;
299
+ font-size: 1.2rem;
300
+ }
301
+
302
+ /* Responsive */
303
+ @media (max-width: 768px) {
304
+ .container {
305
+ padding: 20px;
306
+ }
307
+
308
+ .header h1 {
309
+ font-size: 2rem;
310
+ }
311
+
312
+ .score {
313
+ font-size: 2.5rem;
314
+ }
315
+
316
+ .divider {
317
+ font-size: 2.5rem;
318
+ }
319
+
320
+ .controls-grid {
321
+ grid-template-columns: 1fr;
322
+ }
323
+
324
+ .game-mode {
325
+ flex-direction: column;
326
+ align-items: stretch;
327
+ }
328
+
329
+ .mode-btn {
330
+ width: 100%;
331
+ }
332
+
333
+ .controls {
334
+ gap: 10px;
335
+ }
336
+
337
+ .btn {
338
+ padding: 10px 20px;
339
+ min-width: 100px;
340
+ font-size: 0.9rem;
341
+ }
342
+ }
343
+
344
+ @media (max-width: 480px) {
345
+ .header h1 {
346
+ font-size: 1.5rem;
347
+ }
348
+
349
+ .subtitle {
350
+ font-size: 0.95rem;
351
+ }
352
+
353
+ .score-board {
354
+ padding: 15px;
355
+ gap: 15px;
356
+ }
357
+
358
+ .score {
359
+ font-size: 2rem;
360
+ }
361
+
362
+ .divider {
363
+ font-size: 2rem;
364
+ }
365
+
366
+ .key {
367
+ padding: 6px 10px;
368
+ min-width: 35px;
369
+ font-size: 0.9rem;
370
+ }
371
+ }