Juno360219 commited on
Commit
813c735
·
verified ·
1 Parent(s): 74207ed

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +1196 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Dnd Style Card Game
3
- emoji: 📉
4
- colorFrom: pink
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: dnd-style-card-game
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: pink
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1196 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Arcane Chronicles: Battle of Realms</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Fauna+One&display=swap');
11
+
12
+ body {
13
+ font-family: 'Fauna One', serif;
14
+ background-color: #0f172a;
15
+ color: #e2e8f0;
16
+ background-image: url('https://images.unsplash.com/photo-1518562180175-34a163b1a9fa?q=80&w=2070&auto=format&fit=crop');
17
+ background-size: cover;
18
+ background-attachment: fixed;
19
+ }
20
+
21
+ .card {
22
+ transition: all 0.3s ease;
23
+ transform-style: preserve-3d;
24
+ perspective: 1000px;
25
+ }
26
+
27
+ .card:hover {
28
+ transform: translateY(-10px) scale(1.03);
29
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.4);
30
+ }
31
+
32
+ .card-front {
33
+ backface-visibility: hidden;
34
+ }
35
+
36
+ .card-back {
37
+ backface-visibility: hidden;
38
+ transform: rotateY(180deg);
39
+ background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
40
+ }
41
+
42
+ .flipped {
43
+ transform: rotateY(180deg);
44
+ }
45
+
46
+ .health-bar {
47
+ height: 6px;
48
+ transition: width 0.3s ease;
49
+ }
50
+
51
+ .lane {
52
+ min-height: 200px;
53
+ background: rgba(30, 41, 59, 0.5);
54
+ border: 2px solid rgba(148, 163, 184, 0.3);
55
+ border-radius: 8px;
56
+ }
57
+
58
+ .attack-animation {
59
+ animation: attack 0.5s ease;
60
+ }
61
+
62
+ @keyframes attack {
63
+ 0% { transform: translateX(0); }
64
+ 50% { transform: translateX(20px); }
65
+ 100% { transform: translateX(0); }
66
+ }
67
+
68
+ .damage-text {
69
+ animation: floatUp 1s ease forwards;
70
+ position: absolute;
71
+ color: #f87171;
72
+ font-weight: bold;
73
+ pointer-events: none;
74
+ }
75
+
76
+ @keyframes floatUp {
77
+ 0% { transform: translateY(0); opacity: 1; }
78
+ 100% { transform: translateY(-50px); opacity: 0; }
79
+ }
80
+
81
+ .title-font {
82
+ font-family: 'Cinzel', serif;
83
+ }
84
+
85
+ .card-tooltip {
86
+ visibility: hidden;
87
+ width: 200px;
88
+ background-color: #1e293b;
89
+ color: #fff;
90
+ text-align: center;
91
+ border-radius: 6px;
92
+ padding: 10px;
93
+ position: absolute;
94
+ z-index: 1;
95
+ bottom: 125%;
96
+ left: 50%;
97
+ transform: translateX(-50%);
98
+ opacity: 0;
99
+ transition: opacity 0.3s;
100
+ border: 1px solid #475569;
101
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
102
+ }
103
+
104
+ .card:hover .card-tooltip {
105
+ visibility: visible;
106
+ opacity: 1;
107
+ }
108
+
109
+ .end-turn-btn {
110
+ position: fixed;
111
+ bottom: 20px;
112
+ right: 20px;
113
+ z-index: 40;
114
+ transition: all 0.3s ease;
115
+ }
116
+
117
+ .end-turn-btn:hover {
118
+ transform: scale(1.05);
119
+ }
120
+ </style>
121
+ </head>
122
+ <body class="min-h-screen">
123
+ <div class="container mx-auto px-4 py-8">
124
+ <!-- Header -->
125
+ <header class="flex flex-col items-center mb-8">
126
+ <h1 class="title-font text-5xl font-bold text-amber-400 mb-2 text-center">Arcane Chronicles</h1>
127
+ <h2 class="title-font text-2xl text-amber-200 mb-6 text-center">Battle of Realms</h2>
128
+
129
+ <div class="flex space-x-4 mb-6">
130
+ <button id="new-game-btn" class="bg-amber-600 hover:bg-amber-700 text-white px-6 py-2 rounded-lg font-semibold transition">
131
+ <i class="fas fa-play mr-2"></i>New Game
132
+ </button>
133
+ <button id="rules-btn" class="bg-slate-700 hover:bg-slate-600 text-white px-6 py-2 rounded-lg font-semibold transition">
134
+ <i class="fas fa-scroll mr-2"></i>Rules
135
+ </button>
136
+ </div>
137
+
138
+ <div class="flex justify-between w-full max-w-2xl bg-slate-800 p-4 rounded-lg">
139
+ <div class="text-center">
140
+ <div class="text-xl font-semibold text-amber-300">Player</div>
141
+ <div id="player-health" class="text-3xl font-bold">30</div>
142
+ </div>
143
+ <div class="text-center">
144
+ <div class="text-xl font-semibold">Mana</div>
145
+ <div id="current-mana" class="text-3xl font-bold text-blue-400">0/10</div>
146
+ </div>
147
+ <div class="text-center">
148
+ <div class="text-xl font-semibold text-red-300">Enemy</div>
149
+ <div id="enemy-health" class="text-3xl font-bold">30</div>
150
+ </div>
151
+ </div>
152
+ </header>
153
+
154
+ <!-- Game Board -->
155
+ <div class="game-board mb-8">
156
+ <!-- Enemy Lane -->
157
+ <div class="grid grid-cols-2 gap-4 mb-6">
158
+ <div class="lane" id="enemy-field-lane">
159
+ <!-- Enemy cards will appear here -->
160
+ </div>
161
+ <div class="lane" id="enemy-shadow-lane">
162
+ <!-- Enemy cards will appear here -->
163
+ </div>
164
+ </div>
165
+
166
+ <!-- Player Lane -->
167
+ <div class="grid grid-cols-2 gap-4 mb-6">
168
+ <div class="lane" id="player-field-lane">
169
+ <!-- Player cards will appear here -->
170
+ </div>
171
+ <div class="lane" id="player-shadow-lane">
172
+ <!-- Player cards will appear here -->
173
+ </div>
174
+ </div>
175
+ </div>
176
+
177
+ <!-- Player Hand -->
178
+ <div class="player-hand-container bg-slate-900 bg-opacity-70 p-4 rounded-t-lg">
179
+ <h3 class="text-xl font-semibold mb-4 text-center">Your Hand</h3>
180
+ <div class="flex justify-center flex-wrap gap-4 min-h-32" id="player-hand">
181
+ <!-- Player cards will appear here -->
182
+ </div>
183
+ </div>
184
+
185
+ <!-- End Turn Button -->
186
+ <button id="end-turn-btn" class="end-turn-btn bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-full font-semibold transition shadow-lg hidden">
187
+ <i class="fas fa-hourglass-end mr-2"></i>End Turn
188
+ </button>
189
+
190
+ <!-- Modals -->
191
+ <div id="rules-modal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center hidden z-50">
192
+ <div class="bg-slate-800 rounded-lg p-6 max-w-2xl max-h-[80vh] overflow-y-auto">
193
+ <div class="flex justify-between items-center mb-4">
194
+ <h3 class="text-2xl font-bold text-amber-300">Game Rules</h3>
195
+ <button id="close-rules" class="text-slate-400 hover:text-white">
196
+ <i class="fas fa-times"></i>
197
+ </button>
198
+ </div>
199
+
200
+ <div class="space-y-4">
201
+ <div>
202
+ <h4 class="text-lg font-semibold text-amber-200 mb-2">Objective</h4>
203
+ <p>Reduce your opponent's health to zero by strategically playing creatures and using abilities.</p>
204
+ </div>
205
+
206
+ <div>
207
+ <h4 class="text-lg font-semibold text-amber-200 mb-2">Lanes</h4>
208
+ <p>The battlefield has two lanes: Field Lane and Shadow Lane.</p>
209
+ <ul class="list-disc pl-5 mt-2 space-y-1">
210
+ <li><span class="font-semibold">Field Lane:</span> Creatures here can attack the turn they're played.</li>
211
+ <li><span class="font-semibold">Shadow Lane:</span> Creatures here gain Cover for one turn, protecting them from attacks.</li>
212
+ </ul>
213
+ </div>
214
+
215
+ <div>
216
+ <h4 class="text-lg font-semibold text-amber-200 mb-2">Mana System</h4>
217
+ <p>You start with 1 mana and gain 1 additional mana each turn (max 10).</p>
218
+ </div>
219
+
220
+ <div>
221
+ <h4 class="text-lg font-semibold text-amber-200 mb-2">Card Types</h4>
222
+ <ul class="list-disc pl-5 mt-2 space-y-1">
223
+ <li><span class="font-semibold">Creatures:</span> Can attack enemy creatures or the opponent directly.</li>
224
+ <li><span class="font-semibold">Actions:</span> One-time effects that can deal damage, heal, or modify the board.</li>
225
+ <li><span class="font-semibold">Supports:</span> Ongoing effects that remain on the board until destroyed.</li>
226
+ </ul>
227
+ </div>
228
+
229
+ <div>
230
+ <h4 class="text-lg font-semibold text-amber-200 mb-2">Keywords</h4>
231
+ <div class="grid grid-cols-2 gap-2 mt-2">
232
+ <div class="bg-slate-700 p-2 rounded">
233
+ <span class="font-semibold">Breakthrough:</span> Excess damage goes to the opponent.
234
+ </div>
235
+ <div class="bg-slate-700 p-2 rounded">
236
+ <span class="font-semibold">Drain:</span> Heals your health equal to damage dealt.
237
+ </div>
238
+ <div class="bg-slate-700 p-2 rounded">
239
+ <span class="font-semibold">Guard:</span> Must be attacked before other targets.
240
+ </div>
241
+ <div class="bg-slate-700 p-2 rounded">
242
+ <span class="font-semibold">Lethal:</span> Destroys any creature it damages.
243
+ </div>
244
+ </div>
245
+ </div>
246
+ </div>
247
+ </div>
248
+ </div>
249
+
250
+ <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center hidden z-50">
251
+ <div class="bg-slate-800 rounded-lg p-8 max-w-md text-center">
252
+ <h3 id="game-result" class="text-3xl font-bold mb-4">Victory!</h3>
253
+ <p id="game-over-text" class="mb-6">You have defeated your opponent!</p>
254
+ <button id="play-again-btn" class="bg-amber-600 hover:bg-amber-700 text-white px-6 py-2 rounded-lg font-semibold transition">
255
+ <i class="fas fa-redo mr-2"></i>Play Again
256
+ </button>
257
+ </div>
258
+ </div>
259
+
260
+ <div id="turn-indicator" class="fixed top-4 right-4 bg-slate-800 bg-opacity-80 px-4 py-2 rounded-lg shadow-lg hidden">
261
+ <div class="flex items-center">
262
+ <div id="turn-arrow" class="text-amber-400 mr-2">
263
+ <i class="fas fa-arrow-right"></i>
264
+ </div>
265
+ <span id="turn-text" class="font-semibold">Your Turn</span>
266
+ </div>
267
+ </div>
268
+ </div>
269
+
270
+ <script>
271
+ // Game State
272
+ const gameState = {
273
+ playerHealth: 30,
274
+ enemyHealth: 30,
275
+ playerMana: 0,
276
+ maxMana: 0,
277
+ turn: 'player', // 'player' or 'enemy'
278
+ turnCount: 0,
279
+ playerHand: [],
280
+ playerFieldLane: [],
281
+ playerShadowLane: [],
282
+ enemyFieldLane: [],
283
+ enemyShadowLane: [],
284
+ playerDeck: [],
285
+ enemyDeck: [],
286
+ enemyHand: [],
287
+ gameStarted: false
288
+ };
289
+
290
+ // Card Database with more low-cost cards
291
+ const cardDatabase = [
292
+ // Low cost creatures (1-3 mana)
293
+ {
294
+ id: 1,
295
+ name: "Arcane Apprentice",
296
+ type: "creature",
297
+ cost: 1,
298
+ attack: 1,
299
+ health: 2,
300
+ keywords: [],
301
+ lane: "field",
302
+ description: "A novice mage learning the arcane arts.",
303
+ image: "https://images.unsplash.com/photo-1542273917363-3b1817f69a2b?q=80&w=2074&auto=format&fit=crop"
304
+ },
305
+ {
306
+ id: 2,
307
+ name: "Forest Sprite",
308
+ type: "creature",
309
+ cost: 1,
310
+ attack: 1,
311
+ health: 1,
312
+ keywords: [],
313
+ lane: "shadow",
314
+ description: "A tiny woodland spirit that moves swiftly.",
315
+ image: "https://images.unsplash.com/photo-1519457431-44ccd64a7b47?q=80&w=1935&auto=format&fit=crop"
316
+ },
317
+ {
318
+ id: 3,
319
+ name: "Town Guard",
320
+ type: "creature",
321
+ cost: 2,
322
+ attack: 2,
323
+ health: 2,
324
+ keywords: ["Guard"],
325
+ lane: "field",
326
+ description: "Protects the town from threats.",
327
+ image: "https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0?q=80&w=2070&auto=format&fit=crop"
328
+ },
329
+ {
330
+ id: 4,
331
+ name: "Shadow Thief",
332
+ type: "creature",
333
+ cost: 2,
334
+ attack: 3,
335
+ health: 1,
336
+ keywords: [],
337
+ lane: "shadow",
338
+ description: "Strikes quickly from the darkness.",
339
+ image: "https://images.unsplash.com/photo-1518709268805-4e9042af9f23?q=80&w=2048&auto=format&fit=crop"
340
+ },
341
+ {
342
+ id: 5,
343
+ name: "Arcane Sentinel",
344
+ type: "creature",
345
+ cost: 3,
346
+ attack: 2,
347
+ health: 3,
348
+ keywords: ["Guard"],
349
+ lane: "field",
350
+ description: "A mystical guardian that protects its allies.",
351
+ image: "https://images.unsplash.com/photo-1476231682828-37e571bc172f?q=80&w=1974&auto=format&fit=crop"
352
+ },
353
+ {
354
+ id: 6,
355
+ name: "Shadow Assassin",
356
+ type: "creature",
357
+ cost: 3,
358
+ attack: 4,
359
+ health: 2,
360
+ keywords: ["Lethal"],
361
+ lane: "shadow",
362
+ description: "Strikes from the darkness with deadly precision.",
363
+ image: "https://images.unsplash.com/photo-1519457431-44ccd64a7b47?q=80&w=1935&auto=format&fit=crop"
364
+ },
365
+ {
366
+ id: 7,
367
+ name: "Mountain Wolf",
368
+ type: "creature",
369
+ cost: 3,
370
+ attack: 3,
371
+ health: 3,
372
+ keywords: [],
373
+ lane: "field",
374
+ description: "A fierce predator of the highlands.",
375
+ image: "https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0?q=80&w=2070&auto=format&fit=crop"
376
+ },
377
+
378
+ // Mid cost creatures (4-6 mana)
379
+ {
380
+ id: 8,
381
+ name: "Stormcaller",
382
+ type: "creature",
383
+ cost: 4,
384
+ attack: 3,
385
+ health: 4,
386
+ keywords: ["Breakthrough"],
387
+ lane: "field",
388
+ description: "Channels the fury of the storm into devastating attacks.",
389
+ image: "https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0?q=80&w=2070&auto=format&fit=crop"
390
+ },
391
+ {
392
+ id: 9,
393
+ name: "Vampire Noble",
394
+ type: "creature",
395
+ cost: 5,
396
+ attack: 4,
397
+ health: 4,
398
+ keywords: ["Drain"],
399
+ lane: "shadow",
400
+ description: "Feeds on the life force of its enemies.",
401
+ image: "https://images.unsplash.com/photo-1518709268805-4e9042af9f23?q=80&w=2048&auto=format&fit=crop"
402
+ },
403
+ {
404
+ id: 10,
405
+ name: "Ancient Treant",
406
+ type: "creature",
407
+ cost: 6,
408
+ attack: 2,
409
+ health: 6,
410
+ keywords: ["Guard"],
411
+ lane: "field",
412
+ description: "An ancient protector of the forests.",
413
+ image: "https://images.unsplash.com/photo-1476231682828-37e571bc172f?q=80&w=1974&auto=format&fit=crop"
414
+ },
415
+
416
+ // Actions
417
+ {
418
+ id: 11,
419
+ name: "Spark",
420
+ type: "action",
421
+ cost: 1,
422
+ effect: "dealDamage",
423
+ value: 2,
424
+ description: "Deals 2 damage to a target.",
425
+ image: "https://images.unsplash.com/photo-1518562180175-34a163b1a9fa?q=80&w=2070&auto=format&fit=crop"
426
+ },
427
+ {
428
+ id: 12,
429
+ name: "Minor Heal",
430
+ type: "action",
431
+ cost: 1,
432
+ effect: "heal",
433
+ value: 3,
434
+ description: "Restore 3 health to your hero.",
435
+ image: "https://images.unsplash.com/photo-1534447677768-be436bb09401?q=80&w=2094&auto=format&fit=crop"
436
+ },
437
+ {
438
+ id: 13,
439
+ name: "Fireball",
440
+ type: "action",
441
+ cost: 3,
442
+ effect: "dealDamage",
443
+ value: 4,
444
+ description: "Hurl a fiery projectile that deals 4 damage.",
445
+ image: "https://images.unsplash.com/photo-1518562180175-34a163b1a9fa?q=80&w=2070&auto=format&fit=crop"
446
+ },
447
+ {
448
+ id: 14,
449
+ name: "Healing Light",
450
+ type: "action",
451
+ cost: 2,
452
+ effect: "heal",
453
+ value: 5,
454
+ description: "Restore 5 health to your hero.",
455
+ image: "https://images.unsplash.com/photo-1534447677768-be436bb09401?q=80&w=2094&auto=format&fit=crop"
456
+ },
457
+ {
458
+ id: 15,
459
+ name: "Soul Trap",
460
+ type: "action",
461
+ cost: 4,
462
+ effect: "destroyCreature",
463
+ description: "Destroy an enemy creature with 3 or less attack.",
464
+ image: "https://images.unsplash.com/photo-1534447677768-be436bb09401?q=80&w=2094&auto=format&fit=crop"
465
+ },
466
+
467
+ // Supports
468
+ {
469
+ id: 16,
470
+ name: "Training Grounds",
471
+ type: "support",
472
+ cost: 2,
473
+ effect: "buffCreatures",
474
+ value: 1,
475
+ description: "Your creatures have +1 attack.",
476
+ image: "https://images.unsplash.com/photo-1535905557558-3c2747c3d7a3?q=80&w=2070&auto=format&fit=crop"
477
+ },
478
+ {
479
+ id: 17,
480
+ name: "Arcane Library",
481
+ type: "support",
482
+ cost: 4,
483
+ effect: "drawCard",
484
+ value: 1,
485
+ description: "At the start of your turn, draw an extra card.",
486
+ image: "https://images.unsplash.com/photo-1535905557558-3c2747c3d7a3?q=80&w=2070&auto=format&fit=crop"
487
+ },
488
+ {
489
+ id: 18,
490
+ name: "Ward of Protection",
491
+ type: "support",
492
+ cost: 3,
493
+ effect: "reduceDamage",
494
+ value: 1,
495
+ description: "Your hero takes 1 less damage from all sources.",
496
+ image: "https://images.unsplash.com/photo-1505506874110-0a91101d6d41?q=80&w=2070&auto=format&fit=crop"
497
+ }
498
+ ];
499
+
500
+ // DOM Elements
501
+ const playerHealthEl = document.getElementById('player-health');
502
+ const enemyHealthEl = document.getElementById('enemy-health');
503
+ const currentManaEl = document.getElementById('current-mana');
504
+ const playerHandEl = document.getElementById('player-hand');
505
+ const playerFieldLaneEl = document.getElementById('player-field-lane');
506
+ const playerShadowLaneEl = document.getElementById('player-shadow-lane');
507
+ const enemyFieldLaneEl = document.getElementById('enemy-field-lane');
508
+ const enemyShadowLaneEl = document.getElementById('enemy-shadow-lane');
509
+ const newGameBtn = document.getElementById('new-game-btn');
510
+ const rulesBtn = document.getElementById('rules-btn');
511
+ const closeRulesBtn = document.getElementById('close-rules');
512
+ const rulesModal = document.getElementById('rules-modal');
513
+ const gameOverModal = document.getElementById('game-over-modal');
514
+ const gameResultEl = document.getElementById('game-result');
515
+ const gameOverTextEl = document.getElementById('game-over-text');
516
+ const playAgainBtn = document.getElementById('play-again-btn');
517
+ const turnIndicator = document.getElementById('turn-indicator');
518
+ const turnText = document.getElementById('turn-text');
519
+ const turnArrow = document.getElementById('turn-arrow');
520
+ const endTurnBtn = document.getElementById('end-turn-btn');
521
+
522
+ // Event Listeners
523
+ newGameBtn.addEventListener('click', startNewGame);
524
+ rulesBtn.addEventListener('click', () => rulesModal.classList.remove('hidden'));
525
+ closeRulesBtn.addEventListener('click', () => rulesModal.classList.add('hidden'));
526
+ playAgainBtn.addEventListener('click', startNewGame);
527
+ endTurnBtn.addEventListener('click', endPlayerTurn);
528
+
529
+ // Game Functions
530
+ function startNewGame() {
531
+ // Reset game state
532
+ gameState.playerHealth = 30;
533
+ gameState.enemyHealth = 30;
534
+ gameState.playerMana = 0;
535
+ gameState.maxMana = 0;
536
+ gameState.turn = 'player';
537
+ gameState.turnCount = 0;
538
+ gameState.playerHand = [];
539
+ gameState.playerFieldLane = [];
540
+ gameState.playerShadowLane = [];
541
+ gameState.enemyFieldLane = [];
542
+ gameState.enemyShadowLane = [];
543
+ gameState.playerDeck = [];
544
+ gameState.enemyDeck = [];
545
+ gameState.enemyHand = [];
546
+ gameState.gameStarted = true;
547
+
548
+ // Hide modals
549
+ gameOverModal.classList.add('hidden');
550
+ rulesModal.classList.add('hidden');
551
+
552
+ // Update UI
553
+ playerHealthEl.textContent = gameState.playerHealth;
554
+ enemyHealthEl.textContent = gameState.enemyHealth;
555
+ currentManaEl.textContent = `${gameState.playerMana}/${gameState.maxMana}`;
556
+
557
+ // Clear board
558
+ playerHandEl.innerHTML = '';
559
+ playerFieldLaneEl.innerHTML = '';
560
+ playerShadowLaneEl.innerHTML = '';
561
+ enemyFieldLaneEl.innerHTML = '';
562
+ enemyShadowLaneEl.innerHTML = '';
563
+
564
+ // Create decks
565
+ createDecks();
566
+
567
+ // Draw starting hands
568
+ drawStartingHands();
569
+
570
+ // Start first turn
571
+ startPlayerTurn();
572
+
573
+ // Show turn indicator
574
+ turnIndicator.classList.remove('hidden');
575
+ updateTurnIndicator();
576
+
577
+ // Show end turn button
578
+ endTurnBtn.classList.remove('hidden');
579
+ }
580
+
581
+ function createDecks() {
582
+ // Create player deck (30 cards)
583
+ for (let i = 0; i < 30; i++) {
584
+ const randomCard = {...cardDatabase[Math.floor(Math.random() * cardDatabase.length)]};
585
+ gameState.playerDeck.push(randomCard);
586
+ }
587
+
588
+ // Create enemy deck (30 cards)
589
+ for (let i = 0; i < 30; i++) {
590
+ const randomCard = {...cardDatabase[Math.floor(Math.random() * cardDatabase.length)]};
591
+ gameState.enemyDeck.push(randomCard);
592
+ }
593
+ }
594
+
595
+ function drawStartingHands() {
596
+ // Player draws 3 cards
597
+ for (let i = 0; i < 3; i++) {
598
+ drawCard('player');
599
+ }
600
+
601
+ // Enemy draws 3 cards
602
+ for (let i = 0; i < 3; i++) {
603
+ drawCard('enemy');
604
+ }
605
+ }
606
+
607
+ function drawCard(who) {
608
+ if (who === 'player') {
609
+ if (gameState.playerDeck.length > 0) {
610
+ const card = gameState.playerDeck.pop();
611
+ gameState.playerHand.push(card);
612
+ renderPlayerHand();
613
+ }
614
+ } else {
615
+ if (gameState.enemyDeck.length > 0) {
616
+ const card = gameState.enemyDeck.pop();
617
+ gameState.enemyHand.push(card);
618
+ }
619
+ }
620
+ }
621
+
622
+ function startPlayerTurn() {
623
+ gameState.turn = 'player';
624
+ gameState.turnCount++;
625
+
626
+ // Increase max mana (up to 10)
627
+ if (gameState.maxMana < 10) {
628
+ gameState.maxMana++;
629
+ }
630
+
631
+ // Refill mana
632
+ gameState.playerMana = gameState.maxMana;
633
+
634
+ // Draw a card
635
+ drawCard('player');
636
+
637
+ // Update UI
638
+ updateTurnIndicator();
639
+ currentManaEl.textContent = `${gameState.playerMana}/${gameState.maxMana}`;
640
+
641
+ // Check for summoning sickness
642
+ updateSummoningSickness();
643
+
644
+ // Enable player actions
645
+ enablePlayerActions();
646
+
647
+ // Show end turn button
648
+ endTurnBtn.classList.remove('hidden');
649
+ }
650
+
651
+ function endPlayerTurn() {
652
+ // Hide end turn button
653
+ endTurnBtn.classList.add('hidden');
654
+
655
+ // Start enemy turn
656
+ startEnemyTurn();
657
+ }
658
+
659
+ function startEnemyTurn() {
660
+ gameState.turn = 'enemy';
661
+ updateTurnIndicator();
662
+
663
+ // Disable player actions
664
+ disablePlayerActions();
665
+
666
+ // Enemy draws a card
667
+ drawCard('enemy');
668
+
669
+ // Simple AI: Play cards and attack
670
+ setTimeout(() => {
671
+ enemyPlayCards();
672
+
673
+ setTimeout(() => {
674
+ enemyAttack();
675
+
676
+ // End enemy turn after a delay
677
+ setTimeout(() => {
678
+ startPlayerTurn();
679
+ }, 1500);
680
+ }, 1500);
681
+ }, 1500);
682
+ }
683
+
684
+ function enemyPlayCards() {
685
+ // Simple AI: Play cards if possible
686
+ const playableCards = gameState.enemyHand.filter(card => card.cost <= gameState.maxMana);
687
+
688
+ for (const card of playableCards) {
689
+ if (Math.random() > 0.3) { // 70% chance to play each card
690
+ // Determine lane
691
+ const lane = card.lane || (Math.random() > 0.5 ? 'field' : 'shadow');
692
+
693
+ // Play the card
694
+ playCard('enemy', card, lane);
695
+
696
+ // Remove from hand
697
+ const cardIndex = gameState.enemyHand.findIndex(c => c.id === card.id);
698
+ if (cardIndex !== -1) {
699
+ gameState.enemyHand.splice(cardIndex, 1);
700
+ }
701
+ }
702
+ }
703
+ }
704
+
705
+ function enemyAttack() {
706
+ // Simple AI: Attack with all creatures
707
+ const allEnemyCreatures = [...gameState.enemyFieldLane, ...gameState.enemyShadowLane];
708
+
709
+ for (const creature of allEnemyCreatures) {
710
+ if (!creature.hasAttacked && !creature.summoningSickness) {
711
+ // Find a target (simplified - just attack player directly)
712
+ attackTarget('enemy', creature, {type: 'player'});
713
+ }
714
+ }
715
+ }
716
+
717
+ function playCard(who, card, lane) {
718
+ if (who === 'player') {
719
+ // Check if player has enough mana
720
+ if (gameState.playerMana < card.cost) {
721
+ alert("Not enough mana!");
722
+ return;
723
+ }
724
+
725
+ // Spend mana
726
+ gameState.playerMana -= card.cost;
727
+ currentManaEl.textContent = `${gameState.playerMana}/${gameState.maxMana}`;
728
+
729
+ // Remove card from hand
730
+ const cardIndex = gameState.playerHand.findIndex(c => c.id === card.id);
731
+ if (cardIndex !== -1) {
732
+ gameState.playerHand.splice(cardIndex, 1);
733
+ }
734
+
735
+ // Add to appropriate lane
736
+ if (card.type === 'creature') {
737
+ const creature = {...card, hasAttacked: false, summoningSickness: true};
738
+
739
+ if (lane === 'field') {
740
+ gameState.playerFieldLane.push(creature);
741
+ } else {
742
+ gameState.playerShadowLane.push(creature);
743
+ }
744
+ }
745
+
746
+ // Re-render
747
+ renderPlayerHand();
748
+ renderPlayerLanes();
749
+ } else {
750
+ // Enemy plays a card
751
+ if (card.type === 'creature') {
752
+ const creature = {...card, hasAttacked: false, summoningSickness: true};
753
+
754
+ if (lane === 'field') {
755
+ gameState.enemyFieldLane.push(creature);
756
+ } else {
757
+ gameState.enemyShadowLane.push(creature);
758
+ }
759
+ }
760
+
761
+ renderEnemyLanes();
762
+ }
763
+ }
764
+
765
+ function attackTarget(attackerWho, attacker, target) {
766
+ if (attackerWho === 'player') {
767
+ if (attacker.summoningSickness) {
768
+ alert("This creature has summoning sickness and can't attack this turn!");
769
+ return;
770
+ }
771
+
772
+ if (attacker.hasAttacked) {
773
+ alert("This creature has already attacked this turn!");
774
+ return;
775
+ }
776
+
777
+ // Mark as attacked
778
+ attacker.hasAttacked = true;
779
+
780
+ // Apply damage
781
+ if (target.type === 'creature') {
782
+ // Creature vs creature combat
783
+ target.health -= attacker.attack;
784
+ attacker.health -= target.attack;
785
+
786
+ // Check for deaths
787
+ checkForDeaths();
788
+
789
+ // Show damage animation
790
+ showDamageAnimation(target, attacker.attack);
791
+ showDamageAnimation(attacker, target.attack);
792
+ } else if (target.type === 'player') {
793
+ // Attack enemy directly
794
+ gameState.enemyHealth -= attacker.attack;
795
+ enemyHealthEl.textContent = gameState.enemyHealth;
796
+
797
+ // Show damage animation
798
+ showDamageAnimation({element: enemyHealthEl}, attacker.attack);
799
+
800
+ // Check for game over
801
+ if (gameState.enemyHealth <= 0) {
802
+ endGame('player');
803
+ }
804
+ }
805
+
806
+ // Re-render
807
+ renderPlayerLanes();
808
+ renderEnemyLanes();
809
+ } else {
810
+ // Enemy attacks
811
+ if (target.type === 'creature') {
812
+ // Creature vs creature combat
813
+ target.health -= attacker.attack;
814
+ attacker.health -= target.attack;
815
+
816
+ // Check for deaths
817
+ checkForDeaths();
818
+
819
+ // Show damage animation
820
+ showDamageAnimation(target, attacker.attack);
821
+ showDamageAnimation(attacker, target.attack);
822
+ } else if (target.type === 'player') {
823
+ // Attack player directly
824
+ gameState.playerHealth -= attacker.attack;
825
+ playerHealthEl.textContent = gameState.playerHealth;
826
+
827
+ // Show damage animation
828
+ showDamageAnimation({element: playerHealthEl}, attacker.attack);
829
+
830
+ // Check for game over
831
+ if (gameState.playerHealth <= 0) {
832
+ endGame('enemy');
833
+ }
834
+ }
835
+
836
+ // Re-render
837
+ renderPlayerLanes();
838
+ renderEnemyLanes();
839
+ }
840
+ }
841
+
842
+ function checkForDeaths() {
843
+ // Check player field lane
844
+ gameState.playerFieldLane = gameState.playerFieldLane.filter(creature => creature.health > 0);
845
+
846
+ // Check player shadow lane
847
+ gameState.playerShadowLane = gameState.playerShadowLane.filter(creature => creature.health > 0);
848
+
849
+ // Check enemy field lane
850
+ gameState.enemyFieldLane = gameState.enemyFieldLane.filter(creature => creature.health > 0);
851
+
852
+ // Check enemy shadow lane
853
+ gameState.enemyShadowLane = gameState.enemyShadowLane.filter(creature => creature.health > 0);
854
+ }
855
+
856
+ function endGame(winner) {
857
+ gameState.gameStarted = false;
858
+
859
+ if (winner === 'player') {
860
+ gameResultEl.textContent = "Victory!";
861
+ gameOverTextEl.textContent = "You have defeated your opponent!";
862
+ } else {
863
+ gameResultEl.textContent = "Defeat";
864
+ gameOverTextEl.textContent = "Your opponent has defeated you!";
865
+ }
866
+
867
+ gameOverModal.classList.remove('hidden');
868
+ turnIndicator.classList.add('hidden');
869
+ endTurnBtn.classList.add('hidden');
870
+ }
871
+
872
+ function updateSummoningSickness() {
873
+ // Remove summoning sickness from player creatures
874
+ gameState.playerFieldLane.forEach(creature => {
875
+ if (creature.summoningSickness) {
876
+ creature.summoningSickness = false;
877
+ }
878
+ creature.hasAttacked = false;
879
+ });
880
+
881
+ gameState.playerShadowLane.forEach(creature => {
882
+ if (creature.summoningSickness) {
883
+ creature.summoningSickness = false;
884
+ }
885
+ creature.hasAttacked = false;
886
+ });
887
+
888
+ // Re-render
889
+ renderPlayerLanes();
890
+ }
891
+
892
+ function enablePlayerActions() {
893
+ // Enable hand cards
894
+ const handCards = document.querySelectorAll('.hand-card');
895
+ handCards.forEach(card => {
896
+ card.classList.remove('opacity-50', 'cursor-not-allowed');
897
+ card.classList.add('cursor-pointer', 'hover:scale-105');
898
+ });
899
+
900
+ // Enable creatures to attack
901
+ const playerCreatures = document.querySelectorAll('#player-field-lane .creature, #player-shadow-lane .creature');
902
+ playerCreatures.forEach(creature => {
903
+ if (!creature.dataset.hasAttacked && !creature.dataset.summoningSickness) {
904
+ creature.classList.add('cursor-pointer', 'hover:scale-105');
905
+ }
906
+ });
907
+ }
908
+
909
+ function disablePlayerActions() {
910
+ // Disable hand cards
911
+ const handCards = document.querySelectorAll('.hand-card');
912
+ handCards.forEach(card => {
913
+ card.classList.add('opacity-50', 'cursor-not-allowed');
914
+ card.classList.remove('cursor-pointer', 'hover:scale-105');
915
+ });
916
+
917
+ // Disable creatures from attacking
918
+ const playerCreatures = document.querySelectorAll('#player-field-lane .creature, #player-shadow-lane .creature');
919
+ playerCreatures.forEach(creature => {
920
+ creature.classList.remove('cursor-pointer', 'hover:scale-105');
921
+ });
922
+ }
923
+
924
+ function updateTurnIndicator() {
925
+ if (gameState.turn === 'player') {
926
+ turnText.textContent = "Your Turn";
927
+ turnArrow.innerHTML = '<i class="fas fa-arrow-right"></i>';
928
+ } else {
929
+ turnText.textContent = "Enemy Turn";
930
+ turnArrow.innerHTML = '<i class="fas fa-arrow-left"></i>';
931
+ }
932
+ }
933
+
934
+ function showDamageAnimation(target, damage) {
935
+ const element = target.element || document.getElementById(`creature-${target.id}`);
936
+ if (!element) return;
937
+
938
+ const rect = element.getBoundingClientRect();
939
+ const damageText = document.createElement('div');
940
+ damageText.className = 'damage-text';
941
+ damageText.textContent = `-${damage}`;
942
+ damageText.style.left = `${rect.left + rect.width / 2}px`;
943
+ damageText.style.top = `${rect.top}px`;
944
+
945
+ document.body.appendChild(damageText);
946
+
947
+ // Remove after animation
948
+ setTimeout(() => {
949
+ damageText.remove();
950
+ }, 1000);
951
+ }
952
+
953
+ // Rendering Functions
954
+ function renderPlayerHand() {
955
+ playerHandEl.innerHTML = '';
956
+
957
+ gameState.playerHand.forEach((card, index) => {
958
+ const cardEl = createCardElement(card, 'hand');
959
+ cardEl.dataset.index = index;
960
+ playerHandEl.appendChild(cardEl);
961
+ });
962
+ }
963
+
964
+ function renderPlayerLanes() {
965
+ playerFieldLaneEl.innerHTML = '';
966
+ playerShadowLaneEl.innerHTML = '';
967
+
968
+ // Field Lane
969
+ gameState.playerFieldLane.forEach((creature, index) => {
970
+ const creatureEl = createCreatureElement(creature, 'player', index);
971
+ creatureEl.id = `creature-player-${index}`;
972
+ creatureEl.dataset.hasAttacked = creature.hasAttacked;
973
+ creatureEl.dataset.summoningSickness = creature.summoningSickness;
974
+ playerFieldLaneEl.appendChild(creatureEl);
975
+ });
976
+
977
+ // Shadow Lane
978
+ gameState.playerShadowLane.forEach((creature, index) => {
979
+ const creatureEl = createCreatureElement(creature, 'player', index);
980
+ creatureEl.id = `creature-player-${index}`;
981
+ creatureEl.dataset.hasAttacked = creature.hasAttacked;
982
+ creatureEl.dataset.summoningSickness = creature.summoningSickness;
983
+ playerShadowLaneEl.appendChild(creatureEl);
984
+ });
985
+ }
986
+
987
+ function renderEnemyLanes() {
988
+ enemyFieldLaneEl.innerHTML = '';
989
+ enemyShadowLaneEl.innerHTML = '';
990
+
991
+ // Field Lane
992
+ gameState.enemyFieldLane.forEach((creature, index) => {
993
+ const creatureEl = createCreatureElement(creature, 'enemy', index);
994
+ creatureEl.id = `creature-enemy-${index}`;
995
+ enemyFieldLaneEl.appendChild(creatureEl);
996
+ });
997
+
998
+ // Shadow Lane
999
+ gameState.enemyShadowLane.forEach((creature, index) => {
1000
+ const creatureEl = createCreatureElement(creature, 'enemy', index);
1001
+ creatureEl.id = `creature-enemy-${index}`;
1002
+ enemyShadowLaneEl.appendChild(creatureEl);
1003
+ });
1004
+ }
1005
+
1006
+ function createCardElement(card, location) {
1007
+ const cardEl = document.createElement('div');
1008
+ cardEl.className = `card relative ${location === 'hand' ? 'hand-card w-24 h-32' : 'w-full h-full'} bg-slate-700 rounded-lg overflow-hidden shadow-lg`;
1009
+ cardEl.dataset.id = card.id;
1010
+
1011
+ // Card front
1012
+ const cardFront = document.createElement('div');
1013
+ cardFront.className = 'card-front w-full h-full flex flex-col';
1014
+
1015
+ // Card image
1016
+ const imgContainer = document.createElement('div');
1017
+ imgContainer.className = 'flex-1 bg-cover bg-center';
1018
+ imgContainer.style.backgroundImage = `url(${card.image})`;
1019
+
1020
+ // Card info
1021
+ const infoContainer = document.createElement('div');
1022
+ infoContainer.className = 'bg-slate-800 p-2';
1023
+
1024
+ // Name and cost
1025
+ const nameCost = document.createElement('div');
1026
+ nameCost.className = 'flex justify-between items-center mb-1';
1027
+
1028
+ const nameEl = document.createElement('div');
1029
+ nameEl.className = 'font-semibold text-sm truncate';
1030
+ nameEl.textContent = card.name;
1031
+
1032
+ const costEl = document.createElement('div');
1033
+ costEl.className = 'bg-blue-500 text-white text-xs font-bold rounded-full w-6 h-6 flex items-center justify-center';
1034
+ costEl.textContent = card.cost;
1035
+
1036
+ nameCost.appendChild(nameEl);
1037
+ nameCost.appendChild(costEl);
1038
+
1039
+ // Type and stats (if creature)
1040
+ const typeStats = document.createElement('div');
1041
+ typeStats.className = 'flex justify-between items-center text-xs';
1042
+
1043
+ const typeEl = document.createElement('div');
1044
+ typeEl.className = 'text-slate-300 italic';
1045
+ typeEl.textContent = card.type;
1046
+
1047
+ typeStats.appendChild(typeEl);
1048
+
1049
+ if (card.type === 'creature') {
1050
+ const statsEl = document.createElement('div');
1051
+ statsEl.className = 'flex space-x-2';
1052
+
1053
+ const attackEl = document.createElement('div');
1054
+ attackEl.className = 'bg-red-500 text-white font-bold rounded-full w-6 h-6 flex items-center justify-center';
1055
+ attackEl.textContent = card.attack;
1056
+
1057
+ const healthEl = document.createElement('div');
1058
+ healthEl.className = 'bg-green-500 text-white font-bold rounded-full w-6 h-6 flex items-center justify-center';
1059
+ healthEl.textContent = card.health;
1060
+
1061
+ statsEl.appendChild(attackEl);
1062
+ statsEl.appendChild(healthEl);
1063
+ typeStats.appendChild(statsEl);
1064
+ }
1065
+
1066
+ infoContainer.appendChild(nameCost);
1067
+ infoContainer.appendChild(typeStats);
1068
+
1069
+ cardFront.appendChild(imgContainer);
1070
+ cardFront.appendChild(infoContainer);
1071
+
1072
+ // Tooltip
1073
+ const tooltip = document.createElement('div');
1074
+ tooltip.className = 'card-tooltip';
1075
+
1076
+ const tooltipName = document.createElement('div');
1077
+ tooltipName.className = 'font-bold text-amber-300 mb-1';
1078
+ tooltipName.textContent = card.name;
1079
+
1080
+ const tooltipType = document.createElement('div');
1081
+ tooltipType.className = 'text-xs text-slate-300 mb-2';
1082
+ tooltipType.textContent = `${card.type.charAt(0).toUpperCase() + card.type.slice(1)} • ${card.cost} mana`;
1083
+
1084
+ const tooltipDesc = document.createElement('div');
1085
+ tooltipDesc.className = 'text-sm';
1086
+ tooltipDesc.textContent = card.description;
1087
+
1088
+ if (card.keywords && card.keywords.length > 0) {
1089
+ const tooltipKeywords = document.createElement('div');
1090
+ tooltipKeywords.className = 'mt-2 flex flex-wrap gap-1';
1091
+
1092
+ card.keywords.forEach(keyword => {
1093
+ const keywordEl = document.createElement('span');
1094
+ keywordEl.className = 'bg-slate-600 text-xs px-2 py-1 rounded';
1095
+ keywordEl.textContent = keyword;
1096
+ tooltipKeywords.appendChild(keywordEl);
1097
+ });
1098
+
1099
+ tooltip.appendChild(tooltipKeywords);
1100
+ }
1101
+
1102
+ tooltip.appendChild(tooltipName);
1103
+ tooltip.appendChild(tooltipType);
1104
+ tooltip.appendChild(tooltipDesc);
1105
+
1106
+ cardEl.appendChild(cardFront);
1107
+ cardEl.appendChild(tooltip);
1108
+
1109
+ // Add event listeners for hand cards
1110
+ if (location === 'hand') {
1111
+ cardEl.addEventListener('click', () => {
1112
+ if (gameState.turn === 'player' && !cardEl.classList.contains('cursor-not-allowed')) {
1113
+ // For creatures, ask which lane to play in
1114
+ if (card.type === 'creature') {
1115
+ const lane = confirm("Play in Field Lane? (OK for Field, Cancel for Shadow)") ? 'field' : 'shadow';
1116
+ playCard('player', card, lane);
1117
+ } else {
1118
+ // For actions/supports, just play them
1119
+ playCard('player', card);
1120
+ }
1121
+ }
1122
+ });
1123
+ }
1124
+
1125
+ return cardEl;
1126
+ }
1127
+
1128
+ function createCreatureElement(creature, who, index) {
1129
+ const creatureEl = document.createElement('div');
1130
+ creatureEl.className = `creature relative inline-block m-2 ${creature.summoningSickness ? 'opacity-70' : ''}`;
1131
+ creatureEl.id = `creature-${who}-${index}`;
1132
+
1133
+ const cardEl = createCardElement(creature, 'board');
1134
+
1135
+ // Add health bar
1136
+ const healthBar = document.createElement('div');
1137
+ healthBar.className = 'health-bar bg-green-500 rounded-b';
1138
+ healthBar.style.width = '100%';
1139
+
1140
+ const infoContainer = cardEl.querySelector('.bg-slate-800');
1141
+ infoContainer.appendChild(healthBar);
1142
+
1143
+ // Update stats if damaged
1144
+ const originalCard = cardDatabase.find(c => c.id === creature.id);
1145
+ if (creature.health < originalCard.health) {
1146
+ const healthEl = cardEl.querySelector('.bg-green-500');
1147
+ if (healthEl) healthEl.textContent = creature.health;
1148
+ healthBar.style.width = `${(creature.health / originalCard.health) * 100}%`;
1149
+
1150
+ if (creature.health <= 2) {
1151
+ healthBar.className = 'health-bar bg-red-500 rounded-b';
1152
+ }
1153
+ }
1154
+
1155
+ // Add summoning sickness indicator
1156
+ if (creature.summoningSickness) {
1157
+ const sicknessIcon = document.createElement('div');
1158
+ sicknessIcon.className = 'absolute top-0 right-0 bg-yellow-500 text-black text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center';
1159
+ sicknessIcon.title = "Summoning Sickness";
1160
+ sicknessIcon.innerHTML = '<i class="fas fa-hourglass-start"></i>';
1161
+ cardEl.appendChild(sicknessIcon);
1162
+ }
1163
+
1164
+ // Add attack indicator if hasn't attacked
1165
+ if (!creature.hasAttacked && !creature.summoningSickness && gameState.turn === who) {
1166
+ const attackIcon = document.createElement('div');
1167
+ attackIcon.className = 'absolute top-0 left-0 bg-red-500 text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center';
1168
+ attackIcon.title = "Ready to Attack";
1169
+ attackIcon.innerHTML = '<i class="fas fa-bolt"></i>';
1170
+ cardEl.appendChild(attackIcon);
1171
+ }
1172
+
1173
+ creatureEl.appendChild(cardEl);
1174
+
1175
+ // Add event listener for attacking
1176
+ if (who === 'player' && !creature.hasAttacked && !creature.summoningSickness && gameState.turn === 'player') {
1177
+ creatureEl.classList.add('cursor-pointer', 'hover:scale-105');
1178
+ creatureEl.addEventListener('click', () => {
1179
+ // For simplicity, just attack enemy directly
1180
+ attackTarget('player', creature, {type: 'player'});
1181
+ });
1182
+ }
1183
+
1184
+ return creatureEl;
1185
+ }
1186
+
1187
+ // Initialize
1188
+ document.addEventListener('DOMContentLoaded', () => {
1189
+ // Show welcome message
1190
+ setTimeout(() => {
1191
+ rulesModal.classList.remove('hidden');
1192
+ }, 500);
1193
+ });
1194
+ </script>
1195
+ <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=Juno360219/dnd-style-card-game" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1196
+ </html>