AviKaye2025 commited on
Commit
388e168
Β·
verified Β·
1 Parent(s): 7febcfe

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +992 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Kayako Game
3
- emoji: 🐒
4
- colorFrom: purple
5
- colorTo: gray
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: kayako-game
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
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,992 @@
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>Ticket Triage Turbo</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ :root {
11
+ --primary: #3a86ff;
12
+ --danger: #ef476f;
13
+ --success: #06d6a0;
14
+ --warning: #ffd166;
15
+ --dark: #1c2541;
16
+ --light: #f8f9fa;
17
+ }
18
+
19
+ * {
20
+ margin: 0;
21
+ padding: 0;
22
+ box-sizing: border-box;
23
+ font-family: 'Poppins', sans-serif;
24
+ }
25
+
26
+ body {
27
+ background-color: #f0f2f5;
28
+ min-height: 100vh;
29
+ display: flex;
30
+ flex-direction: column;
31
+ align-items: center;
32
+ padding: 20px;
33
+ }
34
+
35
+ header {
36
+ text-align: center;
37
+ margin-bottom: 30px;
38
+ }
39
+
40
+ h1 {
41
+ color: var(--dark);
42
+ margin-bottom: 10px;
43
+ font-size: 2.5rem;
44
+ }
45
+
46
+ .score-display {
47
+ display: flex;
48
+ justify-content: center;
49
+ gap: 30px;
50
+ margin-bottom: 20px;
51
+ }
52
+
53
+ .score-box {
54
+ background: white;
55
+ padding: 15px 25px;
56
+ border-radius: 10px;
57
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 10px;
61
+ font-weight: 600;
62
+ }
63
+
64
+ .score-box .value {
65
+ font-size: 1.5rem;
66
+ }
67
+
68
+ #score {
69
+ color: var(--primary);
70
+ }
71
+
72
+ #streak {
73
+ color: var(--success);
74
+ }
75
+
76
+ .game-container {
77
+ width: 100%;
78
+ max-width: 800px;
79
+ background: white;
80
+ border-radius: 15px;
81
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
82
+ padding: 30px;
83
+ margin-bottom: 30px;
84
+ position: relative;
85
+ overflow: hidden;
86
+ }
87
+
88
+ .ticket-display {
89
+ background: var(--light);
90
+ border-radius: 10px;
91
+ padding: 20px;
92
+ min-height: 200px;
93
+ margin-bottom: 30px;
94
+ border: 2px dashed #dee2e6;
95
+ position: relative;
96
+ }
97
+
98
+ .ticket-content {
99
+ margin-bottom: 15px;
100
+ }
101
+
102
+ .ticket-meta {
103
+ display: flex;
104
+ justify-content: space-between;
105
+ color: #6c757d;
106
+ font-size: 0.9rem;
107
+ }
108
+
109
+ .tag {
110
+ display: inline-block;
111
+ padding: 3px 8px;
112
+ border-radius: 5px;
113
+ font-size: 0.8rem;
114
+ font-weight: 600;
115
+ margin-right: 8px;
116
+ }
117
+
118
+ .critical-tag {
119
+ background-color: var(--danger);
120
+ color: white;
121
+ }
122
+
123
+ .technical-tag {
124
+ background-color: var(--primary);
125
+ color: white;
126
+ }
127
+
128
+ .billing-tag {
129
+ background-color: var(--success);
130
+ color: white;
131
+ }
132
+
133
+ .feature-tag {
134
+ background-color: var(--warning);
135
+ color: var(--dark);
136
+ }
137
+
138
+ .actions {
139
+ display: flex;
140
+ justify-content: center;
141
+ gap: 20px;
142
+ margin-bottom: 30px;
143
+ }
144
+
145
+ .action-btn {
146
+ padding: 15px 25px;
147
+ border-radius: 8px;
148
+ border: none;
149
+ font-size: 1rem;
150
+ font-weight: 600;
151
+ cursor: pointer;
152
+ transition: all 0.2s;
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 10px;
156
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
157
+ }
158
+
159
+ .action-btn:active {
160
+ transform: translateY(3px);
161
+ }
162
+
163
+ .human-btn {
164
+ background-color: var(--primary);
165
+ color: white;
166
+ }
167
+
168
+ .ai-btn {
169
+ background-color: var(--success);
170
+ color: white;
171
+ }
172
+
173
+ .explanation {
174
+ text-align: center;
175
+ color: #6c757d;
176
+ margin-bottom: 20px;
177
+ min-height: 30px;
178
+ font-style: italic;
179
+ }
180
+
181
+ .emoji-feedback {
182
+ font-size: 3rem;
183
+ text-align: center;
184
+ height: 60px;
185
+ margin-bottom: 20px;
186
+ animation: fadeIn 0.5s;
187
+ }
188
+
189
+ @keyframes fadeIn {
190
+ from { opacity: 0; }
191
+ to { opacity: 1; }
192
+ }
193
+
194
+ .next-ticket {
195
+ text-align: center;
196
+ }
197
+
198
+ .next-btn {
199
+ padding: 10px 20px;
200
+ background-color: var(--dark);
201
+ color: white;
202
+ border: none;
203
+ border-radius: 5px;
204
+ cursor: pointer;
205
+ transition: all 0.2s;
206
+ }
207
+
208
+ .next-btn:hover {
209
+ background-color: #2c3b6b;
210
+ }
211
+
212
+ .progress-container {
213
+ width: 100%;
214
+ height: 10px;
215
+ background-color: #e9ecef;
216
+ border-radius: 5px;
217
+ margin-bottom: 30px;
218
+ }
219
+
220
+ .progress-bar {
221
+ height: 100%;
222
+ border-radius: 5px;
223
+ background-color: var(--primary);
224
+ width: 0;
225
+ transition: width 0.3s ease;
226
+ }
227
+
228
+ .timer {
229
+ font-size: 1.2rem;
230
+ color: var(--dark);
231
+ margin-bottom: 20px;
232
+ text-align: center;
233
+ }
234
+
235
+ .ticket-countdown {
236
+ position: absolute;
237
+ top: 10px;
238
+ right: 10px;
239
+ width: 30px;
240
+ height: 30px;
241
+ border-radius: 50%;
242
+ background-color: var(--primary);
243
+ color: white;
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ font-weight: bold;
248
+ }
249
+
250
+ .ticket-badge {
251
+ position: absolute;
252
+ top: 10px;
253
+ left: 10px;
254
+ background-color: var(--primary);
255
+ color: white;
256
+ padding: 3px 8px;
257
+ border-radius: 5px;
258
+ font-size: 0.8rem;
259
+ }
260
+
261
+ .game-over {
262
+ position: absolute;
263
+ top: 0;
264
+ left: 0;
265
+ width: 100%;
266
+ height: 100%;
267
+ background: rgba(255, 255, 255, 0.9);
268
+ display: flex;
269
+ flex-direction: column;
270
+ justify-content: center;
271
+ align-items: center;
272
+ z-index: 10;
273
+ opacity: 0;
274
+ pointer-events: none;
275
+ transition: opacity 0.3s;
276
+ }
277
+
278
+ .game-over.show {
279
+ opacity: 1;
280
+ pointer-events: all;
281
+ }
282
+
283
+ .game-over h2 {
284
+ font-size: 2rem;
285
+ margin-bottom: 20px;
286
+ color: var(--dark);
287
+ }
288
+
289
+ .final-score {
290
+ font-size: 1.5rem;
291
+ margin-bottom: 30px;
292
+ color: var(--primary);
293
+ }
294
+
295
+ .restart-btn {
296
+ padding: 15px 30px;
297
+ background-color: var(--primary);
298
+ color: white;
299
+ border: none;
300
+ border-radius: 8px;
301
+ font-size: 1rem;
302
+ font-weight: 600;
303
+ cursor: pointer;
304
+ transition: all 0.2s;
305
+ }
306
+
307
+ .restart-btn:hover {
308
+ background-color: #2a74e5;
309
+ }
310
+
311
+ .difficulty-selector {
312
+ margin-bottom: 20px;
313
+ }
314
+
315
+ .difficulty-btn {
316
+ padding: 8px 15px;
317
+ margin: 0 5px;
318
+ background-color: #e9ecef;
319
+ border: none;
320
+ border-radius: 5px;
321
+ cursor: pointer;
322
+ transition: all 0.2s;
323
+ }
324
+
325
+ .difficulty-btn.active {
326
+ background-color: var(--primary);
327
+ color: white;
328
+ }
329
+
330
+ .combo-meter {
331
+ width: 100%;
332
+ height: 6px;
333
+ background-color: #e9ecef;
334
+ border-radius: 3px;
335
+ margin-bottom: 10px;
336
+ overflow: hidden;
337
+ }
338
+
339
+ .combo-fill {
340
+ height: 100%;
341
+ background: linear-gradient(to right, var(--warning), var(--danger));
342
+ width: 0;
343
+ transition: width 0.3s;
344
+ }
345
+
346
+ .combo-display {
347
+ text-align: center;
348
+ color: #6c757d;
349
+ font-size: 0.9rem;
350
+ margin-bottom: 20px;
351
+ }
352
+
353
+ .highlight {
354
+ animation: highlight 1s;
355
+ }
356
+
357
+ @keyframes highlight {
358
+ 0% { background-color: initial; }
359
+ 50% { background-color: rgba(255, 215, 0, 0.3); }
360
+ 100% { background-color: initial; }
361
+ }
362
+
363
+ .floating-points {
364
+ position: absolute;
365
+ font-weight: bold;
366
+ color: var(--success);
367
+ animation: floatUp 1s forwards;
368
+ opacity: 0;
369
+ pointer-events: none;
370
+ }
371
+
372
+ @keyframes floatUp {
373
+ 0% { transform: translateY(0); opacity: 1; }
374
+ 100% { transform: translateY(-100px); opacity: 0; }
375
+ }
376
+ </style>
377
+ </head>
378
+ <body>
379
+ <header>
380
+ <h1>Ticket Triage Turbo</h1>
381
+ <p>Route support tickets to humans or AI as fast as possible!</p>
382
+ </header>
383
+
384
+ <div class="score-display">
385
+ <div class="score-box">
386
+ <i class="fas fa-star"></i>
387
+ <span>Score: </span>
388
+ <span class="value" id="score">0</span>
389
+ </div>
390
+ <div class="score-box">
391
+ <i class="fas fa-bolt"></i>
392
+ <span>Streak: </span>
393
+ <span class="value" id="streak">0x</span>
394
+ </div>
395
+ </div>
396
+
397
+ <div class="difficulty-selector">
398
+ <button class="difficulty-btn active" data-difficulty="easy">Easy</button>
399
+ <button class="difficulty-btn" data-difficulty="medium">Medium</button>
400
+ <button class="difficulty-btn" data-difficulty="hard">Hard</button>
401
+ </div>
402
+
403
+ <div class="combo-meter">
404
+ <div class="combo-fill" id="combo-fill"></div>
405
+ </div>
406
+ <div class="combo-display" id="combo-display">No combo</div>
407
+
408
+ <div class="timer">Time: <span id="time">30</span>s</div>
409
+
410
+ <div class="game-container" id="game-container">
411
+ <div class="game-over" id="game-over">
412
+ <h2>Game Over!</h2>
413
+ <div class="final-score" id="final-score">Score: 0</div>
414
+ <button class="restart-btn" id="restart-btn">Play Again</button>
415
+ </div>
416
+
417
+ <div class="progress-container">
418
+ <div class="progress-bar" id="progress-bar"></div>
419
+ </div>
420
+
421
+ <div class="ticket-display" id="ticket-display">
422
+ <div class="ticket-badge" id="ticket-badge">Ticket #1</div>
423
+ <div class="ticket-countdown" id="ticket-countdown">5</div>
424
+ <div class="ticket-content" id="ticket-content">
425
+ <p>Hi, I can't seem to log in to my account. I've tried resetting my password but the email never arrives.</p>
426
+ </div>
427
+ <div class="ticket-meta">
428
+ <div class="tags" id="tags">
429
+ <span class="tag critical-tag">Critical</span>
430
+ <span class="tag technical-tag">Technical</span>
431
+ </div>
432
+ <div class="customer" id="customer">
433
+ <i class="fas fa-user"></i> John D.
434
+ </div>
435
+ </div>
436
+ </div>
437
+
438
+ <div class="emoji-feedback" id="emoji-feedback"></div>
439
+ <div class="explanation" id="explanation">Decide whether to route this ticket to a human or AI support agent</div>
440
+
441
+ <div class="actions">
442
+ <button class="action-btn human-btn" id="human-btn">
443
+ <i class="fas fa-user-headset"></i> Human Agent
444
+ </button>
445
+ <button class="action-btn ai-btn" id="ai-btn">
446
+ <i class="fas fa-robot"></i> AI Assistant
447
+ </button>
448
+ </div>
449
+
450
+ <div class="next-ticket">
451
+ <button class="next-btn" id="next-btn" disabled>
452
+ Next Ticket <i class="fas fa-arrow-right"></i>
453
+ </button>
454
+ </div>
455
+ </div>
456
+
457
+ <audio id="correct-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-correct-answer-tone-2870.mp3" preload="auto"></audio>
458
+ <audio id="wrong-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-wrong-answer-fail-notification-946.mp3" preload="auto"></audio>
459
+ <audio id="combo-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-achievement-bell-600.mp3" preload="auto"></audio>
460
+
461
+ <script>
462
+ // Game state
463
+ const state = {
464
+ score: 0,
465
+ streak: 0,
466
+ maxStreak: 0,
467
+ timeLeft: 30,
468
+ gameRunning: true,
469
+ combo: 0,
470
+ difficulty: 'easy',
471
+ ticketsProcessed: 0
472
+ };
473
+
474
+ // Ticket categories and their correct routing
475
+ const ticketTypes = {
476
+ technical: {
477
+ name: "Technical",
478
+ aiSuccessRate: 0.3, // 30% chance AI can handle it
479
+ color: "#3a86ff"
480
+ },
481
+ billing: {
482
+ name: "Billing",
483
+ aiSuccessRate: 0.6,
484
+ color: "#06d6a0"
485
+ },
486
+ feature: {
487
+ name: "Feature Request",
488
+ aiSuccessRate: 0.8,
489
+ color: "#ffd166"
490
+ },
491
+ critical: {
492
+ name: "Critical",
493
+ aiSuccessRate: 0.1,
494
+ color: "#ef476f"
495
+ }
496
+ };
497
+
498
+ // Current ticket
499
+ let currentTicket = null;
500
+ let ticketTimer = null;
501
+ let gameTimer = null;
502
+ let countdownInterval = null;
503
+
504
+ // Elements
505
+ const elements = {
506
+ gameContainer: document.getElementById('game-container'),
507
+ ticketDisplay: document.getElementById('ticket-display'),
508
+ ticketContent: document.getElementById('ticket-content'),
509
+ ticketBadge: document.getElementById('ticket-badge'),
510
+ ticketCountdown: document.getElementById('ticket-countdown'),
511
+ scoreDisplay: document.getElementById('score'),
512
+ streakDisplay: document.getElementById('streak'),
513
+ humanBtn: document.getElementById('human-btn'),
514
+ aiBtn: document.getElementById('ai-btn'),
515
+ nextBtn: document.getElementById('next-btn'),
516
+ explanation: document.getElementById('explanation'),
517
+ emojiFeedback: document.getElementById('emoji-feedback'),
518
+ tagsContainer: document.getElementById('tags'),
519
+ customerDisplay: document.getElementById('customer'),
520
+ gameOverScreen: document.getElementById('game-over'),
521
+ finalScore: document.getElementById('final-score'),
522
+ restartBtn: document.getElementById('restart-btn'),
523
+ progressBar: document.getElementById('progress-bar'),
524
+ timeDisplay: document.getElementById('time'),
525
+ comboFill: document.getElementById('combo-fill'),
526
+ comboDisplay: document.getElementById('combo-display')
527
+ };
528
+
529
+ // Sounds
530
+ const sounds = {
531
+ correct: document.getElementById('correct-sound'),
532
+ wrong: document.getElementById('wrong-sound'),
533
+ combo: document.getElementById('combo-sound')
534
+ };
535
+
536
+ // Utilities
537
+ function randomItem(arr) {
538
+ return arr[Math.floor(Math.random() * arr.length)];
539
+ }
540
+
541
+ function randomBetween(min, max) {
542
+ return Math.floor(Math.random() * (max - min + 1) + min);
543
+ }
544
+
545
+ function shuffleArray(array) {
546
+ const newArray = [...array];
547
+ for (let i = newArray.length - 1; i > 0; i--) {
548
+ const j = Math.floor(Math.random() * (i + 1));
549
+ [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
550
+ }
551
+ return newArray;
552
+ }
553
+
554
+ // Customers
555
+ const customers = [
556
+ "John D.", "Sarah K.", "Mike T.", "Lisa P.", "David M.",
557
+ "Emma R.", "James L.", "Olivia B.", "Robert G.", "Sophia N."
558
+ ];
559
+
560
+ // Ticket templates
561
+ const ticketTemplates = {
562
+ technical: [
563
+ "I can't log in to my account. The password reset email isn't arriving.",
564
+ "The app crashes every time I try to open the settings page.",
565
+ "I'm getting a 404 error when trying to access my dashboard.",
566
+ "The download process gets stuck at 99% and never completes.",
567
+ "After the latest update, all my settings were reset to default."
568
+ ],
569
+ billing: [
570
+ "I was charged twice this month but only received one invoice.",
571
+ "Can you explain the extra $5 charge on my last bill?",
572
+ "I want to upgrade my plan but keep my current payment method.",
573
+ "The system says my credit card expired but it's still valid.",
574
+ "I canceled my subscription last week but was still charged."
575
+ ],
576
+ feature: [
577
+ "I'd love a dark mode option for the mobile app.",
578
+ "Could you add keyboard shortcuts for common actions?",
579
+ "Would it be possible to export reports in CSV format?",
580
+ "I wish there was a way to customize the dashboard layout.",
581
+ "Can you implement a toggle to hide all images for text-only browsing?"
582
+ ],
583
+ critical: [
584
+ "Our entire company account was suddenly deactivated without warning!",
585
+ "All our customer data has disappeared from the system!",
586
+ "We're getting reports from multiple users about unauthorized access.",
587
+ "The payment system is charging all customers double!",
588
+ "A critical security vulnerability was just reported in your API."
589
+ ]
590
+ };
591
+
592
+ // Customer complaints
593
+ const complaints = {
594
+ aiWrong: [
595
+ "The AI gave me completely irrelevant answers!",
596
+ "The bot just sent me in circles without solving anything.",
597
+ "Automated responses didn't address my issue at all.",
598
+ "I wasted 30 minutes with the AI and still need help!",
599
+ "The AI kept misunderstanding my very clear problem."
600
+ ],
601
+ humanWrong: [
602
+ "I waited 2 hours for a human when the AI could have answered!",
603
+ "Why does every simple question need a human response?",
604
+ "A human agent just gave me the same answer as the AI would have.",
605
+ "This was a basic question that didn't need human involvement.",
606
+ "I needed instant help but was stuck in queue unnecessarily."
607
+ ],
608
+ aiSuccess: [
609
+ "The AI solved my problem instantly - great experience!",
610
+ "No waiting, fast answer - exactly what I needed.",
611
+ "Simple problem, simple solution - perfect for AI.",
612
+ "The bot understood my question immediately and helped.",
613
+ "Quick response that actually fixed my issue - very efficient."
614
+ ],
615
+ humanSuccess: [
616
+ "The human agent was patient and solved my complex problem.",
617
+ "I really appreciated the personal touch for this sensitive issue.",
618
+ "After the AI didn't help, the human fixed everything quickly.",
619
+ "The agent took time to understand all the nuances of my case.",
620
+ "For this level of service, waiting was definitely worth it."
621
+ ]
622
+ };
623
+
624
+ // Timer logic
625
+ function startGameTimer() {
626
+ elements.timeDisplay.textContent = state.timeLeft;
627
+ gameTimer = setInterval(() => {
628
+ state.timeLeft--;
629
+ elements.timeDisplay.textContent = state.timeLeft;
630
+ elements.progressBar.style.width = `${(state.timeLeft / 30) * 100}%`;
631
+
632
+ if (state.timeLeft <= 0) {
633
+ endGame();
634
+ }
635
+ }, 1000);
636
+ }
637
+
638
+ // Ticket countdown
639
+ function startTicketTimer() {
640
+ let secondsLeft = getTicketTimeLimit();
641
+ elements.ticketCountdown.textContent = secondsLeft;
642
+
643
+ if (countdownInterval) clearInterval(countdownInterval);
644
+
645
+ countdownInterval = setInterval(() => {
646
+ secondsLeft--;
647
+ elements.ticketCountdown.textContent = secondsLeft;
648
+
649
+ if (secondsLeft <= 0) {
650
+ clearInterval(countdownInterval);
651
+ handleTimeout();
652
+ }
653
+ }, 1000);
654
+ }
655
+
656
+ function getTicketTimeLimit() {
657
+ switch (state.difficulty) {
658
+ case 'easy': return 7;
659
+ case 'medium': return 5;
660
+ case 'hard': return 3;
661
+ default: return 5;
662
+ }
663
+ }
664
+
665
+ function handleTimeout() {
666
+ state.streak = 0;
667
+ updateStreakDisplay();
668
+ resetCombo();
669
+
670
+ elements.emojiFeedback.textContent = "😴";
671
+ elements.explanation.textContent = "Too slow! Customer was frustrated by the long wait.";
672
+ sounds.wrong.play();
673
+
674
+ elements.humanBtn.disabled = true;
675
+ elements.aiBtn.disabled = true;
676
+ elements.nextBtn.disabled = false;
677
+ }
678
+
679
+ // Ticket generation
680
+ function generateRandomTicket() {
681
+ state.ticketsProcessed++;
682
+ clearInterval(countdownInterval);
683
+
684
+ // Determine which ticket types to include based on difficulty
685
+ let availableTypes = Object.keys(ticketTypes);
686
+
687
+ if (state.difficulty === 'easy') {
688
+ // Remove critical tickets in easy mode
689
+ availableTypes = availableTypes.filter(type => type !== 'critical');
690
+ }
691
+
692
+ const typeKey = randomItem(availableTypes);
693
+ const type = ticketTypes[typeKey];
694
+ const templates = ticketTemplates[typeKey];
695
+
696
+ // Select random content
697
+ const content = randomItem(templates);
698
+ const customer = randomItem(customers);
699
+
700
+ // Create list of tags (always includes the main type)
701
+ const tags = [typeKey];
702
+
703
+ // Add a second tag 50% of the time in medium/hard modes
704
+ if (Math.random() > 0.5 && state.difficulty !== 'easy') {
705
+ const otherTypes = availableTypes.filter(t => t !== typeKey);
706
+ if (otherTypes.length > 0) {
707
+ tags.push(randomItem(otherTypes));
708
+ }
709
+ }
710
+
711
+ // Create ticket object
712
+ currentTicket = {
713
+ id: state.ticketsProcessed,
714
+ type: typeKey,
715
+ content: content,
716
+ customer: customer,
717
+ tags: shuffleArray(tags),
718
+ correctChoice: Math.random() < type.aiSuccessRate ? 'ai' : 'human'
719
+ };
720
+
721
+ // Update UI
722
+ renderTicket(currentTicket);
723
+ startTicketTimer();
724
+
725
+ // Reset buttons
726
+ elements.humanBtn.disabled = false;
727
+ elements.aiBtn.disabled = false;
728
+ elements.nextBtn.disabled = true;
729
+
730
+ // Clear feedback
731
+ elements.emojiFeedback.textContent = "";
732
+ elements.explanation.textContent = "Decide whether to route this ticket to a human or AI support agent";
733
+ }
734
+
735
+ function renderTicket(ticket) {
736
+ elements.ticketBadge.textContent = `Ticket #${ticket.id}`;
737
+ elements.ticketContent.innerHTML = `<p>${ticket.content}</p>`;
738
+ elements.customerDisplay.innerHTML = `<i class="fas fa-user"></i> ${ticket.customer}`;
739
+
740
+ // Clear existing tags
741
+ elements.tagsContainer.innerHTML = '';
742
+
743
+ // Add new tags
744
+ ticket.tags.forEach(tag => {
745
+ const span = document.createElement('span');
746
+ span.className = `tag ${tag}-tag`;
747
+ span.textContent = ticketTypes[tag].name;
748
+ span.style.backgroundColor = ticketTypes[tag].color;
749
+ elements.tagsContainer.appendChild(span);
750
+ });
751
+ }
752
+
753
+ // Game actions
754
+ function routeToHuman() {
755
+ clearInterval(countdownInterval);
756
+ evaluateChoice('human');
757
+ }
758
+
759
+ function routeToAI() {
760
+ clearInterval(countdownInterval);
761
+ evaluateChoice('ai');
762
+ }
763
+
764
+ function evaluateChoice(choice) {
765
+ elements.humanBtn.disabled = true;
766
+ elements.aiBtn.disabled = true;
767
+ elements.nextBtn.disabled = false;
768
+
769
+ const wasCorrect = choice === currentTicket.correctChoice;
770
+
771
+ if (wasCorrect) {
772
+ handleCorrectChoice();
773
+ } else {
774
+ handleWrongChoice(choice);
775
+ }
776
+
777
+ // Show feedback
778
+ const feedback = generateFeedback(choice, wasCorrect);
779
+ elements.emojiFeedback.textContent = feedback.emoji;
780
+ elements.explanation.textContent = feedback.text;
781
+
782
+ // Update combo
783
+ if (wasCorrect) {
784
+ incrementCombo();
785
+ } else {
786
+ resetCombo();
787
+ }
788
+
789
+ // Update streak
790
+ if (wasCorrect) {
791
+ state.streak++;
792
+ if (state.streak > state.maxStreak) {
793
+ state.maxStreak = state.streak;
794
+ }
795
+ } else {
796
+ state.streak = 0;
797
+ }
798
+
799
+ updateStreakDisplay();
800
+
801
+ // Add floating points for correct answer
802
+ if (wasCorrect) {
803
+ addFloatingPoints();
804
+ }
805
+ }
806
+
807
+ function handleCorrectChoice() {
808
+ let pointsEarned = 100;
809
+
810
+ // Add streak bonus
811
+ if (state.streak > 0) {
812
+ pointsEarned += state.streak * 10;
813
+ }
814
+
815
+ // Add combo bonus
816
+ if (state.combo > 2) {
817
+ pointsEarned += Math.pow(state.combo, 2) * 5;
818
+ }
819
+
820
+ // Difficulty bonus
821
+ if (state.difficulty === 'hard') pointsEarned *= 1.5;
822
+ else if (state.difficulty === 'medium') pointsEarned *= 1.2;
823
+
824
+ pointsEarned = Math.round(pointsEarned);
825
+ state.score += pointsEarned;
826
+
827
+ updateScoreDisplay();
828
+ sounds.correct.play();
829
+ }
830
+
831
+ function handleWrongChoice(choice) {
832
+ if (choice === 'ai' && currentTicket.correctChoice === 'human') {
833
+ sounds.wrong.play();
834
+ } else if (choice === 'human' && currentTicket.correctChoice === 'ai') {
835
+ sounds.wrong.play();
836
+ }
837
+ }
838
+
839
+ function generateFeedback(choice, wasCorrect) {
840
+ const ticketType = currentTicket.type;
841
+
842
+ if (wasCorrect) {
843
+ if (choice === 'ai') {
844
+ const msg = randomItem(complaints.aiSuccess);
845
+ return { emoji: "πŸ€–βœ…", text: `Correct! AI handled this ${ticketType} issue well: "${msg}"` };
846
+ } else {
847
+ const msg = randomItem(complaints.humanSuccess);
848
+ return { emoji: "πŸ‘©β€πŸ’Όβœ…", text: `Correct! Human was right for this ${ticketType} issue: "${msg}"` };
849
+ }
850
+ } else {
851
+ if (choice === 'ai') {
852
+ const msg = randomItem(complaints.aiWrong);
853
+ return { emoji: "πŸ€–βŒ", text: `Wrong! AI failed this ${ticketType} issue: "${msg}"` };
854
+ } else {
855
+ const msg = randomItem(complaints.humanWrong);
856
+ return { emoji: "πŸ‘©β€πŸ’ΌβŒ", text: `Wrong! Human was wrong for this ${ticketType} issue: "${msg}"` };
857
+ }
858
+ }
859
+ }
860
+
861
+ // Combo system
862
+ function incrementCombo() {
863
+ state.combo++;
864
+ updateComboDisplay();
865
+
866
+ // Play combo sound every 3 correct answers
867
+ if (state.combo >= 3 && state.combo % 3 === 0) {
868
+ sounds.combo.play();
869
+ }
870
+ }
871
+
872
+ function resetCombo() {
873
+ state.combo = 0;
874
+ updateComboDisplay();
875
+ }
876
+
877
+ function updateComboDisplay() {
878
+ const percent = Math.min(100, (state.combo / 10) * 100);
879
+ elements.comboFill.style.width = `${percent}%`;
880
+
881
+ if (state.combo === 0) {
882
+ elements.comboDisplay.textContent = "No combo";
883
+ elements.comboDisplay.style.color = "#6c757d";
884
+ } else if (state.combo < 3) {
885
+ elements.comboDisplay.textContent = `${state.combo}x combo`;
886
+ elements.comboDisplay.style.color = "#6c757d";
887
+ } else if (state.combo < 5) {
888
+ elements.comboDisplay.textContent = `${state.combo}x combo!`;
889
+ elements.comboDisplay.style.color = "#ffd166";
890
+ } else {
891
+ elements.comboDisplay.textContent = `${state.combo}x COMBO!! πŸ”₯`;
892
+ elements.comboDisplay.style.color = "#ef476f";
893
+ }
894
+ }
895
+
896
+ // Score display
897
+ function updateScoreDisplay() {
898
+ elements.scoreDisplay.textContent = state.score;
899
+ elements.scoreDisplay.classList.add('highlight');
900
+ setTimeout(() => {
901
+ elements.scoreDisplay.classList.remove('highlight');
902
+ }, 1000);
903
+ }
904
+
905
+ function updateStreakDisplay() {
906
+ elements.streakDisplay.textContent = `${state.streak > 0 ? state.streak : 0}x`;
907
+
908
+ // Add visual effect for streaks
909
+ if (state.streak >= 5) {
910
+ elements.streakDisplay.style.color = "#ffd166";
911
+ } else if (state.streak >= 3) {
912
+ elements.streakDisplay.style.color = "#06d6a0";
913
+ } else {
914
+ elements.streakDisplay.style.color = "#3a86ff";
915
+ }
916
+ }
917
+
918
+ function addFloatingPoints() {
919
+ let points = 100;
920
+ if (state.streak > 0) points += state.streak * 10;
921
+ if (state.combo > 2) points += Math.pow(state.combo, 2) * 5;
922
+
923
+ if (state.difficulty === 'hard') points *= 1.5;
924
+ else if (state.difficulty === 'medium') points *= 1.2;
925
+
926
+ points = Math.round(points);
927
+
928
+ const floating = document.createElement('div');
929
+ floating.className = 'floating-points';
930
+ floating.textContent = `+${points}`;
931
+
932
+ // Position near the score display
933
+ floating.style.left = `${elements.scoreDisplay.getBoundingClientRect().left - 30}px`;
934
+ floating.style.top = `${elements.scoreDisplay.getBoundingClientRect().top}px`;
935
+
936
+ document.body.appendChild(floating);
937
+
938
+ // Remove after animation
939
+ setTimeout(() => {
940
+ floating.remove();
941
+ }, 1000);
942
+ }
943
+
944
+ // Game flow
945
+ function startGame() {
946
+ state.score = 0;
947
+ state.streak = 0;
948
+ state.maxStreak = 0;
949
+ state.timeLeft = 30;
950
+ state.gameRunning = true;
951
+ state.combo = 0;
952
+ state.ticketsProcessed = 0;
953
+
954
+ updateScoreDisplay();
955
+ updateStreakDisplay();
956
+ updateComboDisplay();
957
+
958
+ elements.gameOverScreen.classList.remove('show');
959
+ elements.progressBar.style.width = "100%";
960
+
961
+ startGameTimer();
962
+ generateRandomTicket();
963
+ }
964
+
965
+ function endGame() {
966
+ clearInterval(gameTimer);
967
+ clearInterval(countdownInterval);
968
+ state.gameRunning = false;
969
+
970
+ elements.finalScore.textContent = `Final Score: ${state.score} (Max Streak: ${state.maxStreak}x)`;
971
+ elements.gameOverScreen.classList.add('show');
972
+ }
973
+
974
+ // Event listeners
975
+ elements.humanBtn.addEventListener('click', routeToHuman);
976
+ elements.aiBtn.addEventListener('click', routeToAI);
977
+ elements.nextBtn.addEventListener('click', generateRandomTicket);
978
+ elements.restartBtn.addEventListener('click', startGame);
979
+
980
+ document.querySelectorAll('.difficulty-btn').forEach(btn => {
981
+ btn.addEventListener('click', function() {
982
+ document.querySelectorAll('.difficulty-btn').forEach(b => b.classList.remove('active'));
983
+ this.classList.add('active');
984
+ state.difficulty = this.dataset.difficulty;
985
+ });
986
+ });
987
+
988
+ // Start the game
989
+ startGame();
990
+ </script>
991
+ <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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
992
+ </html>