create-template-html-css 1.9.0 → 2.0.1

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 (54) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/COMPONENTS-GALLERY.html +735 -747
  3. package/README.md +179 -2
  4. package/bin/cli.js +15 -3
  5. package/package.json +1 -1
  6. package/templates/blackjack/index.html +97 -0
  7. package/templates/blackjack/script.js +381 -0
  8. package/templates/blackjack/style.css +452 -0
  9. package/templates/breakout/index.html +56 -0
  10. package/templates/breakout/script.js +387 -0
  11. package/templates/breakout/style.css +239 -0
  12. package/templates/connect-four/index.html +78 -0
  13. package/templates/connect-four/script.js +413 -0
  14. package/templates/connect-four/style.css +426 -0
  15. package/templates/dice-game/index.html +99 -0
  16. package/templates/dice-game/script.js +291 -0
  17. package/templates/dice-game/style.css +403 -0
  18. package/templates/flappy-bird/index.html +47 -0
  19. package/templates/flappy-bird/script.js +394 -0
  20. package/templates/flappy-bird/style.css +243 -0
  21. package/templates/game-2048/index.html +59 -0
  22. package/templates/game-2048/script.js +269 -0
  23. package/templates/game-2048/style.css +281 -0
  24. package/templates/pong/index.html +90 -0
  25. package/templates/pong/script.js +364 -0
  26. package/templates/pong/style.css +371 -0
  27. package/templates/rock-paper-scissors/index.html +84 -0
  28. package/templates/rock-paper-scissors/script.js +199 -0
  29. package/templates/rock-paper-scissors/style.css +295 -0
  30. package/templates/simon-says/index.html +64 -0
  31. package/templates/simon-says/script.js +206 -0
  32. package/templates/simon-says/style.css +250 -0
  33. package/templates/slot-machine/index.html +112 -0
  34. package/templates/slot-machine/script.js +238 -0
  35. package/templates/slot-machine/style.css +464 -0
  36. package/templates/tetris/index.html +84 -0
  37. package/templates/tetris/script.js +447 -0
  38. package/templates/tetris/style.css +286 -0
  39. package/templates/whack-a-mole/index.html +85 -0
  40. package/templates/whack-a-mole/script.js +172 -0
  41. package/{demo-games/snake-game → templates/whack-a-mole}/style.css +114 -97
  42. package/PUBLISH-GUIDE.md +0 -112
  43. package/create-template-html-css-1.8.0.tgz +0 -0
  44. package/demo-games/guess-number/index.html +0 -71
  45. package/demo-games/guess-number/script.js +0 -216
  46. package/demo-games/guess-number/style.css +0 -337
  47. package/demo-games/memory-game/index.html +0 -50
  48. package/demo-games/memory-game/script.js +0 -216
  49. package/demo-games/memory-game/style.css +0 -288
  50. package/demo-games/snake-game/index.html +0 -61
  51. package/demo-games/snake-game/script.js +0 -360
  52. package/demo-games/tic-tac-toe/index.html +0 -57
  53. package/demo-games/tic-tac-toe/script.js +0 -156
  54. package/demo-games/tic-tac-toe/style.css +0 -244
@@ -6,7 +6,7 @@
6
6
 
7
7
  body {
8
8
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
9
+ background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
10
10
  min-height: 100vh;
11
11
  display: flex;
12
12
  justify-content: center;
@@ -16,7 +16,7 @@ body {
16
16
 
17
17
  .container {
18
18
  width: 100%;
19
- max-width: 500px;
19
+ max-width: 600px;
20
20
  }
21
21
 
22
22
  .game-card {
@@ -33,113 +33,146 @@ body {
33
33
  font-size: 2.5rem;
34
34
  }
35
35
 
36
- .game-info {
36
+ .game-stats {
37
37
  display: flex;
38
- justify-content: space-between;
38
+ justify-content: space-around;
39
39
  padding: 15px;
40
40
  background: #f3f4f6;
41
41
  border-radius: 12px;
42
42
  margin-bottom: 20px;
43
43
  }
44
44
 
45
- .info-item {
46
- display: flex;
47
- flex-direction: column;
48
- align-items: center;
45
+ .stat {
46
+ text-align: center;
49
47
  }
50
48
 
51
- .label {
49
+ .stat-label {
52
50
  font-size: 0.9rem;
53
51
  color: #6b7280;
54
52
  margin-bottom: 5px;
55
53
  }
56
54
 
57
- .value {
58
- font-size: 1.3rem;
55
+ .stat-value {
56
+ font-size: 1.5rem;
59
57
  font-weight: bold;
60
58
  color: #333;
61
59
  }
62
60
 
63
- #gameCanvas {
64
- width: 100%;
65
- max-width: 400px;
66
- height: auto;
67
- display: block;
68
- margin: 0 auto 20px;
61
+ .difficulty-selector {
62
+ display: flex;
63
+ justify-content: center;
64
+ align-items: center;
65
+ gap: 10px;
66
+ margin-bottom: 20px;
67
+ font-weight: 600;
68
+ color: #555;
69
+ }
70
+
71
+ #difficulty {
72
+ padding: 8px 15px;
73
+ border: 2px solid #e5e7eb;
69
74
  border-radius: 8px;
70
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
75
+ font-size: 1rem;
76
+ cursor: pointer;
77
+ background: white;
71
78
  }
72
79
 
73
- .message {
74
- text-align: center;
75
- font-size: 1.1rem;
76
- font-weight: 600;
77
- height: 35px;
80
+ #difficulty:disabled {
81
+ opacity: 0.5;
82
+ cursor: not-allowed;
83
+ }
84
+
85
+ .game-board {
86
+ display: grid;
87
+ grid-template-columns: repeat(3, 1fr);
88
+ gap: 15px;
89
+ margin: 20px 0;
90
+ padding: 20px;
91
+ background: #f9fafb;
92
+ border-radius: 12px;
93
+ }
94
+
95
+ .hole {
96
+ aspect-ratio: 1;
97
+ background: linear-gradient(to bottom, #8b4513 0%, #654321 100%);
98
+ border-radius: 50% 50% 0 0;
99
+ position: relative;
100
+ overflow: hidden;
101
+ cursor: pointer;
102
+ box-shadow: inset 0 -4px 8px rgba(0, 0, 0, 0.3);
103
+ }
104
+
105
+ .mole {
106
+ position: absolute;
107
+ width: 100%;
108
+ height: 100%;
109
+ bottom: -100%;
78
110
  display: flex;
79
111
  justify-content: center;
80
112
  align-items: center;
81
- margin-bottom: 20px;
82
- color: #6b7280;
83
- opacity: 0;
84
- transition: opacity 0.3s ease;
113
+ font-size: 3rem;
114
+ transition: bottom 0.3s ease;
115
+ user-select: none;
85
116
  }
86
117
 
87
- .message.show {
88
- opacity: 1;
89
- animation: pulse 1.5s ease-in-out infinite;
118
+ .mole.up {
119
+ bottom: 0;
90
120
  }
91
121
 
92
- .message.game-over {
93
- color: #ef4444;
94
- font-size: 1.2rem;
122
+ .mole.whacked {
123
+ animation: whack 0.3s ease;
95
124
  }
96
125
 
97
- @keyframes pulse {
98
- 0%, 100% {
99
- opacity: 1;
126
+ @keyframes whack {
127
+ 0% {
128
+ transform: scale(1) rotate(0deg);
100
129
  }
101
130
  50% {
102
- opacity: 0.6;
131
+ transform: scale(1.2) rotate(10deg);
132
+ }
133
+ 100% {
134
+ transform: scale(0.8) rotate(-10deg);
135
+ bottom: -100%;
103
136
  }
104
137
  }
105
138
 
106
- .controls {
107
- margin-bottom: 20px;
139
+ @keyframes shake {
140
+ 0%, 100% {
141
+ transform: translateX(0);
142
+ }
143
+ 25% {
144
+ transform: translateX(-5px);
145
+ }
146
+ 75% {
147
+ transform: translateX(5px);
148
+ }
108
149
  }
109
150
 
110
- .arrow-buttons {
151
+ .message {
152
+ text-align: center;
153
+ font-size: 1.2rem;
154
+ font-weight: bold;
155
+ height: 35px;
111
156
  display: flex;
112
- flex-direction: column;
157
+ justify-content: center;
113
158
  align-items: center;
114
- gap: 5px;
115
- }
116
-
117
- .arrow-row {
118
- display: flex;
119
- gap: 5px;
120
- }
121
-
122
- .arrow-btn {
123
- width: 60px;
124
- height: 60px;
125
- border: 2px solid #e5e7eb;
126
- border-radius: 8px;
127
- background: white;
128
- font-size: 1.5rem;
129
- cursor: pointer;
130
- transition: all 0.2s ease;
131
- color: #333;
159
+ margin-bottom: 20px;
160
+ color: #10b981;
132
161
  }
133
162
 
134
- .arrow-btn:hover {
135
- background: #f3f4f6;
136
- border-color: #9ca3af;
137
- transform: scale(1.05);
163
+ .message.show {
164
+ animation: slideDown 0.4s ease;
138
165
  }
139
166
 
140
- .arrow-btn:active {
141
- transform: scale(0.95);
142
- background: #e5e7eb;
167
+ @keyframes slideDown {
168
+ from {
169
+ transform: translateY(-20px);
170
+ opacity: 0;
171
+ }
172
+ to {
173
+ transform: translateY(0);
174
+ opacity: 1;
175
+ }
143
176
  }
144
177
 
145
178
  .button-group {
@@ -150,7 +183,7 @@ body {
150
183
 
151
184
  .btn {
152
185
  flex: 1;
153
- padding: 12px 20px;
186
+ padding: 12px 24px;
154
187
  border: none;
155
188
  border-radius: 8px;
156
189
  font-size: 1rem;
@@ -184,26 +217,22 @@ body {
184
217
  box-shadow: 0 5px 15px rgba(245, 158, 11, 0.4);
185
218
  }
186
219
 
187
- .btn-danger {
188
- background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
189
- color: white;
190
- }
191
-
192
- .btn-danger:hover:not(:disabled) {
193
- transform: translateY(-2px);
194
- box-shadow: 0 5px 15px rgba(239, 68, 68, 0.4);
195
- }
196
-
197
220
  .instructions {
198
221
  background: #f9fafb;
199
222
  border-radius: 8px;
200
223
  padding: 15px;
201
- font-size: 0.9rem;
202
- color: #6b7280;
224
+ }
225
+
226
+ .instructions h3 {
227
+ color: #333;
228
+ margin-bottom: 10px;
229
+ font-size: 1.1rem;
203
230
  }
204
231
 
205
232
  .instructions p {
206
- margin-bottom: 8px;
233
+ color: #6b7280;
234
+ font-size: 0.9rem;
235
+ margin-bottom: 5px;
207
236
  }
208
237
 
209
238
  .instructions p:last-child {
@@ -219,28 +248,16 @@ body {
219
248
  font-size: 2rem;
220
249
  }
221
250
 
222
- .game-info {
223
- flex-direction: column;
224
- gap: 10px;
225
- }
226
-
227
- .info-item {
228
- flex-direction: row;
229
- justify-content: space-between;
230
- width: 100%;
251
+ .mole {
252
+ font-size: 2rem;
231
253
  }
232
254
 
233
- .arrow-btn {
234
- width: 50px;
235
- height: 50px;
236
- font-size: 1.2rem;
255
+ .game-board {
256
+ gap: 10px;
257
+ padding: 15px;
237
258
  }
238
259
 
239
260
  .button-group {
240
261
  flex-direction: column;
241
262
  }
242
-
243
- .instructions {
244
- font-size: 0.85rem;
245
- }
246
263
  }
package/PUBLISH-GUIDE.md DELETED
@@ -1,112 +0,0 @@
1
- # Publishing Guide for v1.8.0
2
-
3
- ## Pre-Publish Checklist ✅
4
-
5
- - [x] Version updated to 1.8.0 in package.json
6
- - [x] Version updated to 1.8.0 in bin/cli.js
7
- - [x] README.md updated with all features
8
- - [x] CHANGELOG.md updated with v1.8.0 features
9
- - [x] All commits pushed to GitHub
10
- - [x] Security audit passed (npm audit: 0 vulnerabilities)
11
- - [x] No Hebrew text in codebase
12
- - [x] Path traversal protection added
13
- - [x] Input validation verified
14
- - [x] All 26 components available and tested
15
-
16
- ## Features in v1.8.0
17
-
18
- ### 🌙 Dark Mode Support
19
- - Automatic `prefers-color-scheme: dark` detection
20
- - `--dark-mode` flag to enable dark theme support
21
-
22
- ### 🎨 Color Customizer with Presets
23
- - 10 preset color schemes: vibrant, pastel, ocean, sunset, forest, purple, minimal, coral, teal, neon
24
- - `--color-scheme` flag for preset selection
25
- - Interactive CLI color selection (preset/custom/skip)
26
- - Hex color validation
27
- - Automatic RGB conversion for rgba() support
28
-
29
- ### 📊 Interactive Component Gallery
30
- - Browse all 26 components with descriptions
31
- - Search and filter by category
32
- - Live color scheme preview with hex values
33
- - Copy commands (both npx and local)
34
- - Dark mode support
35
- - Print-friendly layout
36
- - Mobile responsive design
37
-
38
- ### 🎪 Gallery Command
39
- - `create-template gallery` opens COMPONENTS-GALLERY.html in browser
40
- - Cross-platform support (Windows, macOS, Linux)
41
-
42
- ### 📦 Package Updates
43
- - Added `open` dependency for cross-platform file opening
44
- - Updated .npmignore to exclude development files
45
- - All dependencies verified and security audited
46
-
47
- ## Publishing Steps
48
-
49
- ### 1. Login to npm (if not already logged in)
50
- ```bash
51
- npm login
52
- ```
53
-
54
- ### 2. Verify package contents
55
- ```bash
56
- npm pack
57
- # This creates a .tgz file showing what will be published
58
- tar -tzf create-template-html-css-1.8.0.tgz | head -20
59
- ```
60
-
61
- ### 3. Publish to npm
62
- ```bash
63
- npm publish
64
- ```
65
-
66
- ### 4. Verify published package
67
- ```bash
68
- npm info create-template-html-css
69
- npm view create-template-html-css@1.8.0
70
- ```
71
-
72
- ### 5. Test installation from npm
73
- ```bash
74
- npm install -g create-template-html-css@1.8.0
75
- create-template --version
76
- create-template list
77
- create-template gallery
78
- ```
79
-
80
- ### 6. Push commits to GitHub
81
- ```bash
82
- git push origin main
83
- ```
84
-
85
- ## Post-Publish Tasks
86
-
87
- - [ ] Add release tag: `git tag -a v1.8.0 -m "Release v1.8.0"`
88
- - [ ] Push tags: `git push origin v1.8.0`
89
- - [ ] Create GitHub Release with changelog
90
- - [ ] Update social media/documentation sites
91
- - [ ] Monitor npm page for feedback
92
-
93
- ## Package Statistics
94
-
95
- - **Version**: 1.8.0
96
- - **License**: MIT
97
- - **Repository**: https://github.com/benshabbat/create-template-html-css
98
- - **NPM**: https://www.npmjs.com/package/create-template-html-css
99
- - **Components**: 26 total
100
- - **Color Schemes**: 10 presets
101
- - **Dependencies**: 3 (chalk, commander, inquirer, open)
102
- - **DevDependencies**: 1 (prettier)
103
-
104
- ## Security & Quality
105
-
106
- - ✅ No vulnerabilities (npm audit: 0)
107
- - ✅ Path traversal protection implemented
108
- - ✅ Input validation on all user inputs
109
- - ✅ Component whitelist validation
110
- - ✅ HTML structure validation
111
- - ✅ Cross-platform support verified
112
- - ✅ All code is English (no Hebrew text)
Binary file
@@ -1,71 +0,0 @@
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>{{name}} - Guess Number</title>
7
- <link rel="stylesheet" href="style.css">
8
- </head>
9
- <body>
10
- <div class="container">
11
- <div class="game-card">
12
- <h1>🎯 Guess the Number</h1>
13
-
14
- <div class="game-info">
15
- <div class="info-row">
16
- <span class="label">Range:</span>
17
- <span id="rangeDisplay" class="value">1 - 100</span>
18
- </div>
19
- <div class="info-row">
20
- <span class="label">Attempts:</span>
21
- <span id="attempts" class="value">0</span>
22
- </div>
23
- <div class="info-row">
24
- <span class="label">Best Score:</span>
25
- <span id="bestScore" class="value">-</span>
26
- </div>
27
- </div>
28
-
29
- <div class="hint-section">
30
- <div class="hint-box" id="hintBox">
31
- <p id="hintText">I'm thinking of a number...</p>
32
- <p id="hintDetails">Make your first guess!</p>
33
- </div>
34
- </div>
35
-
36
- <div class="input-section">
37
- <input
38
- type="number"
39
- id="guessInput"
40
- placeholder="Enter your guess"
41
- min="1"
42
- max="100"
43
- />
44
- <button id="guessBtn" class="btn btn-primary">Guess</button>
45
- </div>
46
-
47
- <div class="history-section">
48
- <h3>Previous Guesses</h3>
49
- <div id="guessHistory" class="guess-history">
50
- <p class="empty-state">No guesses yet</p>
51
- </div>
52
- </div>
53
-
54
- <div class="difficulty-section">
55
- <h3>Difficulty</h3>
56
- <div class="difficulty-buttons">
57
- <button class="difficulty-btn active" data-range="100">Easy (1-100)</button>
58
- <button class="difficulty-btn" data-range="500">Medium (1-500)</button>
59
- <button class="difficulty-btn" data-range="1000">Hard (1-1000)</button>
60
- </div>
61
- </div>
62
-
63
- <div class="button-group">
64
- <button id="newGameBtn" class="btn btn-success">New Game</button>
65
- <button id="giveUpBtn" class="btn btn-secondary">Give Up</button>
66
- </div>
67
- </div>
68
- </div>
69
- <script src="script.js"></script>
70
- </body>
71
- </html>
@@ -1,216 +0,0 @@
1
- // Guess the Number Game Logic
2
-
3
- const guessInput = document.getElementById('guessInput');
4
- const guessBtn = document.getElementById('guessBtn');
5
- const newGameBtn = document.getElementById('newGameBtn');
6
- const giveUpBtn = document.getElementById('giveUpBtn');
7
- const attemptsDisplay = document.getElementById('attempts');
8
- const bestScoreDisplay = document.getElementById('bestScore');
9
- const rangeDisplay = document.getElementById('rangeDisplay');
10
- const hintBox = document.getElementById('hintBox');
11
- const hintText = document.getElementById('hintText');
12
- const hintDetails = document.getElementById('hintDetails');
13
- const guessHistory = document.getElementById('guessHistory');
14
- const difficultyBtns = document.querySelectorAll('.difficulty-btn');
15
-
16
- let targetNumber = 0;
17
- let attempts = 0;
18
- let maxRange = 100;
19
- let guesses = [];
20
- let bestScores = {
21
- 100: localStorage.getItem('bestScore100') || null,
22
- 500: localStorage.getItem('bestScore500') || null,
23
- 1000: localStorage.getItem('bestScore1000') || null
24
- };
25
- let gameActive = true;
26
-
27
- // Initialize game
28
- function initGame() {
29
- targetNumber = Math.floor(Math.random() * maxRange) + 1;
30
- attempts = 0;
31
- guesses = [];
32
- gameActive = true;
33
-
34
- updateDisplay();
35
- guessInput.value = '';
36
- guessInput.disabled = false;
37
- guessBtn.disabled = false;
38
- guessInput.focus();
39
-
40
- hintBox.className = 'hint-box';
41
- hintText.textContent = "I'm thinking of a number...";
42
- hintDetails.textContent = 'Make your first guess!';
43
-
44
- guessHistory.innerHTML = '<p class="empty-state">No guesses yet</p>';
45
- }
46
-
47
- // Make a guess
48
- function makeGuess() {
49
- if (!gameActive) return;
50
-
51
- const guess = parseInt(guessInput.value);
52
-
53
- // Validate input
54
- if (isNaN(guess) || guess < 1 || guess > maxRange) {
55
- showHint('invalid', '⚠️ Invalid Input', `Please enter a number between 1 and ${maxRange}`);
56
- return;
57
- }
58
-
59
- // Check if already guessed
60
- if (guesses.includes(guess)) {
61
- showHint('duplicate', '🔄 Already Guessed', 'You already tried this number!');
62
- return;
63
- }
64
-
65
- attempts++;
66
- guesses.push(guess);
67
- updateDisplay();
68
- addToHistory(guess);
69
-
70
- // Check if correct
71
- if (guess === targetNumber) {
72
- handleWin();
73
- } else if (guess < targetNumber) {
74
- const diff = targetNumber - guess;
75
- if (diff <= 5) {
76
- showHint('hot', '🔥 Very Hot!', 'You\'re super close! Go higher!');
77
- } else if (diff <= 10) {
78
- showHint('warm', '🌡️ Hot!', 'Getting closer! Go higher!');
79
- } else if (diff <= 20) {
80
- showHint('cool', '❄️ Warm', 'Go higher!');
81
- } else {
82
- showHint('cold', '🧊 Cold', 'Too low! Go much higher!');
83
- }
84
- } else {
85
- const diff = guess - targetNumber;
86
- if (diff <= 5) {
87
- showHint('hot', '🔥 Very Hot!', 'You\'re super close! Go lower!');
88
- } else if (diff <= 10) {
89
- showHint('warm', '🌡️ Hot!', 'Getting closer! Go lower!');
90
- } else if (diff <= 20) {
91
- showHint('cool', '❄️ Warm', 'Go lower!');
92
- } else {
93
- showHint('cold', '🧊 Cold', 'Too high! Go much lower!');
94
- }
95
- }
96
-
97
- guessInput.value = '';
98
- guessInput.focus();
99
- }
100
-
101
- // Handle win
102
- function handleWin() {
103
- gameActive = false;
104
- guessInput.disabled = true;
105
- guessBtn.disabled = true;
106
-
107
- showHint('win', '🎉 Congratulations!', `You found it in ${attempts} attempts!`);
108
-
109
- // Update best score
110
- if (!bestScores[maxRange] || attempts < bestScores[maxRange]) {
111
- bestScores[maxRange] = attempts;
112
- localStorage.setItem(`bestScore${maxRange}`, attempts);
113
- bestScoreDisplay.textContent = attempts;
114
-
115
- // Show new record message
116
- setTimeout(() => {
117
- hintDetails.textContent = `🏆 New Record: ${attempts} attempts!`;
118
- }, 1500);
119
- }
120
- }
121
-
122
- // Give up
123
- function giveUp() {
124
- if (!gameActive) return;
125
-
126
- gameActive = false;
127
- guessInput.disabled = true;
128
- guessBtn.disabled = true;
129
-
130
- showHint('give-up', '😔 Game Over', `The number was ${targetNumber}`);
131
- }
132
-
133
- // Show hint
134
- function showHint(type, title, details) {
135
- hintBox.className = `hint-box ${type}`;
136
- hintText.textContent = title;
137
- hintDetails.textContent = details;
138
-
139
- // Animate
140
- hintBox.style.animation = 'none';
141
- setTimeout(() => {
142
- hintBox.style.animation = 'bounceIn 0.5s ease';
143
- }, 10);
144
- }
145
-
146
- // Add to history
147
- function addToHistory(guess) {
148
- if (guesses.length === 1) {
149
- guessHistory.innerHTML = '';
150
- }
151
-
152
- const guessItem = document.createElement('div');
153
- guessItem.className = 'guess-item';
154
-
155
- let icon = '';
156
- if (guess === targetNumber) {
157
- icon = '🎯';
158
- guessItem.classList.add('correct');
159
- } else if (Math.abs(guess - targetNumber) <= 5) {
160
- icon = '🔥';
161
- } else if (Math.abs(guess - targetNumber) <= 10) {
162
- icon = '🌡️';
163
- } else if (Math.abs(guess - targetNumber) <= 20) {
164
- icon = '❄️';
165
- } else {
166
- icon = '🧊';
167
- }
168
-
169
- guessItem.innerHTML = `
170
- <span class="guess-number">${guess}</span>
171
- <span class="guess-icon">${icon}</span>
172
- `;
173
-
174
- guessHistory.prepend(guessItem);
175
- }
176
-
177
- // Update display
178
- function updateDisplay() {
179
- attemptsDisplay.textContent = attempts;
180
- bestScoreDisplay.textContent = bestScores[maxRange] || '-';
181
- rangeDisplay.textContent = `1 - ${maxRange}`;
182
- guessInput.setAttribute('max', maxRange);
183
- guessInput.setAttribute('placeholder', `Enter number (1-${maxRange})`);
184
- }
185
-
186
- // Change difficulty
187
- function changeDifficulty(newRange) {
188
- maxRange = parseInt(newRange);
189
-
190
- // Update active button
191
- difficultyBtns.forEach(btn => {
192
- btn.classList.toggle('active', parseInt(btn.dataset.range) === maxRange);
193
- });
194
-
195
- initGame();
196
- }
197
-
198
- // Event listeners
199
- guessBtn.addEventListener('click', makeGuess);
200
- newGameBtn.addEventListener('click', initGame);
201
- giveUpBtn.addEventListener('click', giveUp);
202
-
203
- guessInput.addEventListener('keypress', (e) => {
204
- if (e.key === 'Enter') {
205
- makeGuess();
206
- }
207
- });
208
-
209
- difficultyBtns.forEach(btn => {
210
- btn.addEventListener('click', () => {
211
- changeDifficulty(btn.dataset.range);
212
- });
213
- });
214
-
215
- // Initialize on load
216
- initGame();