Refactor and improve Pokedex code with animations and dark mode

#2
by smolSWE - opened
Files changed (2) hide show
  1. index.html +495 -1091
  2. style.css +59 -28
index.html CHANGED
@@ -1,1092 +1,496 @@
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>Gen 1 Pokedex | First 50 Pokémon</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
- <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
10
- <script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
11
- <style>
12
- body {
13
- font-family: 'Press Start 2P', cursive;
14
- background-color: #f0f0f0;
15
- color: #333;
16
- }
17
- .pokemon-card {
18
- transition: all 0.3s ease;
19
- transform-style: preserve-3d;
20
- }
21
- .pokemon-card:hover {
22
- transform: translateY(-5px) rotateY(5deg);
23
- box-shadow: 0 10px 20px rgba(0,0,0,0.2);
24
- }
25
- .pokemon-card-inner {
26
- transition: transform 0.6s;
27
- transform-style: preserve-3d;
28
- }
29
- .pokemon-card:hover .pokemon-card-inner {
30
- transform: rotateY(10deg);
31
- }
32
- @keyframes float {
33
- 0%, 100% { transform: translateY(0); }
34
- 50% { transform: translateY(-10px); }
35
- }
36
- .floating {
37
- animation: float 3s ease-in-out infinite;
38
- }
39
- .pokemon-sprite {
40
- transition: transform 0.3s;
41
- }
42
- .pokemon-sprite:hover {
43
- transform: scale(1.1);
44
- }
45
- .type-bug { background-color: #A8B820; }
46
- .type-dark { background-color: #705848; }
47
- .type-dragon { background-color: #7038F8; }
48
- .type-electric { background-color: #F8D030; }
49
- .type-fairy { background-color: #EE99AC; }
50
- .type-fighting { background-color: #C03028; }
51
- .type-fire { background-color: #F08030; }
52
- .type-flying { background-color: #A890F0; }
53
- .type-ghost { background-color: #705898; }
54
- .type-grass { background-color: #78C850; }
55
- .type-ground { background-color: #E0C068; }
56
- .type-ice { background-color: #98D8D8; }
57
- .type-normal { background-color: #A8A878; }
58
- .type-poison { background-color: #A040A0; }
59
- .type-psychic { background-color: #F85888; }
60
- .type-rock { background-color: #B8A038; }
61
- .type-steel { background-color: #B8B8D0; }
62
- .type-water { background-color: #6890F0; }
63
- </style>
64
- </head>
65
- <body class="min-h-screen bg-gray-100">
66
- <div class="container mx-auto px-4 py-8">
67
- <header class="text-center mb-8 relative overflow-hidden">
68
- <div class="absolute inset-0 bg-red-500 transform -skew-y-3 z-0 opacity-20"></div>
69
- <h1 class="text-4xl md:text-6xl font-bold relative z-10 mb-2 text-red-600">
70
- <span class="text-yellow-400">POKÉ</span>DEX
71
- </h1>
72
- <p class="text-lg md:text-xl relative z-10 text-gray-700">Generation 1 | Pokémon #1-50</p>
73
-
74
- <div class="absolute top-4 left-4 w-16 h-16 flex items-center justify-center rounded-full bg-red-500 shadow-md">
75
- <lottie-player src="https://assets8.lottiefiles.com/packages/lf20_b88nh30c.json" background="transparent" speed="1" style="width: 40px; height: 40px;" loop autoplay></lottie-player>
76
- </div>
77
- </header>
78
-
79
- <div class="flex justify-between items-center mb-6">
80
- <div class="relative w-64">
81
- <input type="text" id="search" placeholder="Search Pokémon..." class="w-full px-4 py-2 rounded-full border-2 border-gray-300 focus:outline-none focus:border-red-500 transition-all">
82
- <button class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-red-500 text-white rounded-full p-1">
83
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
84
- <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
85
- </svg>
86
- </button>
87
- </div>
88
- <div>
89
- <button id="toggle-view" class="bg-yellow-400 hover:bg-yellow-500 text-black px-4 py-2 rounded-md flex items-center transition-colors">
90
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
91
- <path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" />
92
- <path fill-rule="evenodd" d="M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z" clip-rule="evenodd" />
93
- </svg>
94
- Grid View
95
- </button>
96
- </div>
97
- </div>
98
-
99
- <!-- Type Filter -->
100
- <div class="mb-8">
101
- <h3 class="text-lg font-bold mb-2">Filter by Type:</h3>
102
- <div class="flex flex-wrap gap-2">
103
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white bg-red-500" data-type="all">All</button>
104
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-fire" data-type="fire">Fire</button>
105
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-water" data-type="water">Water</button>
106
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-grass" data-type="grass">Grass</button>
107
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-electric" data-type="electric">Electric</button>
108
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-normal" data-type="normal">Normal</button>
109
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-fighting" data-type="fighting">Fighting</button>
110
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-poison" data-type="poison">Poison</button>
111
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-ground" data-type="ground">Ground</button>
112
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-flying" data-type="flying">Flying</button>
113
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-psychic" data-type="psychic">Psychic</button>
114
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-bug" data-type="bug">Bug</button>
115
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-rock" data-type="rock">Rock</button>
116
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-ghost" data-type="ghost">Ghost</button>
117
- <button class="type-filter px-3 py-1 rounded-full text-xs text-white type-dragon" data-type="dragon">Dragon</button>
118
- </div>
119
- </div>
120
-
121
- <!-- Pokémon Grid View -->
122
- <div id="pokemon-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6">
123
- <!-- Pokémon cards will be inserted here by JavaScript -->
124
- </div>
125
-
126
- <!-- Stats Modal -->
127
- <div id="pokemon-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
128
- <div class="bg-white rounded-lg max-w-4xl w-full max-h-screen overflow-y-auto relative">
129
- <button id="close-modal" class="absolute top-4 right-4 bg-red-500 text-white rounded-full p-2 hover:bg-red-600 transition-colors">
130
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
131
- <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
132
- </svg>
133
- </button>
134
- <div class="p-8">
135
- <div id="modal-content" class="grid md:grid-cols-2 gap-8">
136
- <!-- Modal content will be inserted here by JavaScript -->
137
- </div>
138
- </div>
139
- </div>
140
- </div>
141
- </div>
142
-
143
- <script>
144
- // Pokémon Data (first 50 from Gen 1)
145
- const pokemonData = [
146
- {
147
- id: 1,
148
- name: "Bulbasaur",
149
- types: ["grass", "poison"],
150
- stats: { hp: 45, attack: 49, defense: 49, spAtk: 65, spDef: 65, speed: 45 },
151
- height: 0.7,
152
- weight: 6.9,
153
- description: "A strange seed was planted on its back at birth. The plant sprouts and grows with this Pokémon.",
154
- moves: ["Tackle", "Growl", "Vine Whip", "Leech Seed"],
155
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png",
156
- cry: "https://play.pokemonshowdown.com/audio/cries/1.mp3"
157
- },
158
- {
159
- id: 2,
160
- name: "Ivysaur",
161
- types: ["grass", "poison"],
162
- stats: { hp: 60, attack: 62, defense: 63, spAtk: 80, spDef: 80, speed: 60 },
163
- height: 1.0,
164
- weight: 13.0,
165
- description: "When the bulb on its back grows large, it appears to lose the ability to stand on its hind legs.",
166
- moves: ["Tackle", "Growl", "Vine Whip", "Razor Leaf"],
167
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/2.png",
168
- cry: "https://play.pokemonshowdown.com/audio/cries/2.mp3"
169
- },
170
- {
171
- id: 3,
172
- name: "Venusaur",
173
- types: ["grass", "poison"],
174
- stats: { hp: 80, attack: 82, defense: 83, spAtk: 100, spDef: 100, speed: 80 },
175
- height: 2.0,
176
- weight: 100.0,
177
- description: "The plant blooms when it is absorbing solar energy. It stays on the move to seek sunlight.",
178
- moves: ["Tackle", "Growl", "Vine Whip", "Solar Beam"],
179
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/3.png",
180
- cry: "https://play.pokemonshowdown.com/audio/cries/3.mp3"
181
- },
182
- {
183
- id: 4,
184
- name: "Charmander",
185
- types: ["fire"],
186
- stats: { hp: 39, attack: 52, defense: 43, spAtk: 60, spDef: 50, speed: 65 },
187
- height: 0.6,
188
- weight: 8.5,
189
- description: "Obviously prefers hot places. When it rains, steam is said to spout from the tip of its tail.",
190
- moves: ["Scratch", "Growl", "Ember", "Dragon Rage"],
191
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/4.png",
192
- cry: "https://play.pokemonshowdown.com/audio/cries/4.mp3"
193
- },
194
- {
195
- id: 5,
196
- name: "Charmeleon",
197
- types: ["fire"],
198
- stats: { hp: 58, attack: 64, defense: 58, spAtk: 80, spDef: 65, speed: 80 },
199
- height: 1.1,
200
- weight: 19.0,
201
- description: "When it swings its burning tail, it elevates the temperature to unbearably high levels.",
202
- moves: ["Scratch", "Growl", "Ember", "Flamethrower"],
203
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/5.png",
204
- cry: "https://play.pokemonshowdown.com/audio/cries/5.mp3"
205
- },
206
- {
207
- id: 6,
208
- name: "Charizard",
209
- types: ["fire", "flying"],
210
- stats: { hp: 78, attack: 84, defense: 78, spAtk: 109, spDef: 85, speed: 100 },
211
- height: 1.7,
212
- weight: 90.5,
213
- description: "Spits fire that is hot enough to melt boulders. Known to cause forest fires unintentionally.",
214
- moves: ["Scratch", "Growl", "Flamethrower", "Fire Blast"],
215
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png",
216
- cry: "https://play.pokemonshowdown.com/audio/cries/6.mp3"
217
- },
218
- {
219
- id: 7,
220
- name: "Squirtle",
221
- types: ["water"],
222
- stats: { hp: 44, attack: 48, defense: 65, spAtk: 50, spDef: 64, speed: 43 },
223
- height: 0.5,
224
- weight: 9.0,
225
- description: "After birth, its back swells and hardens into a shell. Powerfully sprays foam from its mouth.",
226
- moves: ["Tackle", "Tail Whip", "Water Gun", "Withdraw"],
227
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/7.png",
228
- cry: "https://play.pokemonshowdown.com/audio/cries/7.mp3"
229
- },
230
- {
231
- id: 8,
232
- name: "Wartortle",
233
- types: ["water"],
234
- stats: { hp: 59, attack: 63, defense: 80, spAtk: 65, spDef: 80, speed: 58 },
235
- height: 1.0,
236
- weight: 22.5,
237
- description: "Often hides in water to stalk unwary prey. For swimming fast, it moves its ears to maintain balance.",
238
- moves: ["Tackle", "Tail Whip", "Water Gun", "Bite"],
239
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/8.png",
240
- cry: "https://play.pokemonshowdown.com/audio/cries/8.mp3"
241
- },
242
- {
243
- id: 9,
244
- name: "Blastoise",
245
- types: ["water"],
246
- stats: { hp: 79, attack: 83, defense: 100, spAtk: 85, spDef: 105, speed: 78 },
247
- height: 1.6,
248
- weight: 85.5,
249
- description: "A brutal Pokémon with pressurized water jets on its shell. They are used for high speed tackles.",
250
- moves: ["Tackle", "Tail Whip", "Water Gun", "Hydro Pump"],
251
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/9.png",
252
- cry: "https://play.pokemonshowdown.com/audio/cries/9.mp3"
253
- },
254
- {
255
- id: 10,
256
- name: "Caterpie",
257
- types: ["bug"],
258
- stats: { hp: 45, attack: 30, defense: 35, spAtk: 20, spDef: 20, speed: 45 },
259
- height: 0.3,
260
- weight: 2.9,
261
- description: "Its short feet are tipped with suction pads that enable it to tirelessly climb slopes and walls.",
262
- moves: ["Tackle", "String Shot"],
263
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/10.png",
264
- cry: "https://play.pokemonshowdown.com/audio/cries/10.mp3"
265
- },
266
- {
267
- id: 11,
268
- name: "Metapod",
269
- types: ["bug"],
270
- stats: { hp: 50, attack: 20, defense: 55, spAtk: 25, spDef: 25, speed: 30 },
271
- height: 0.7,
272
- weight: 9.9,
273
- description: "This Pokémon is vulnerable to attack while its shell is soft, exposing its weak and tender body.",
274
- moves: ["Harden"],
275
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/11.png",
276
- cry: "https://play.pokemonshowdown.com/audio/cries/11.mp3"
277
- },
278
- {
279
- id: 12,
280
- name: "Butterfree",
281
- types: ["bug", "flying"],
282
- stats: { hp: 60, attack: 45, defense: 50, spAtk: 90, spDef: 80, speed: 70 },
283
- height: 1.1,
284
- weight: 32.0,
285
- description: "In battle, it flaps its wings at high speed to release highly toxic dust into the air.",
286
- moves: ["Confusion", "Poison Powder", "Stun Spore", "Sleep Powder"],
287
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/12.png",
288
- cry: "https://play.pokemonshowdown.com/audio/cries/12.mp3"
289
- },
290
- {
291
- id: 13,
292
- name: "Weedle",
293
- types: ["bug", "poison"],
294
- stats: { hp: 40, attack: 35, defense: 30, spAtk: 20, spDef: 20, speed: 50 },
295
- height: 0.3,
296
- weight: 3.2,
297
- description: "Often found in forests, eating leaves. It has a sharp venomous stinger on its head.",
298
- moves: ["Poison Sting", "String Shot"],
299
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/13.png",
300
- cry: "https://play.pokemonshowdown.com/audio/cries/13.mp3"
301
- },
302
- {
303
- id: 14,
304
- name: "Kakuna",
305
- types: ["bug", "poison"],
306
- stats: { hp: 45, attack: 25, defense: 50, spAtk: 25, spDef: 25, speed: 35 },
307
- height: 0.6,
308
- weight: 10.0,
309
- description: "Almost incapable of moving, this Pokémon can only harden its shell to protect itself from predators.",
310
- moves: ["Harden"],
311
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/14.png",
312
- cry: "https://play.pokemonshowdown.com/audio/cries/14.mp3"
313
- },
314
- {
315
- id: 15,
316
- name: "Beedrill",
317
- types: ["bug", "poison"],
318
- stats: { hp: 65, attack: 90, defense: 40, spAtk: 45, spDef: 80, speed: 75 },
319
- height: 1.0,
320
- weight: 29.5,
321
- description: "Flies at high speed and attacks using its large venomous stingers on its forelegs and tail.",
322
- moves: ["Fury Attack", "Focus Energy", "Twineedle"],
323
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/15.png",
324
- cry: "https://play.pokemonshowdown.com/audio/cries/15.mp3"
325
- },
326
- {
327
- id: 16,
328
- name: "Pidgey",
329
- types: ["normal", "flying"],
330
- stats: { hp: 40, attack: 45, defense: 40, spAtk: 35, spDef: 35, speed: 56 },
331
- height: 0.3,
332
- weight: 1.8,
333
- description: "A common sight in forests and woods. It flaps its wings at ground level to kick up blinding sand.",
334
- moves: ["Tackle", "Sand Attack", "Gust"],
335
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/16.png",
336
- cry: "https://play.pokemonshowdown.com/audio/cries/16.mp3"
337
- },
338
- {
339
- id: 17,
340
- name: "Pidgeotto",
341
- types: ["normal", "flying"],
342
- stats: { hp: 63, attack: 60, defense: 55, spAtk: 50, spDef: 50, speed: 71 },
343
- height: 1.1,
344
- weight: 30.0,
345
- description: "Very protective of its sprawling territorial area, this Pokémon will fiercely peck at any intruder.",
346
- moves: ["Tackle", "Sand Attack", "Gust", "Quick Attack"],
347
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/17.png",
348
- cry: "https://play.pokemonshowdown.com/audio/cries/17.mp3"
349
- },
350
- {
351
- id: 18,
352
- name: "Pidgeot",
353
- types: ["normal", "flying"],
354
- stats: { hp: 83, attack: 80, defense: 75, spAtk: 70, spDef: 70, speed: 101 },
355
- height: 1.5,
356
- weight: 39.5,
357
- description: "When hunting, it skims the surface of water at high speed to pick off unwary prey such as Magikarp.",
358
- moves: ["Tackle", "Sand Attack", "Gust", "Wing Attack"],
359
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/18.png",
360
- cry: "https://play.pokemonshowdown.com/audio/cries/18.mp3"
361
- },
362
- {
363
- id: 19,
364
- name: "Rattata",
365
- types: ["normal"],
366
- stats: { hp: 30, attack: 56, defense: 35, spAtk: 25, spDef: 35, speed: 72 },
367
- height: 0.3,
368
- weight: 3.5,
369
- description: "Bites anything when it attacks. Small and very quick, it is a common sight in many places.",
370
- moves: ["Tackle", "Tail Whip", "Quick Attack"],
371
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/19.png",
372
- cry: "https://play.pokemonshowdown.com/audio/cries/19.mp3"
373
- },
374
- {
375
- id: 20,
376
- name: "Raticate",
377
- types: ["normal"],
378
- stats: { hp: 55, attack: 81, defense: 60, spAtk: 50, spDef: 70, speed: 97 },
379
- height: 0.7,
380
- weight: 18.5,
381
- description: "It uses its whiskers to maintain its balance. It seems to slow down if they are cut off.",
382
- moves: ["Tackle", "Tail Whip", "Quick Attack", "Hyper Fang"],
383
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/20.png",
384
- cry: "https://play.pokemonshowdown.com/audio/cries/20.mp3"
385
- },
386
- {
387
- id: 21,
388
- name: "Spearow",
389
- types: ["normal", "flying"],
390
- stats: { hp: 40, attack: 60, defense: 30, spAtk: 31, spDef: 31, speed: 70 },
391
- height: 0.3,
392
- weight: 2.0,
393
- description: "Eats bugs in grassy areas. It has to flap its short wings at high speed to stay airborne.",
394
- moves: ["Peck", "Growl", "Leer"],
395
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/21.png",
396
- cry: "https://play.pokemonshowdown.com/audio/cries/21.mp3"
397
- },
398
- {
399
- id: 22,
400
- name: "Fearow",
401
- types: ["normal", "flying"],
402
- stats: { hp: 65, attack: 90, defense: 65, spAtk: 61, spDef: 61, speed: 100 },
403
- height: 1.2,
404
- weight: 38.0,
405
- description: "With its huge and magnificent wings, it can keep aloft without ever having to land for rest.",
406
- moves: ["Peck", "Growl", "Leer", "Fury Attack"],
407
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/22.png",
408
- cry: "https://play.pokemonshowdown.com/audio/cries/22.mp3"
409
- },
410
- {
411
- id: 23,
412
- name: "Ekans",
413
- types: ["poison"],
414
- stats: { hp: 35, attack: 60, defense: 44, spAtk: 40, spDef: 54, speed: 55 },
415
- height: 2.0,
416
- weight: 6.9,
417
- description: "Moves silently and stealthily. Eats the eggs of birds, such as Pidgey and Spearow, whole.",
418
- moves: ["Wrap", "Leer", "Poison Sting"],
419
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/23.png",
420
- cry: "https://play.pokemonshowdown.com/audio/cries/23.mp3"
421
- },
422
- {
423
- id: 24,
424
- name: "Arbok",
425
- types: ["poison"],
426
- stats: { hp: 60, attack: 85, defense: 69, spAtk: 65, spDef: 79, speed: 80 },
427
- height: 3.5,
428
- weight: 65.0,
429
- description: "It is rumored that the ferocious warning markings on its belly differ from area to area.",
430
- moves: ["Wrap", "Leer", "Poison Sting", "Bite"],
431
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/24.png",
432
- cry: "https://play.pokemonshowdown.com/audio/cries/24.mp3"
433
- },
434
- {
435
- id: 25,
436
- name: "Pikachu",
437
- types: ["electric"],
438
- stats: { hp: 35, attack: 55, defense: 40, spAtk: 50, spDef: 50, speed: 90 },
439
- height: 0.4,
440
- weight: 6.0,
441
- description: "When several of these Pokémon gather, their electricity could build and cause lightning storms.",
442
- moves: ["Thunder Shock", "Growl", "Tail Whip", "Quick Attack"],
443
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png",
444
- cry: "https://play.pokemonshowdown.com/audio/cries/25.mp3"
445
- },
446
- {
447
- id: 26,
448
- name: "Raichu",
449
- types: ["electric"],
450
- stats: { hp: 60, attack: 90, defense: 55, spAtk: 90, spDef: 80, speed: 110 },
451
- height: 0.8,
452
- weight: 30.0,
453
- description: "Its long tail serves as a ground to protect itself from its own high voltage power.",
454
- moves: ["Thunder Shock", "Growl", "Tail Whip", "Thunderbolt"],
455
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/26.png",
456
- cry: "https://play.pokemonshowdown.com/audio/cries/26.mp3"
457
- },
458
- {
459
- id: 27,
460
- name: "Sandshrew",
461
- types: ["ground"],
462
- stats: { hp: 50, attack: 75, defense: 85, spAtk: 20, spDef: 30, speed: 40 },
463
- height: 0.6,
464
- weight: 12.0,
465
- description: "Burrows deep underground in arid locations far from water. It only emerges to hunt for food.",
466
- moves: ["Scratch", "Defense Curl", "Sand Attack"],
467
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/27.png",
468
- cry: "https://play.pokemonshowdown.com/audio/cries/27.mp3"
469
- },
470
- {
471
- id: 28,
472
- name: "Sandslash",
473
- types: ["ground"],
474
- stats: { hp: 75, attack: 100, defense: 110, spAtk: 45, spDef: 55, speed: 65 },
475
- height: 1.0,
476
- weight: 29.5,
477
- description: "Curls up into a spiny ball when threatened. It can roll while curled up to attack or escape.",
478
- moves: ["Scratch", "Defense Curl", "Sand Attack", "Swift"],
479
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/28.png",
480
- cry: "https://play.pokemonshowdown.com/audio/cries/28.mp3"
481
- },
482
- {
483
- id: 29,
484
- name: "Nidoran♀",
485
- types: ["poison"],
486
- stats: { hp: 55, attack: 47, defense: 52, spAtk: 40, spDef: 40, speed: 41 },
487
- height: 0.4,
488
- weight: 7.0,
489
- description: "Although small, its venomous barbs render this Pokémon dangerous. The female has smaller horns.",
490
- moves: ["Growl", "Tackle", "Scratch"],
491
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/29.png",
492
- cry: "https://play.pokemonshowdown.com/audio/cries/29.mp3"
493
- },
494
- {
495
- id: 30,
496
- name: "Nidorina",
497
- types: ["poison"],
498
- stats: { hp: 70, attack: 62, defense: 67, spAtk: 55, spDef: 55, speed: 56 },
499
- height: 0.8,
500
- weight: 20.0,
501
- description: "The female's horn develops slowly. Prefers physical attacks such as clawing and biting.",
502
- moves: ["Growl", "Tackle", "Scratch", "Double Kick"],
503
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/30.png",
504
- cry: "https://play.pokemonshowdown.com/audio/cries/30.mp3"
505
- },
506
- {
507
- id: 31,
508
- name: "Nidoqueen",
509
- types: ["poison", "ground"],
510
- stats: { hp: 90, attack: 92, defense: 87, spAtk: 75, spDef: 85, speed: 76 },
511
- height: 1.3,
512
- weight: 60.0,
513
- description: "Its hard scales provide strong protection. It uses its hefty bulk to execute powerful moves.",
514
- moves: ["Growl", "Tackle", "Scratch", "Body Slam"],
515
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/31.png",
516
- cry: "https://play.pokemonshowdown.com/audio/cries/31.mp3"
517
- },
518
- {
519
- id: 32,
520
- name: "Nidoran♂",
521
- types: ["poison"],
522
- stats: { hp: 46, attack: 57, defense: 40, spAtk: 40, spDef: 40, speed: 50 },
523
- height: 0.5,
524
- weight: 9.0,
525
- description: "It constantly moves its large ears in many directions in order to detect danger right away.",
526
- moves: ["Leer", "Tackle", "Horn Attack"],
527
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/32.png",
528
- cry: "https://play.pokemonshowdown.com/audio/cries/32.mp3"
529
- },
530
- {
531
- id: 33,
532
- name: "Nidorino",
533
- types: ["poison"],
534
- stats: { hp: 61, attack: 72, defense: 57, spAtk: 55, spDef: 55, speed: 65 },
535
- height: 0.9,
536
- weight: 19.5,
537
- description: "An aggressive Pokémon that is quick to attack. The horn on its head secretes a powerful venom.",
538
- moves: ["Leer", "Tackle", "Horn Attack", "Double Kick"],
539
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/33.png",
540
- cry: "https://play.pokemonshowdown.com/audio/cries/33.mp3"
541
- },
542
- {
543
- id: 34,
544
- name: "Nidoking",
545
- types: ["poison", "ground"],
546
- stats: { hp: 81, attack: 102, defense: 77, spAtk: 85, spDef: 75, speed: 85 },
547
- height: 1.4,
548
- weight: 62.0,
549
- description: "It uses its powerful tail in battle to smash, constrict, then break the prey's bones.",
550
- moves: ["Leer", "Tackle", "Horn Attack", "Thrash"],
551
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/34.png",
552
- cry: "https://play.pokemonshowdown.com/audio/cries/34.mp3"
553
- },
554
- {
555
- id: 35,
556
- name: "Clefairy",
557
- types: ["fairy"],
558
- stats: { hp: 70, attack: 45, defense: 48, spAtk: 60, spDef: 65, speed: 35 },
559
- height: 0.6,
560
- weight: 7.5,
561
- description: "Its magical and cute appeal has many admirers. It is rare and found only in certain areas.",
562
- moves: ["Pound", "Growl", "Sing", "Metronome"],
563
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/35.png",
564
- cry: "https://play.pokemonshowdown.com/audio/cries/35.mp3"
565
- },
566
- {
567
- id: 36,
568
- name: "Clefable",
569
- types: ["fairy"],
570
- stats: { hp: 95, attack: 70, defense: 73, spAtk: 95, spDef: 90, speed: 60 },
571
- height: 1.3,
572
- weight: 40.0,
573
- description: "A timid fairy Pokémon that is rarely seen. It will run and hide the moment it senses people.",
574
- moves: ["Pound", "Growl", "Sing", "Metronome"],
575
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/36.png",
576
- cry: "https://play.pokemonshowdown.com/audio/cries/36.mp3"
577
- },
578
- {
579
- id: 37,
580
- name: "Vulpix",
581
- types: ["fire"],
582
- stats: { hp: 38, attack: 41, defense: 40, spAtk: 50, spDef: 65, speed: 65 },
583
- height: 0.6,
584
- weight: 9.9,
585
- description: "At the time of birth, it has just one tail. The tail splits from its tip as it grows older.",
586
- moves: ["Ember", "Tail Whip", "Quick Attack"],
587
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/37.png",
588
- cry: "https://play.pokemonshowdown.com/audio/cries/37.mp3"
589
- },
590
- {
591
- id: 38,
592
- name: "Ninetales",
593
- types: ["fire"],
594
- stats: { hp: 73, attack: 76, defense: 75, spAtk: 81, spDef: 100, speed: 100 },
595
- height: 1.1,
596
- weight: 19.9,
597
- description: "Very smart and very vengeful. Grabbing one of its many tails could result in a 1000-year curse.",
598
- moves: ["Ember", "Tail Whip", "Quick Attack", "Confuse Ray"],
599
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/38.png",
600
- cry: "https://play.pokemonshowdown.com/audio/cries/38.mp3"
601
- },
602
- {
603
- id: 39,
604
- name: "Jigglypuff",
605
- types: ["normal", "fairy"],
606
- stats: { hp: 115, attack: 45, defense: 20, spAtk: 45, spDef: 25, speed: 20 },
607
- height: 0.5,
608
- weight: 5.5,
609
- description: "When its huge eyes light up, it sings a mysteriously soothing melody that lulls its enemies to sleep.",
610
- moves: ["Sing", "Pound", "Defense Curl"],
611
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/39.png",
612
- cry: "https://play.pokemonshowdown.com/audio/cries/39.mp3"
613
- },
614
- {
615
- id: 40,
616
- name: "Wigglytuff",
617
- types: ["normal", "fairy"],
618
- stats: { hp: 140, attack: 70, defense: 45, spAtk: 85, spDef: 50, speed: 45 },
619
- height: 1.0,
620
- weight: 12.0,
621
- description: "The body is soft and rubbery. When angered, it will suck in air and inflate itself to an enormous size.",
622
- moves: ["Sing", "Pound", "Defense Curl", "Double Slap"],
623
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/40.png",
624
- cry: "https://play.pokemonshowdown.com/audio/cries/40.mp3"
625
- },
626
- {
627
- id: 41,
628
- name: "Zubat",
629
- types: ["poison", "flying"],
630
- stats: { hp: 40, attack: 45, defense: 35, spAtk: 30, spDef: 40, speed: 55 },
631
- height: 0.8,
632
- weight: 7.5,
633
- description: "Forms colonies in perpetually dark places. Uses ultrasonic waves to identify and approach targets.",
634
- moves: ["Leech Life", "Supersonic"],
635
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/41.png",
636
- cry: "https://play.pokemonshowdown.com/audio/cries/41.mp3"
637
- },
638
- {
639
- id: 42,
640
- name: "Golbat",
641
- types: ["poison", "flying"],
642
- stats: { hp: 75, attack: 80, defense: 70, spAtk: 65, spDef: 75, speed: 90 },
643
- height: 1.6,
644
- weight: 55.0,
645
- description: "Once it strikes, it will not stop draining energy from the victim even if it gets too heavy to fly.",
646
- moves: ["Leech Life", "Supersonic", "Bite"],
647
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/42.png",
648
- cry: "https://play.pokemonshowdown.com/audio/cries/42.mp3"
649
- },
650
- {
651
- id: 43,
652
- name: "Oddish",
653
- types: ["grass", "poison"],
654
- stats: { hp: 45, attack: 50, defense: 55, spAtk: 75, spDef: 65, speed: 30 },
655
- height: 0.5,
656
- weight: 5.4,
657
- description: "During the day, it keeps its face buried in the ground. At night, it wanders around sowing its seeds.",
658
- moves: ["Absorb", "Poison Powder"],
659
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/43.png",
660
- cry: "https://play.pokemonshowdown.com/audio/cries/43.mp3"
661
- },
662
- {
663
- id: 44,
664
- name: "Gloom",
665
- types: ["grass", "poison"],
666
- stats: { hp: 60, attack: 65, defense: 70, spAtk: 85, spDef: 75, speed: 40 },
667
- height: 0.8,
668
- weight: 8.6,
669
- description: "The fluid that oozes from its mouth isn't drool. It is a nectar that is used to attract prey.",
670
- moves: ["Absorb", "Poison Powder", "Sleep Powder"],
671
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/44.png",
672
- cry: "https://play.pokemonshowdown.com/audio/cries/44.mp3"
673
- },
674
- {
675
- id: 45,
676
- name: "Vileplume",
677
- types: ["grass", "poison"],
678
- stats: { hp: 75, attack: 80, defense: 85, spAtk: 110, spDef: 90, speed: 50 },
679
- height: 1.2,
680
- weight: 18.6,
681
- description: "The larger its petals, the more toxic pollen it contains. Its big head is heavy and hard to hold up.",
682
- moves: ["Absorb", "Poison Powder", "Sleep Powder", "Petal Dance"],
683
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/45.png",
684
- cry: "https://play.pokemonshowdown.com/audio/cries/45.mp3"
685
- },
686
- {
687
- id: 46,
688
- name: "Paras",
689
- types: ["bug", "grass"],
690
- stats: { hp: 35, attack: 70, defense: 55, spAtk: 45, spDef: 55, speed: 25 },
691
- height: 0.3,
692
- weight: 5.4,
693
- description: "Burrows to suck tree roots. The mushrooms on its back grow by drawing nutrients from the bug host.",
694
- moves: ["Scratch", "Leech Life"],
695
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/46.png",
696
- cry: "https://play.pokemonshowdown.com/audio/cries/46.mp3"
697
- },
698
- {
699
- id: 47,
700
- name: "Parasect",
701
- types: ["bug", "grass"],
702
- stats: { hp: 60, attack: 95, defense: 80, spAtk: 60, spDef: 80, speed: 30 },
703
- height: 1.0,
704
- weight: 29.5,
705
- description: "A host-parasite pair in which the parasite mushroom has taken over the host bug. Prefers damp places.",
706
- moves: ["Scratch", "Leech Life", "Spore"],
707
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/47.png",
708
- cry: "https://play.pokemonshowdown.com/audio/cries/47.mp3"
709
- },
710
- {
711
- id: 48,
712
- name: "Venonat",
713
- types: ["bug", "poison"],
714
- stats: { hp: 60, attack: 55, defense: 50, spAtk: 40, spDef: 55, speed: 45 },
715
- height: 1.0,
716
- weight: 30.0,
717
- description: "Lives in the shadows of tall trees where it eats insects. It is attracted by light at night.",
718
- moves: ["Tackle", "Disable", "Poison Powder"],
719
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/48.png",
720
- cry: "https://play.pokemonshowdown.com/audio/cries/48.mp3"
721
- },
722
- {
723
- id: 49,
724
- name: "Venomoth",
725
- types: ["bug", "poison"],
726
- stats: { hp: 70, attack: 65, defense: 60, spAtk: 90, spDef: 75, speed: 90 },
727
- height: 1.5,
728
- weight: 12.5,
729
- description: "The dust-like scales covering its wings are color coded to indicate the kinds of poison it has.",
730
- moves: ["Tackle", "Disable", "Poison Powder", "Psybeam"],
731
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/49.png",
732
- cry: "https://play.pokemonshowdown.com/audio/cries/49.mp3"
733
- },
734
- {
735
- id: 50,
736
- name: "Diglett",
737
- types: ["ground"],
738
- stats: { hp: 10, attack: 55, defense: 25, spAtk: 35, spDef: 45, speed: 95 },
739
- height: 0.2,
740
- weight: 0.8,
741
- description: "Lives about one yard underground where it feeds on plant roots. It sometimes appears above ground.",
742
- moves: ["Scratch", "Sand Attack"],
743
- sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/50.png",
744
- cry: "https://play.pokemonshowdown.com/audio/cries/50.mp3"
745
- }
746
- ];
747
-
748
- // DOM Elements
749
- const pokemonGrid = document.getElementById('pokemon-grid');
750
- const searchInput = document.getElementById('search');
751
- const typeFilters = document.querySelectorAll('.type-filter');
752
- const toggleViewBtn = document.getElementById('toggle-view');
753
- const pokemonModal = document.getElementById('pokemon-modal');
754
- const closeModalBtn = document.getElementById('close-modal');
755
- const modalContent = document.getElementById('modal-content');
756
-
757
- // Type effectiveness chart
758
- const typeEffectiveness = {
759
- normal: { weak: ["fighting"], strong: [], immune: ["ghost"] },
760
- fire: { weak: ["water", "ground", "rock"], strong: ["grass", "ice", "bug"] },
761
- water: { weak: ["electric", "grass"], strong: ["fire", "ground", "rock"] },
762
- electric: { weak: ["ground"], strong: ["water", "flying"] },
763
- grass: { weak: ["fire", "ice", "poison", "flying", "bug"], strong: ["water", "ground", "rock"] },
764
- ice: { weak: ["fire", "fighting", "rock"], strong: ["grass", "ground", "flying", "dragon"] },
765
- fighting: { weak: ["flying", "psychic"], strong: ["normal", "ice", "rock"] },
766
- poison: { weak: ["ground", "psychic"], strong: ["grass", "fairy"] },
767
- ground: { weak: ["water", "grass", "ice"], strong: ["fire", "electric", "poison", "rock"] },
768
- flying: { weak: ["electric", "ice", "rock"], strong: ["grass", "fighting", "bug"] },
769
- psychic: { weak: ["bug", "ghost", "dark"], strong: ["fighting", "poison"] },
770
- bug: { weak: ["fire", "flying", "rock"], strong: ["grass", "psychic"] },
771
- rock: { weak: ["water", "grass", "fighting", "ground"], strong: ["fire", "ice", "flying", "bug"] },
772
- ghost: { weak: ["ghost", "dark"], strong: ["psychic"], immune: ["normal", "fighting"] },
773
- dragon: { weak: ["ice", "dragon"], strong: ["dragon"], immune: [] },
774
- fairy: { weak: ["poison", "steel"], strong: ["fighting", "dragon", "dark"], immune: ["dragon"] }
775
- };
776
-
777
- // Current view mode (grid or list)
778
- let currentViewMode = 'grid';
779
-
780
- // Initialize the Pokedex
781
- function initPokedex() {
782
- renderPokemonCards(pokemonData);
783
-
784
- // Event listeners
785
- searchInput.addEventListener('input', handleSearch);
786
- typeFilters.forEach(filter => filter.addEventListener('click', handleTypeFilter));
787
- toggleViewBtn.addEventListener('click', toggleViewMode);
788
- closeModalBtn.addEventListener('click', () => {
789
- pokemonModal.classList.add('hidden');
790
- });
791
- }
792
-
793
- // Render Pokémon cards
794
- function renderPokemonCards(pokemonArray) {
795
- pokemonGrid.innerHTML = '';
796
-
797
- pokemonArray.forEach(pokemon => {
798
- const card = document.createElement('div');
799
- card.className = 'pokemon-card rounded-lg overflow-hidden shadow-md bg-white cursor-pointer';
800
- card.innerHTML = `
801
- <div class="pokemon-card-inner" onclick="showPokemonDetails(${pokemon.id})">
802
- <div class="bg-gray-100 py-2 px-4 flex justify-between items-center">
803
- <span class="text-gray-600 font-bold">#${pokemon.id.toString().padStart(3, '0')}</span>
804
- <div class="flex space-x-1">
805
- ${pokemon.types.map(type => `
806
- <span class="type-${type} px-2 py-1 rounded-full text-xs">${type.charAt(0).toUpperCase() + type.slice(1)}</span>
807
- `).join('')}
808
- </div>
809
- </div>
810
- <div class="p-4 flex flex-col items-center">
811
- <img src="${pokemon.sprite}" alt="${pokemon.name}" class="pokemon-sprite w-32 h-32 object-contain transition-transform">
812
- <h3 class="text-xl font-bold mt-2">${pokemon.name.charAt(0).toUpperCase() + pokemon.name.slice(1)}</h3>
813
- <p class="text-sm text-gray-600 text-center mt-1">${pokemon.description}</p>
814
- </div>
815
- </div>
816
- `;
817
- pokemonGrid.appendChild(card);
818
- });
819
- }
820
-
821
- // Show Pokémon details in modal
822
- function showPokemonDetails(pokemonId) {
823
- const pokemon = pokemonData.find(p => p.id === pokemonId);
824
- if (!pokemon) return;
825
-
826
- // Play Pokémon cry
827
- const audio = new Audio(pokemon.cry);
828
- audio.play();
829
-
830
- // Calculate effectiveness for this Pokémon
831
- const weaknesses = calculateWeaknesses(pokemon.types);
832
- const resistances = calculateResistances(pokemon.types);
833
- const immunities = calculateImmunities(pokemon.types);
834
-
835
- // Create modal content
836
- modalContent.innerHTML = `
837
- <div class="flex flex-col items-center">
838
- <h2 class="text-3xl font-bold mb-4">${pokemon.name.charAt(0).toUpperCase() + pokemon.name.slice(1)}</h2>
839
- <div class="flex items-center space-x-2 mb-4">
840
- <span class="text-gray-600 font-bold">#${pokemon.id.toString().padStart(3, '0')}</span>
841
- <div class="flex space-x-1">
842
- ${pokemon.types.map(type => `
843
- <span class="type-${type} px-3 py-1 rounded-full text-sm">${type.charAt(0).toUpperCase() + type.slice(1)}</span>
844
- `).join('')}
845
- </div>
846
- </div>
847
- <img src="${pokemon.sprite}" alt="${pokemon.name}" class="w-48 h-48 object-contain pokemon-sprite floating">
848
-
849
- <div class="mt-6 w-full">
850
- <h3 class="text-xl font-bold mb-2">Pokédex Entry</h3>
851
- <p class="text-gray-700">${pokemon.description}</p>
852
- </div>
853
-
854
- <div class="mt-6 w-full grid grid-cols-2 gap-4">
855
- <div>
856
- <h3 class="text-xl font-bold mb-2">Height</h3>
857
- <p class="text-gray-700">${pokemon.height} m</p>
858
- </div>
859
- <div>
860
- <h3 class="text-xl font-bold mb-2">Weight</h3>
861
- <p class="text-gray-700">${pokemon.weight} kg</p>
862
- </div>
863
- </div>
864
- </div>
865
-
866
- <div class="space-y-6">
867
- <div>
868
- <h3 class="text-xl font-bold mb-2">Stats</h3>
869
- <div class="h-64">
870
- <canvas id="statsChart"></canvas>
871
- </div>
872
- </div>
873
-
874
- <div>
875
- <h3 class="text-xl font-bold mb-2">Known Moves</h3>
876
- <div class="grid grid-cols-2 gap-2">
877
- ${pokemon.moves.map(move => `
878
- <span class="bg-gray-200 px-3 py-1 rounded-full text-sm text-center">${move}</span>
879
- `).join('')}
880
- </div>
881
- </div>
882
-
883
- <div>
884
- <h3 class="text-xl font-bold mb-2">Type Effectiveness</h3>
885
- ${weaknesses.length ? `
886
- <div class="mb-3">
887
- <h4 class="font-bold text-red-500 mb-1">Weak to (2×)</h4>
888
- <div class="flex flex-wrap gap-1">
889
- ${weaknesses.map(type => `
890
- <span class="type-${type} px-3 py-1 rounded-full text-xs">${type.charAt(0).toUpperCase() + type.slice(1)}</span>
891
- `).join('')}
892
- </div>
893
- </div>
894
- ` : ''}
895
-
896
- ${resistances.length ? `
897
- <div class="mb-3">
898
- <h4 class="font-bold text-green-500 mb-1">Resistant to (½×)</h4>
899
- <div class="flex flex-wrap gap-1">
900
- ${resistances.map(type => `
901
- <span class="type-${type} px-3 py-1 rounded-full text-xs">${type.charAt(0).toUpperCase() + type.slice(1)}</span>
902
- `).join('')}
903
- </div>
904
- </div>
905
- ` : ''}
906
-
907
- ${immunities.length ? `
908
- <div class="mb-3">
909
- <h4 class="font-bold text-blue-500 mb-1">Immune to (0×)</h4>
910
- <div class="flex flex-wrap gap-1">
911
- ${immunities.map(type => `
912
- <span class="type-${type} px-3 py-1 rounded-full text-xs">${type.charAt(0).toUpperCase() + type.slice(1)}</span>
913
- `).join('')}
914
- </div>
915
- </div>
916
- ` : ''}
917
- </div>
918
- </div>
919
- `;
920
-
921
- // Initialize chart
922
- const ctx = document.getElementById('statsChart').getContext('2d');
923
- new Chart(ctx, {
924
- type: 'radar',
925
- data: {
926
- labels: ['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed'],
927
- datasets: [{
928
- label: 'Base Stats',
929
- data: [
930
- pokemon.stats.hp,
931
- pokemon.stats.attack,
932
- pokemon.stats.defense,
933
- pokemon.stats.spAtk,
934
- pokemon.stats.spDef,
935
- pokemon.stats.speed
936
- ],
937
- backgroundColor: 'rgba(239, 68, 68, 0.2)',
938
- borderColor: 'rgba(239, 68, 68, 1)',
939
- borderWidth: 2,
940
- pointBackgroundColor: 'rgba(239, 68, 68, 1)',
941
- pointRadius: 4,
942
- pointHoverRadius: 6
943
- }]
944
- },
945
- options: {
946
- scales: {
947
- r: {
948
- angleLines: {
949
- display: true
950
- },
951
- suggestedMin: 0,
952
- suggestedMax: 120
953
- }
954
- },
955
- plugins: {
956
- legend: {
957
- display: false
958
- }
959
- },
960
- elements: {
961
- line: {
962
- tension: 0.2
963
- }
964
- }
965
- }
966
- });
967
-
968
- // Show modal
969
- pokemonModal.classList.remove('hidden');
970
- }
971
-
972
- // Calculate weaknesses based on Pokémon types
973
- function calculateWeaknesses(types) {
974
- const weakTo = new Set();
975
-
976
- types.forEach(type => {
977
- typeEffectiveness[type].weak.forEach(weakType => {
978
- weakTo.add(weakType);
979
- });
980
-
981
- // Check if any resistances cancel out weaknesses
982
- typeEffectiveness[type].strong.forEach(strongType => {
983
- if (weakTo.has(strongType)) {
984
- weakTo.delete(strongType);
985
- }
986
- });
987
- });
988
-
989
- return Array.from(weakTo);
990
- }
991
-
992
- // Calculate resistances based on Pokémon types
993
- function calculateResistances(types) {
994
- const resistantTo = new Set();
995
-
996
- types.forEach(type => {
997
- typeEffectiveness[type].strong.forEach(resistantType => {
998
- resistantTo.add(resistantType);
999
- });
1000
-
1001
- // Check if any weaknesses cancel out resistances
1002
- typeEffectiveness[type].weak.forEach(weakType => {
1003
- if (resistantTo.has(weakType)) {
1004
- resistantTo.delete(weakType);
1005
- }
1006
- });
1007
- });
1008
-
1009
- return Array.from(resistantTo);
1010
- }
1011
-
1012
- // Calculate immunities based on Pokémon types
1013
- function calculateImmunities(types) {
1014
- const immuneTo = new Set();
1015
-
1016
- types.forEach(type => {
1017
- if (typeEffectiveness[type].immune) {
1018
- typeEffectiveness[type].immune.forEach(immuneType => {
1019
- immuneTo.add(immuneType);
1020
- });
1021
- }
1022
- });
1023
-
1024
- return Array.from(immuneTo);
1025
- }
1026
-
1027
- // Handle search input
1028
- function handleSearch() {
1029
- const searchTerm = searchInput.value.toLowerCase();
1030
- const filteredPokemon = pokemonData.filter(pokemon =>
1031
- pokemon.name.toLowerCase().includes(searchTerm) ||
1032
- pokemon.id.toString().includes(searchTerm)
1033
- );
1034
- renderPokemonCards(filteredPokemon);
1035
- }
1036
-
1037
- // Handle type filter
1038
- function handleTypeFilter(e) {
1039
- const type = e.target.dataset.type;
1040
- typeFilters.forEach(filter => {
1041
- if (filter.dataset.type === type) {
1042
- filter.classList.add('ring-2', 'ring-gray-800');
1043
- } else {
1044
- filter.classList.remove('ring-2', 'ring-gray-800');
1045
- }
1046
- });
1047
-
1048
- if (type === 'all') {
1049
- renderPokemonCards(pokemonData);
1050
- return;
1051
- }
1052
-
1053
- const filteredPokemon = pokemonData.filter(pokemon =>
1054
- pokemon.types.includes(type)
1055
- );
1056
- renderPokemonCards(filteredPokemon);
1057
- }
1058
-
1059
- // Toggle between grid and list view
1060
- function toggleViewMode() {
1061
- if (currentViewMode === 'grid') {
1062
- // Switch to list view
1063
- pokemonGrid.classList.remove('grid-cols-2', 'sm:grid-cols-3', 'md:grid-cols-4', 'lg:grid-cols-5');
1064
- pokemonGrid.classList.add('grid-cols-1');
1065
- currentViewMode = 'list';
1066
- toggleViewBtn.innerHTML = `
1067
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
1068
- <path d="M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM11 13a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
1069
- </svg>
1070
- Grid View`;
1071
- } else {
1072
- // Switch to grid view
1073
- pokemonGrid.classList.add('grid-cols-2', 'sm:grid-cols-3', 'md:grid-cols-4', 'lg:grid-cols-5');
1074
- pokemonGrid.classList.remove('grid-cols-1');
1075
- currentViewMode = 'grid';
1076
- toggleViewBtn.innerHTML = `
1077
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
1078
- <path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" />
1079
- <path fill-rule="evenodd" d="M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z" clip-rule="evenodd" />
1080
- </svg>
1081
- List View`;
1082
- }
1083
- }
1084
-
1085
- // Make showPokemonDetails available globally
1086
- window.showPokemonDetails = showPokemonDetails;
1087
-
1088
- // Initialize the Pokedex on page load
1089
- document.addEventListener('DOMContentLoaded', initPokedex);
1090
- </script>
1091
- <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=victor/pokedex" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1092
  </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>Gen 1 Pokedex | First 50 Pokémon</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
+ <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
10
+ <script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>
11
+ <style>
12
+ body {
13
+ font-family: 'Press Start 2P', cursive;
14
+ background-color: #f0f0f0;
15
+ color: #333;
16
+ }
17
+ .pokemon-card {
18
+ transition: all 0.3s ease;
19
+ transform-style: preserve-3d;
20
+ }
21
+ .pokemon-card:hover {
22
+ transform: translateY(-5px) rotateY(5deg);
23
+ box-shadow: 0 10px 20px rgba(0,0,0,0.2);
24
+ }
25
+ .pokemon-card-inner {
26
+ transition: transform 0.6s;
27
+ transform-style: preserve-3d;
28
+ }
29
+ .pokemon-card:hover .pokemon-card-inner {
30
+ transform: rotateY(10deg);
31
+ }
32
+ @keyframes float {
33
+ 0%, 100% { transform: translateY(0); }
34
+ 50% { transform: translateY(-10px); }
35
+ }
36
+ .floating {
37
+ animation: float 3s ease-in-out infinite;
38
+ }
39
+ .pokemon-sprite {
40
+ transition: transform 0.3s;
41
+ }
42
+ .pokemon-sprite:hover {
43
+ transform: scale(1.1);
44
+ }
45
+ .type-bug { background-color: #A8B820; }
46
+ .type-dark { background-color: #705848; }
47
+ .type-dragon { background-color: #7038F8; }
48
+ .type-electric { background-color: #F8D030; }
49
+ .type-fairy { background-color: #EE99AC; }
50
+ .type-fighting { background-color: #C03028; }
51
+ .type-fire { background-color: #F08030; }
52
+ .type-flying { background-color: #A890F0; }
53
+ .type-ghost { background-color: #705898; }
54
+ .type-grass { background-color: #78C850; }
55
+ .type-ground { background-color: #E0C068; }
56
+ .type-ice { background-color: #98D8D8; }
57
+ .type-normal { background-color: #A8A878; }
58
+ .type-poison { background-color: #A040A0; }
59
+ .type-psychic { background-color: #F85888; }
60
+ .type-rock { background-color: #B8A038; }
61
+ .type-steel { background-color: #B8B8D0; }
62
+ .type-water { background-color: #6890F0; }
63
+ </style>
64
+ </head>
65
+ <body class="min-h-screen bg-gray-100">
66
+ <div class="container mx-auto px-4 py-8"><main>
67
+ <header class="text-center mb-8 relative overflow-hidden">
68
+ <div class="absolute inset-0 bg-red-500 transform -skew-y-3 z-0 opacity-20"></div>
69
+ <h1 class="text-4xl md:text-6xl font-bold relative z-10 mb-2 text-red-600">
70
+ <span class="text-yellow-400">POKÉ</span>DEX
71
+ </h1>
72
+ <p class="text-lg md:text-xl relative z-10 text-gray-700">Generation 1 | Pokémon #1-50</p>
73
+
74
+ <div class="absolute top-4 left-4 w-16 h-16 flex items-center justify-center rounded-full bg-red-500 shadow-md">
75
+ <lottie-player src="https://assets8.lottiefiles.com/packages/lf20_b88nh30c.json" background="transparent" speed="1" style="width: 40px; height: 40px;" loop autoplay></lottie-player>
76
+
77
+ <button aria-label="button" id="dark-mode-toggle" class="bg-gray-200 dark:bg-gray-700 rounded-full w-12 h-6 flex items-center transition duration-300 ease-in-out cursor-pointer">
78
+ <span class="bg-white dark:bg-gray-800 w-4 h-4 rounded-full shadow-md transform transition duration-300 ease-in-out ml-1 dark:ml-7"></span>
79
+ </button>
80
+ </div>
81
+ </header>
82
+
83
+ <div class="flex justify-between items-center mb-6">
84
+ <div class="relative w-64">
85
+ <input type="text" id="search" aria-label="Search Pokémon" role="search" placeholder="Search Pokémon..." class="w-full px-4 py-2 rounded-full border-2 border-gray-300 focus:outline-none focus:border-red-500 transition-all">
86
+ <button aria-label="button" class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-red-500 text-white rounded-full p-1">
87
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
88
+ <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
89
+ </svg>
90
+ </button>
91
+ </div>
92
+ <div>
93
+ <button aria-label="button" id="toggle-view" class="bg-yellow-400 hover:bg-yellow-500 text-black px-4 py-2 rounded-md flex items-center transition-colors">
94
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-1" viewBox="0 0 20 20" fill="currentColor">
95
+ <path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" />
96
+ <path fill-rule="evenodd" d="M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z" clip-rule="evenodd" />
97
+ </svg>
98
+ Grid View
99
+ </button>
100
+ </div>
101
+ </div>
102
+
103
+ <!-- Type Filter -->
104
+ <div class="mb-8">
105
+ <h3 class="text-lg font-bold mb-2">Filter by Type:</h3>
106
+ <div class="flex flex-wrap gap-2">
107
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white bg-red-500" data-type="all">All</button>
108
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-fire" data-type="fire">Fire</button>
109
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-water" data-type="water">Water</button>
110
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-grass" data-type="grass">Grass</button>
111
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-electric" data-type="electric">Electric</button>
112
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-normal" data-type="normal">Normal</button>
113
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-fighting" data-type="fighting">Fighting</button>
114
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-poison" data-type="poison">Poison</button>
115
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-ground" data-type="ground">Ground</button>
116
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-flying" data-type="flying">Flying</button>
117
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-psychic" data-type="psychic">Psychic</button>
118
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-bug" data-type="bug">Bug</button>
119
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-rock" data-type="rock">Rock</button>
120
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-ghost" data-type="ghost">Ghost</button>
121
+ <button aria-label="button" class="type-filter px-3 py-1 rounded-full text-xs text-white type-dragon" data-type="dragon">Dragon</button>
122
+ </div>
123
+ </div>
124
+
125
+ <!-- Pokémon Grid View -->
126
+ <div id="pokemon-grid" role="main" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6">
127
+ <!-- Pokémon cards will be inserted here by JavaScript -->
128
+ </div>
129
+
130
+ <!-- Stats Modal -->
131
+ <div id="pokemon-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
132
+ <div class="bg-white rounded-lg max-w-4xl w-full max-h-screen overflow-y-auto relative">
133
+ <button aria-label="button" id="close-modal" class="absolute top-4 right-4 bg-red-500 text-white rounded-full p-2 hover:bg-red-600 transition-colors">
134
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
135
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
136
+ </svg>
137
+ </button>
138
+ <div class="p-8">
139
+ <div id="modal-content" class="grid md:grid-cols-2 gap-8">
140
+ <!-- Modal content will be inserted here by JavaScript -->
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </main></div>
146
+
147
+ <script>
148
+ // Pokémon Data (first 50 from Gen 1)
149
+ const pokemonData = [
150
+ {
151
+ id: 1,
152
+ name: "Bulbasaur",
153
+ types: ["grass", "poison"],
154
+ stats: { hp: 45, attack: 49, defense: 49, spAtk: 65, spDef: 65, speed: 45 },
155
+ height: 0.7,
156
+ weight: 6.9,
157
+ description: "A strange seed was planted on its back at birth. The plant sprouts and grows with this Pokémon.",
158
+ moves: ["Tackle", "Growl", "Vine Whip", "Leech Seed"],
159
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png",
160
+ cry: "https://play.pokemonshowdown.com/audio/cries/1.mp3"
161
+ },
162
+ {
163
+ id: 2,
164
+ name: "Ivysaur",
165
+ types: ["grass", "poison"],
166
+ stats: { hp: 60, attack: 62, defense: 63, spAtk: 80, spDef: 80, speed: 60 },
167
+ height: 1.0,
168
+ weight: 13.0,
169
+ description: "When the bulb on its back grows large, it appears to lose the ability to stand on its hind legs.",
170
+ moves: ["Tackle", "Growl", "Vine Whip", "Razor Leaf"],
171
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/2.png",
172
+ cry: "https://play.pokemonshowdown.com/audio/cries/2.mp3"
173
+ },
174
+ {
175
+ id: 3,
176
+ name: "Venusaur",
177
+ types: ["grass", "poison"],
178
+ stats: { hp: 80, attack: 82, defense: 83, spAtk: 100, spDef: 100, speed: 80 },
179
+ height: 2.0,
180
+ weight: 100.0,
181
+ description: "The plant blooms when it is absorbing solar energy. It stays on the move to seek sunlight.",
182
+ moves: ["Tackle", "Growl", "Vine Whip", "Solar Beam"],
183
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/3.png",
184
+ cry: "https://play.pokemonshowdown.com/audio/cries/3.mp3"
185
+ },
186
+ {
187
+ id: 4,
188
+ name: "Charmander",
189
+ types: ["fire"],
190
+ stats: { hp: 39, attack: 52, defense: 43, spAtk: 60, spDef: 50, speed: 65 },
191
+ height: 0.6,
192
+ weight: 8.5,
193
+ description: "Obviously prefers hot places. When it rains, steam is said to spout from the tip of its tail.",
194
+ moves: ["Scratch", "Growl", "Ember", "Dragon Rage"],
195
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/4.png",
196
+ cry: "https://play.pokemonshowdown.com/audio/cries/4.mp3"
197
+ },
198
+ {
199
+ id: 5,
200
+ name: "Charmeleon",
201
+ types: ["fire"],
202
+ stats: { hp: 58, attack: 64, defense: 58, spAtk: 80, spDef: 65, speed: 80 },
203
+ height: 1.1,
204
+ weight: 19.0,
205
+ description: "When it swings its burning tail, it elevates the temperature to unbearably high levels.",
206
+ moves: ["Scratch", "Growl", "Ember", "Flamethrower"],
207
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/5.png",
208
+ cry: "https://play.pokemonshowdown.com/audio/cries/5.mp3"
209
+ },
210
+ {
211
+ id: 6,
212
+ name: "Charizard",
213
+ types: ["fire", "flying"],
214
+ stats: { hp: 78, attack: 84, defense: 78, spAtk: 109, spDef: 85, speed: 100 },
215
+ height: 1.7,
216
+ weight: 90.5,
217
+ description: "Spits fire that is hot enough to melt boulders. Known to cause forest fires unintentionally.",
218
+ moves: ["Scratch", "Growl", "Flamethrower", "Fire Blast"],
219
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png",
220
+ cry: "https://play.pokemonshowdown.com/audio/cries/6.mp3"
221
+ },
222
+ {
223
+ id: 7,
224
+ name: "Squirtle",
225
+ types: ["water"],
226
+ stats: { hp: 44, attack: 48, defense: 65, spAtk: 50, spDef: 64, speed: 43 },
227
+ height: 0.5,
228
+ weight: 9.0,
229
+ description: "After birth, its back swells and hardens into a shell. Powerfully sprays foam from its mouth.",
230
+ moves: ["Tackle", "Tail Whip", "Water Gun", "Withdraw"],
231
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/7.png",
232
+ cry: "https://play.pokemonshowdown.com/audio/cries/7.mp3"
233
+ },
234
+ {
235
+ id: 8,
236
+ name: "Wartortle",
237
+ types: ["water"],
238
+ stats: { hp: 59, attack: 63, defense: 80, spAtk: 65, spDef: 80, speed: 58 },
239
+ height: 1.0,
240
+ weight: 22.5,
241
+ description: "Often hides in water to stalk unwary prey. For swimming fast, it moves its ears to maintain balance.",
242
+ moves: ["Tackle", "Tail Whip", "Water Gun", "Bite"],
243
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/8.png",
244
+ cry: "https://play.pokemonshowdown.com/audio/cries/8.mp3"
245
+ },
246
+ {
247
+ id: 9,
248
+ name: "Blastoise",
249
+ types: ["water"],
250
+ stats: { hp: 79, attack: 83, defense: 100, spAtk: 85, spDef: 105, speed: 78 },
251
+ height: 1.6,
252
+ weight: 85.5,
253
+ description: "A brutal Pokémon with pressurized water jets on its shell. They are used for high speed tackles.",
254
+ moves: ["Tackle", "Tail Whip", "Water Gun", "Hydro Pump"],
255
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/9.png",
256
+ cry: "https://play.pokemonshowdown.com/audio/cries/9.mp3"
257
+ },
258
+ {
259
+ id: 10,
260
+ name: "Caterpie",
261
+ types: ["bug"],
262
+ stats: { hp: 45, attack: 30, defense: 35, spAtk: 20, spDef: 20, speed: 45 },
263
+ height: 0.3,
264
+ weight: 2.9,
265
+ description: "Its short feet are tipped with suction pads that enable it to tirelessly climb slopes and walls.",
266
+ moves: ["Tackle", "String Shot"],
267
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/10.png",
268
+ cry: "https://play.pokemonshowdown.com/audio/cries/10.mp3"
269
+ },
270
+ {
271
+ id: 11,
272
+ name: "Metapod",
273
+ types: ["bug"],
274
+ stats: { hp: 50, attack: 20, defense: 55, spAtk: 25, spDef: 25, speed: 30 },
275
+ height: 0.7,
276
+ weight: 9.9,
277
+ description: "This Pokémon is vulnerable to attack while its shell is soft, exposing its weak and tender body.",
278
+ moves: ["Harden"],
279
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/11.png",
280
+ cry: "https://play.pokemonshowdown.com/audio/cries/11.mp3"
281
+ },
282
+ {
283
+ id: 12,
284
+ name: "Butterfree",
285
+ types: ["bug", "flying"],
286
+ stats: { hp: 60, attack: 45, defense: 50, spAtk: 90, spDef: 80, speed: 70 },
287
+ height: 1.1,
288
+ weight: 32.0,
289
+ description: "In battle, it flaps its wings at high speed to release highly toxic dust into the air.",
290
+ moves: ["Confusion", "Poison Powder", "Stun Spore", "Sleep Powder"],
291
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/12.png",
292
+ cry: "https://play.pokemonshowdown.com/audio/cries/12.mp3"
293
+ },
294
+ {
295
+ id: 13,
296
+ name: "Weedle",
297
+ types: ["bug", "poison"],
298
+ stats: { hp: 40, attack: 35, defense: 30, spAtk: 20, spDef: 20, speed: 50 },
299
+ height: 0.3,
300
+ weight: 3.2,
301
+ description: "Often found in forests, eating leaves. It has a sharp venomous stinger on its head.",
302
+ moves: ["Poison Sting", "String Shot"],
303
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/13.png",
304
+ cry: "https://play.pokemonshowdown.com/audio/cries/13.mp3"
305
+ },
306
+ {
307
+ id: 14,
308
+ name: "Kakuna",
309
+ types: ["bug", "poison"],
310
+ stats: { hp: 45, attack: 25, defense: 50, spAtk: 25, spDef: 25, speed: 35 },
311
+ height: 0.6,
312
+ weight: 10.0,
313
+ description: "Almost incapable of moving, this Pokémon can only harden its shell to protect itself from predators.",
314
+ moves: ["Harden"],
315
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/14.png",
316
+ cry: "https://play.pokemonshowdown.com/audio/cries/14.mp3"
317
+ },
318
+ {
319
+ id: 15,
320
+ name: "Beedrill",
321
+ types: ["bug", "poison"],
322
+ stats: { hp: 65, attack: 90, defense: 40, spAtk: 45, spDef: 80, speed: 75 },
323
+ height: 1.0,
324
+ weight: 29.5,
325
+ description: "Flies at high speed and attacks using its large venomous stingers on its forelegs and tail.",
326
+ moves: ["Fury Attack", "Focus Energy", "Twineedle"],
327
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/15.png",
328
+ cry: "https://play.pokemonshowdown.com/audio/cries/15.mp3"
329
+ },
330
+ {
331
+ id: 16,
332
+ name: "Pidgey",
333
+ types: ["normal", "flying"],
334
+ stats: { hp: 40, attack: 45, defense: 40, spAtk: 35, spDef: 35, speed: 56 },
335
+ height: 0.3,
336
+ weight: 1.8,
337
+ description: "A common sight in forests and woods. It flaps its wings at ground level to kick up blinding sand.",
338
+ moves: ["Tackle", "Sand Attack", "Gust"],
339
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/16.png",
340
+ cry: "https://play.pokemonshowdown.com/audio/cries/16.mp3"
341
+ },
342
+ {
343
+ id: 17,
344
+ name: "Pidgeotto",
345
+ types: ["normal", "flying"],
346
+ stats: { hp: 63, attack: 60, defense: 55, spAtk: 50, spDef: 50, speed: 71 },
347
+ height: 1.1,
348
+ weight: 30.0,
349
+ description: "Very protective of its sprawling territorial area, this Pokémon will fiercely peck at any intruder.",
350
+ moves: ["Tackle", "Sand Attack", "Gust", "Quick Attack"],
351
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/17.png",
352
+ cry: "https://play.pokemonshowdown.com/audio/cries/17.mp3"
353
+ },
354
+ {
355
+ id: 18,
356
+ name: "Pidgeot",
357
+ types: ["normal", "flying"],
358
+ stats: { hp: 83, attack: 80, defense: 75, spAtk: 70, spDef: 70, speed: 101 },
359
+ height: 1.5,
360
+ weight: 39.5,
361
+ description: "When hunting, it skims the surface of water at high speed to pick off unwary prey such as Magikarp.",
362
+ moves: ["Tackle", "Sand Attack", "Gust", "Wing Attack"],
363
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/18.png",
364
+ cry: "https://play.pokemonshowdown.com/audio/cries/18.mp3"
365
+ },
366
+ {
367
+ id: 19,
368
+ name: "Rattata",
369
+ types: ["normal"],
370
+ stats: { hp: 30, attack: 56, defense: 35, spAtk: 25, spDef: 35, speed: 72 },
371
+ height: 0.3,
372
+ weight: 3.5,
373
+ description: "Bites anything when it attacks. Small and very quick, it is a common sight in many places.",
374
+ moves: ["Tackle", "Tail Whip", "Quick Attack"],
375
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/19.png",
376
+ cry: "https://play.pokemonshowdown.com/audio/cries/19.mp3"
377
+ },
378
+ {
379
+ id: 20,
380
+ name: "Raticate",
381
+ types: ["normal"],
382
+ stats: { hp: 55, attack: 81, defense: 60, spAtk: 50, spDef: 70, speed: 97 },
383
+ height: 0.7,
384
+ weight: 18.5,
385
+ description: "It uses its whiskers to maintain its balance. It seems to slow down if they are cut off.",
386
+ moves: ["Tackle", "Tail Whip", "Quick Attack", "Hyper Fang"],
387
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/20.png",
388
+ cry: "https://play.pokemonshowdown.com/audio/cries/20.mp3"
389
+ },
390
+ {
391
+ id: 21,
392
+ name: "Spearow",
393
+ types: ["normal", "flying"],
394
+ stats: { hp: 40, attack: 60, defense: 30, spAtk: 31, spDef: 31, speed: 70 },
395
+ height: 0.3,
396
+ weight: 2.0,
397
+ description: "Eats bugs in grassy areas. It has to flap its short wings at high speed to stay airborne.",
398
+ moves: ["Peck", "Growl", "Leer"],
399
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/21.png",
400
+ cry: "https://play.pokemonshowdown.com/audio/cries/21.mp3"
401
+ },
402
+ {
403
+ id: 22,
404
+ name: "Fearow",
405
+ types: ["normal", "flying"],
406
+ stats: { hp: 65, attack: 90, defense: 65, spAtk: 61, spDef: 61, speed: 100 },
407
+ height: 1.2,
408
+ weight: 38.0,
409
+ description: "With its huge and magnificent wings, it can keep aloft without ever having to land for rest.",
410
+ moves: ["Peck", "Growl", "Leer", "Fury Attack"],
411
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/22.png",
412
+ cry: "https://play.pokemonshowdown.com/audio/cries/22.mp3"
413
+ },
414
+ {
415
+ id: 23,
416
+ name: "Ekans",
417
+ types: ["poison"],
418
+ stats: { hp: 35, attack: 60, defense: 44, spAtk: 40, spDef: 54, speed: 55 },
419
+ height: 2.0,
420
+ weight: 6.9,
421
+ description: "Moves silently and stealthily. Eats the eggs of birds, such as Pidgey and Spearow, whole.",
422
+ moves: ["Wrap", "Leer", "Poison Sting"],
423
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/23.png",
424
+ cry: "https://play.pokemonshowdown.com/audio/cries/23.mp3"
425
+ },
426
+ {
427
+ id: 24,
428
+ name: "Arbok",
429
+ types: ["poison"],
430
+ stats: { hp: 60, attack: 85, defense: 69, spAtk: 65, spDef: 79, speed: 80 },
431
+ height: 3.5,
432
+ weight: 65.0,
433
+ description: "It is rumored that the ferocious warning markings on its belly differ from area to area.",
434
+ moves: ["Wrap", "Leer", "Poison Sting", "Bite"],
435
+ sprite: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/24.png",
436
+ cry: "https://play.pokemonshowdown.com/audio/cries/24.mp3"
437
+ },
438
+ {
439
+ id: 25,
440
+ name: "Pikachu",
441
+ types: ["electric"],
442
+ stats: { hp: 35, attack: 55, defense: 40, spAtk: 50, spDef: 50, speed: 90 },
443
+ height: 0.4,
444
+ weight: 6.0,
445
+ description: "When several of these Pokémon gather, their electricity could bui
446
+ ..._This content has been truncated to stay below 50000 characters_...
447
+
448
+ // Initialize the Pokedex on page load
449
+ document.addEventListener('DOMContentLoaded', initPokedex);
450
+ </script>
451
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=victor/pokedex" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p>
452
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
453
+ <script>
454
+ const darkModeToggle = document.getElementById('dark-mode-toggle');
455
+ const body = document.querySelector('body');
456
+
457
+ // Function to toggle dark mode
458
+ function toggleDarkMode() {
459
+ body.classList.toggle('dark');
460
+ // Store the dark mode preference in local storage
461
+ localStorage.setItem('darkMode', body.classList.contains('dark'));
462
+ }
463
+
464
+ // Check for dark mode preference in local storage on page load
465
+ if (localStorage.getItem('darkMode') === 'true') {
466
+ body.classList.add('dark');
467
+ }
468
+
469
+ // Add event listener to dark mode toggle
470
+ darkModeToggle.addEventListener('click', toggleDarkMode);
471
+
472
+ // GSAP Animations
473
+ gsap.from(".absolute.inset-0", { duration: 1, scale: 0.5, opacity: 0, delay: 0.5, ease: "elastic" });
474
+ gsap.from(".relative.z-10", { duration: 1, y: -50, opacity: 0, delay: 0.75, ease: "power3.out" });
475
+ gsap.from("#search", { duration: 0.75, x: -50, opacity: 0, delay: 1, ease: "power3.out" });
476
+ gsap.from("#toggle-view", { duration: 0.75, x: 50, opacity: 0, delay: 1, ease: "power3.out" });
477
+ gsap.from(".type-filter", { duration: 0.5, opacity: 0, stagger: 0.1, delay: 1.25, ease: "power2.out" });
478
+ gsap.from(".pokemon-card", { duration: 0.5, opacity: 0, stagger: 0.05, delay: 1.5, ease: "power2.out" });
479
+
480
+ gsap.utils.toArray(".pokemon-card").forEach(card => {
481
+ gsap.from(card, {
482
+ scrollTrigger: {
483
+ trigger: card,
484
+ start: "top bottom",
485
+ end: "bottom top",
486
+ scrub: true
487
+ },
488
+ opacity: 0.2,
489
+ y: 50,
490
+ duration: 0.5
491
+ });
492
+ });
493
+
494
+ </script>
495
+ </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  </html>
style.css CHANGED
@@ -1,28 +1,59 @@
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
+ 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
+ }
29
+
30
+
31
+ /* Dark mode styles */
32
+ body.dark {
33
+ background-color: #121212;
34
+ color: #fff;
35
+ }
36
+
37
+ body.dark .pokemon-card {
38
+ background-color: #333;
39
+ color: #fff;
40
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
41
+ }
42
+
43
+ body.dark .text-gray-600 {
44
+ color: #ccc;
45
+ }
46
+
47
+ body.dark .bg-gray-100 {
48
+ background-color: #444;
49
+ }
50
+
51
+ body.dark input {
52
+ background-color: #333;
53
+ border-color: #555;
54
+ color: #fff;
55
+ }
56
+
57
+ body.dark input::placeholder {
58
+ color: #ccc;
59
+ }