bug-report-js 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,996 @@
1
+ <!DOCTYPE html>
2
+ <html lang="de">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>NeonStore — Demo Shop | Bug Report Widget v2</title>
7
+ <meta name="description" content="Demo-Shop zur Veranschaulichung des Bug Report Widget v2 — mit annotiertem Screenshot, Ist/Soll-Beschreibung und HTML-Export.">
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
11
+ <style>
12
+ /* ═══════════════════════════════════════════════════════════════
13
+ NeonStore — Demo E-Commerce Shop Styles
14
+ ═══════════════════════════════════════════════════════════════ */
15
+
16
+ :root {
17
+ --bg: #0a0b10;
18
+ --bg-elevated: #12131a;
19
+ --bg-card: #181922;
20
+ --bg-card-hover: #1e2030;
21
+ --bg-input: #0f1017;
22
+ --border: #252736;
23
+ --border-hover: #3d4060;
24
+ --text: #eaecf4;
25
+ --text-secondary: #8b8fa4;
26
+ --text-muted: #555770;
27
+ --accent: #818cf8;
28
+ --accent-hover: #6366f1;
29
+ --accent-glow: rgba(129, 140, 248, 0.15);
30
+ --accent-strong: rgba(129, 140, 248, 0.25);
31
+ --success: #34d399;
32
+ --success-bg: rgba(52, 211, 153, 0.08);
33
+ --danger: #f87171;
34
+ --danger-bg: rgba(248, 113, 113, 0.08);
35
+ --warning: #fbbf24;
36
+ --warning-bg: rgba(251, 191, 36, 0.08);
37
+ --pink: #f472b6;
38
+ --cyan: #22d3ee;
39
+ --radius: 14px;
40
+ --radius-sm: 10px;
41
+ --radius-xs: 6px;
42
+ --shadow-sm: 0 2px 8px rgba(0,0,0,0.2);
43
+ --shadow-md: 0 8px 32px rgba(0,0,0,0.3);
44
+ --shadow-glow: 0 0 24px var(--accent-glow);
45
+ --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
46
+ --transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
47
+ }
48
+
49
+ *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
50
+
51
+ body {
52
+ font-family: var(--font);
53
+ background: var(--bg);
54
+ color: var(--text);
55
+ line-height: 1.6;
56
+ -webkit-font-smoothing: antialiased;
57
+ min-height: 100vh;
58
+ }
59
+
60
+ /* ── Navbar ─────────────────────────────────────────────────── */
61
+
62
+ .navbar {
63
+ position: sticky; top: 0; z-index: 100;
64
+ display: flex; align-items: center; gap: 16px;
65
+ padding: 0 28px; height: 64px;
66
+ background: rgba(10, 11, 16, 0.85);
67
+ backdrop-filter: blur(16px) saturate(1.6);
68
+ -webkit-backdrop-filter: blur(16px) saturate(1.6);
69
+ border-bottom: 1px solid var(--border);
70
+ }
71
+
72
+ .nav-logo {
73
+ font-size: 18px; font-weight: 800; letter-spacing: -0.04em;
74
+ color: var(--text); text-decoration: none;
75
+ display: flex; align-items: center; gap: 8px;
76
+ }
77
+
78
+ .nav-logo-icon {
79
+ width: 28px; height: 28px; border-radius: 8px;
80
+ background: linear-gradient(135deg, var(--accent), var(--pink));
81
+ display: flex; align-items: center; justify-content: center;
82
+ font-size: 14px; color: #fff;
83
+ }
84
+
85
+ .nav-search {
86
+ flex: 1; max-width: 400px; position: relative; margin: 0 16px;
87
+ }
88
+
89
+ .nav-search input {
90
+ width: 100%; padding: 9px 14px 9px 36px;
91
+ background: var(--bg-elevated); color: var(--text);
92
+ border: 1px solid var(--border); border-radius: 10px;
93
+ font-size: 13px; font-family: var(--font);
94
+ transition: border-color var(--transition);
95
+ }
96
+
97
+ .nav-search input:focus { outline: none; border-color: var(--accent); }
98
+
99
+ .nav-search::before {
100
+ content: '🔍'; position: absolute; left: 12px; top: 50%;
101
+ transform: translateY(-50%); font-size: 13px; pointer-events: none;
102
+ }
103
+
104
+ .nav-links {
105
+ display: flex; align-items: center; gap: 4px; margin-left: auto;
106
+ }
107
+
108
+ .nav-link {
109
+ padding: 8px 14px; border-radius: 8px;
110
+ font-size: 13px; font-weight: 500; color: var(--text-secondary);
111
+ text-decoration: none; transition: all var(--transition);
112
+ cursor: pointer; border: none; background: none; font-family: var(--font);
113
+ }
114
+
115
+ .nav-link:hover { color: var(--text); background: var(--bg-card); }
116
+
117
+ .nav-cart {
118
+ position: relative; display: flex; align-items: center; gap: 6px;
119
+ padding: 8px 14px; border-radius: 10px;
120
+ background: var(--accent-glow); border: 1px solid rgba(129,140,248,0.2);
121
+ color: var(--accent); font-size: 13px; font-weight: 600;
122
+ cursor: pointer; transition: all var(--transition);
123
+ font-family: var(--font);
124
+ }
125
+
126
+ .nav-cart:hover {
127
+ background: var(--accent-strong);
128
+ border-color: var(--accent);
129
+ box-shadow: var(--shadow-glow);
130
+ }
131
+
132
+ .cart-badge {
133
+ position: absolute; top: -4px; right: -4px;
134
+ width: 18px; height: 18px; border-radius: 50%;
135
+ background: var(--danger); color: #fff;
136
+ font-size: 10px; font-weight: 700;
137
+ display: flex; align-items: center; justify-content: center;
138
+ border: 2px solid var(--bg);
139
+ }
140
+
141
+ /* ── Banner ─────────────────────────────────────────────────── */
142
+
143
+ .promo-banner {
144
+ background: linear-gradient(135deg, rgba(129,140,248,0.08) 0%, rgba(244,114,182,0.08) 100%);
145
+ border-bottom: 1px solid var(--border);
146
+ padding: 14px 28px;
147
+ display: flex; align-items: center; justify-content: center; gap: 10px;
148
+ font-size: 13px; color: var(--text-secondary);
149
+ }
150
+
151
+ .promo-banner strong { color: var(--accent); }
152
+
153
+ .promo-badge {
154
+ display: inline-flex; padding: 2px 8px; border-radius: 4px;
155
+ background: var(--danger-bg); color: var(--danger);
156
+ font-size: 10px; font-weight: 700; letter-spacing: 0.04em;
157
+ text-transform: uppercase;
158
+ }
159
+
160
+ /* ── Category Nav ──────────────────────────────────────────── */
161
+
162
+ .category-nav {
163
+ display: flex; gap: 6px; padding: 16px 28px;
164
+ overflow-x: auto; border-bottom: 1px solid var(--border);
165
+ }
166
+
167
+ .category-nav::-webkit-scrollbar { display: none; }
168
+
169
+ .cat-pill {
170
+ padding: 7px 16px; border-radius: 100px;
171
+ font-size: 12.5px; font-weight: 500; white-space: nowrap;
172
+ background: var(--bg-elevated); color: var(--text-secondary);
173
+ border: 1px solid var(--border); cursor: pointer;
174
+ transition: all var(--transition); font-family: var(--font);
175
+ }
176
+
177
+ .cat-pill:hover { border-color: var(--accent); color: var(--text); }
178
+
179
+ .cat-pill.active {
180
+ background: var(--accent-glow); color: var(--accent);
181
+ border-color: rgba(129,140,248,0.3);
182
+ }
183
+
184
+ /* ── Main Layout ───────────────────────────────────────────── */
185
+
186
+ .main { max-width: 1200px; margin: 0 auto; padding: 28px; }
187
+
188
+ .page-title {
189
+ font-size: 22px; font-weight: 800; letter-spacing: -0.03em;
190
+ margin-bottom: 6px;
191
+ }
192
+
193
+ .page-subtitle {
194
+ font-size: 14px; color: var(--text-muted); margin-bottom: 28px;
195
+ }
196
+
197
+ /* ── Product Grid ──────────────────────────────────────────── */
198
+
199
+ .product-grid {
200
+ display: grid;
201
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
202
+ gap: 18px; margin-bottom: 48px;
203
+ }
204
+
205
+ .product-card {
206
+ background: var(--bg-card);
207
+ border: 1px solid var(--border);
208
+ border-radius: var(--radius);
209
+ overflow: hidden;
210
+ transition: all var(--transition);
211
+ cursor: pointer;
212
+ position: relative;
213
+ }
214
+
215
+ .product-card:hover {
216
+ border-color: var(--border-hover);
217
+ transform: translateY(-3px);
218
+ box-shadow: var(--shadow-md);
219
+ }
220
+
221
+ .product-img {
222
+ width: 100%; height: 200px;
223
+ object-fit: cover; display: block;
224
+ }
225
+
226
+ .product-img-placeholder {
227
+ width: 100%; height: 200px;
228
+ display: flex; align-items: center; justify-content: center;
229
+ font-size: 48px;
230
+ background: linear-gradient(135deg, var(--bg-elevated), var(--bg-card));
231
+ }
232
+
233
+ .product-badge {
234
+ position: absolute; top: 12px; left: 12px;
235
+ padding: 3px 10px; border-radius: 6px;
236
+ font-size: 10px; font-weight: 700;
237
+ text-transform: uppercase; letter-spacing: 0.04em;
238
+ }
239
+
240
+ .badge-new { background: var(--success-bg); color: var(--success); border: 1px solid rgba(52,211,153,0.2); }
241
+ .badge-sale { background: var(--danger-bg); color: var(--danger); border: 1px solid rgba(248,113,113,0.2); }
242
+ .badge-hot { background: var(--warning-bg); color: var(--warning); border: 1px solid rgba(251,191,36,0.2); }
243
+
244
+ .product-body { padding: 16px; }
245
+
246
+ .product-category {
247
+ font-size: 10.5px; color: var(--text-muted); text-transform: uppercase;
248
+ letter-spacing: 0.06em; font-weight: 600; margin-bottom: 4px;
249
+ }
250
+
251
+ .product-name {
252
+ font-size: 15px; font-weight: 700; margin-bottom: 6px;
253
+ letter-spacing: -0.01em;
254
+ }
255
+
256
+ .product-desc {
257
+ font-size: 12.5px; color: var(--text-secondary); margin-bottom: 12px;
258
+ line-height: 1.5;
259
+ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
260
+ overflow: hidden;
261
+ }
262
+
263
+ .product-footer {
264
+ display: flex; align-items: center; justify-content: space-between;
265
+ }
266
+
267
+ .product-price {
268
+ font-size: 18px; font-weight: 800; letter-spacing: -0.02em;
269
+ color: var(--text);
270
+ }
271
+
272
+ .product-price-old {
273
+ font-size: 13px; color: var(--text-muted);
274
+ text-decoration: line-through; margin-left: 6px; font-weight: 400;
275
+ }
276
+
277
+ .btn-add-cart {
278
+ padding: 8px 16px; border-radius: 8px; border: none;
279
+ background: var(--accent); color: #fff;
280
+ font-size: 12px; font-weight: 600; cursor: pointer;
281
+ font-family: var(--font); transition: all var(--transition);
282
+ display: flex; align-items: center; gap: 5px;
283
+ }
284
+
285
+ .btn-add-cart:hover {
286
+ background: var(--accent-hover);
287
+ box-shadow: 0 4px 16px var(--accent-glow);
288
+ transform: translateY(-1px);
289
+ }
290
+
291
+ /* ── Rating Stars ──────────────────────────────────────────── */
292
+
293
+ .rating {
294
+ display: flex; align-items: center; gap: 4px;
295
+ margin-bottom: 10px;
296
+ }
297
+
298
+ .rating-stars { font-size: 12px; letter-spacing: 1px; }
299
+ .rating-count { font-size: 11px; color: var(--text-muted); }
300
+
301
+ /* ── Features Section ──────────────────────────────────────── */
302
+
303
+ .features-section {
304
+ padding: 48px 0 0;
305
+ border-top: 1px solid var(--border);
306
+ margin-top: 24px;
307
+ }
308
+
309
+ .features-title {
310
+ font-size: 18px; font-weight: 700; letter-spacing: -0.02em;
311
+ margin-bottom: 6px; display: flex; align-items: center; gap: 8px;
312
+ }
313
+
314
+ .features-subtitle {
315
+ font-size: 13px; color: var(--text-muted); margin-bottom: 24px;
316
+ }
317
+
318
+ .features-grid {
319
+ display: grid;
320
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
321
+ gap: 14px; margin-bottom: 48px;
322
+ }
323
+
324
+ .feature-card {
325
+ background: var(--bg-card); border: 1px solid var(--border);
326
+ border-radius: var(--radius-sm); padding: 18px;
327
+ transition: all var(--transition);
328
+ }
329
+
330
+ .feature-card:hover { border-color: var(--border-hover); }
331
+
332
+ .feature-icon { font-size: 22px; margin-bottom: 10px; }
333
+
334
+ .feature-name {
335
+ font-size: 13px; font-weight: 700; margin-bottom: 4px;
336
+ }
337
+
338
+ .feature-desc {
339
+ font-size: 12px; color: var(--text-muted); line-height: 1.5;
340
+ }
341
+
342
+ /* ── Newsletter Section ─────────────────────────────────────── */
343
+
344
+ .newsletter-section {
345
+ background: linear-gradient(135deg, rgba(129,140,248,0.06), rgba(34,211,238,0.06));
346
+ border: 1px solid var(--border);
347
+ border-radius: var(--radius);
348
+ padding: 32px;
349
+ text-align: center;
350
+ margin-bottom: 48px;
351
+ }
352
+
353
+ .newsletter-title {
354
+ font-size: 18px; font-weight: 700; margin-bottom: 6px;
355
+ }
356
+
357
+ .newsletter-desc {
358
+ font-size: 13px; color: var(--text-secondary); margin-bottom: 18px;
359
+ }
360
+
361
+ .newsletter-form {
362
+ display: flex; gap: 8px; max-width: 400px; margin: 0 auto;
363
+ }
364
+
365
+ .newsletter-form input {
366
+ flex: 1; padding: 10px 14px;
367
+ background: var(--bg-input); color: var(--text);
368
+ border: 1px solid var(--border); border-radius: 10px;
369
+ font-size: 13px; font-family: var(--font);
370
+ transition: border-color var(--transition);
371
+ }
372
+
373
+ .newsletter-form input:focus { outline: none; border-color: var(--accent); }
374
+
375
+ .newsletter-form button {
376
+ padding: 10px 20px; border: none; border-radius: 10px;
377
+ background: var(--accent); color: #fff;
378
+ font-size: 13px; font-weight: 600; cursor: pointer;
379
+ font-family: var(--font); transition: all var(--transition);
380
+ white-space: nowrap;
381
+ }
382
+
383
+ .newsletter-form button:hover { background: var(--accent-hover); }
384
+
385
+ /* ── Cart Drawer ───────────────────────────────────────────── */
386
+
387
+ .cart-overlay {
388
+ position: fixed; inset: 0; background: rgba(0,0,0,0.5);
389
+ z-index: 200; opacity: 0; pointer-events: none;
390
+ transition: opacity 0.3s ease;
391
+ }
392
+
393
+ .cart-overlay.open { opacity: 1; pointer-events: auto; }
394
+
395
+ .cart-drawer {
396
+ position: fixed; top: 0; right: -420px; bottom: 0;
397
+ width: 400px; max-width: 90vw;
398
+ background: var(--bg-elevated);
399
+ border-left: 1px solid var(--border);
400
+ z-index: 201; padding: 24px;
401
+ transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);
402
+ display: flex; flex-direction: column;
403
+ box-shadow: -8px 0 40px rgba(0,0,0,0.4);
404
+ }
405
+
406
+ .cart-overlay.open + .cart-drawer,
407
+ .cart-drawer.open { right: 0; }
408
+
409
+ .cart-header {
410
+ display: flex; align-items: center; justify-content: space-between;
411
+ padding-bottom: 16px; border-bottom: 1px solid var(--border);
412
+ margin-bottom: 16px;
413
+ }
414
+
415
+ .cart-title { font-size: 17px; font-weight: 700; }
416
+
417
+ .cart-close {
418
+ width: 32px; height: 32px; border-radius: 8px;
419
+ background: var(--bg-card); border: 1px solid var(--border);
420
+ color: var(--text-secondary); cursor: pointer;
421
+ display: flex; align-items: center; justify-content: center;
422
+ font-size: 16px; transition: all var(--transition);
423
+ font-family: var(--font);
424
+ }
425
+
426
+ .cart-close:hover { border-color: var(--danger); color: var(--danger); }
427
+
428
+ .cart-items { flex: 1; overflow-y: auto; }
429
+
430
+ .cart-item {
431
+ display: flex; align-items: center; gap: 12px;
432
+ padding: 12px 0; border-bottom: 1px solid var(--border);
433
+ }
434
+
435
+ .cart-item-emoji {
436
+ width: 48px; height: 48px; border-radius: 10px;
437
+ background: var(--bg-card); display: flex;
438
+ align-items: center; justify-content: center;
439
+ font-size: 24px; flex-shrink: 0;
440
+ }
441
+
442
+ .cart-item-info { flex: 1; }
443
+
444
+ .cart-item-name { font-size: 13px; font-weight: 600; }
445
+
446
+ .cart-item-price {
447
+ font-size: 14px; font-weight: 700; color: var(--accent);
448
+ }
449
+
450
+ .cart-item-remove {
451
+ padding: 4px 10px; border-radius: 6px;
452
+ background: var(--danger-bg); border: 1px solid rgba(248,113,113,0.2);
453
+ color: var(--danger); font-size: 11px; cursor: pointer;
454
+ font-family: var(--font); transition: all var(--transition);
455
+ }
456
+
457
+ .cart-item-remove:hover { background: rgba(248,113,113,0.15); }
458
+
459
+ .cart-empty {
460
+ flex: 1; display: flex; flex-direction: column;
461
+ align-items: center; justify-content: center; gap: 8px;
462
+ color: var(--text-muted); font-size: 14px;
463
+ }
464
+
465
+ .cart-empty-icon { font-size: 40px; opacity: 0.5; }
466
+
467
+ .cart-footer {
468
+ padding-top: 16px; border-top: 1px solid var(--border);
469
+ margin-top: 16px;
470
+ }
471
+
472
+ .cart-total {
473
+ display: flex; justify-content: space-between;
474
+ font-size: 16px; font-weight: 700; margin-bottom: 14px;
475
+ }
476
+
477
+ .cart-total-price { color: var(--accent); }
478
+
479
+ .btn-checkout {
480
+ width: 100%; padding: 13px;
481
+ background: linear-gradient(135deg, var(--accent), var(--pink));
482
+ color: #fff; border: none; border-radius: 12px;
483
+ font-size: 14px; font-weight: 700; cursor: pointer;
484
+ font-family: var(--font); transition: all var(--transition);
485
+ box-shadow: 0 4px 20px var(--accent-glow);
486
+ }
487
+
488
+ .btn-checkout:hover {
489
+ transform: translateY(-2px);
490
+ box-shadow: 0 8px 32px var(--accent-strong);
491
+ }
492
+
493
+ /* ── Toast ──────────────────────────────────────────────────── */
494
+
495
+ .toast {
496
+ position: fixed; bottom: 90px; left: 50%;
497
+ transform: translateX(-50%) translateY(100px);
498
+ background: var(--bg-card); color: var(--text);
499
+ border: 1px solid var(--border); border-radius: 12px;
500
+ padding: 12px 20px; font-size: 13px; font-weight: 500;
501
+ box-shadow: var(--shadow-md);
502
+ z-index: 300; opacity: 0; pointer-events: none;
503
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
504
+ display: flex; align-items: center; gap: 8px;
505
+ }
506
+
507
+ .toast.show {
508
+ opacity: 1; pointer-events: auto;
509
+ transform: translateX(-50%) translateY(0);
510
+ }
511
+
512
+ /* ── Footer ─────────────────────────────────────────────────── */
513
+
514
+ .site-footer {
515
+ border-top: 1px solid var(--border);
516
+ padding: 32px 28px;
517
+ display: flex; flex-wrap: wrap; gap: 48px;
518
+ max-width: 1200px; margin: 0 auto;
519
+ }
520
+
521
+ .footer-col { flex: 1; min-width: 160px; }
522
+
523
+ .footer-col h4 {
524
+ font-size: 12px; font-weight: 700; text-transform: uppercase;
525
+ letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 12px;
526
+ }
527
+
528
+ .footer-col a {
529
+ display: block; font-size: 13px; color: var(--text-secondary);
530
+ text-decoration: none; padding: 3px 0;
531
+ transition: color var(--transition); cursor: pointer;
532
+ }
533
+
534
+ .footer-col a:hover { color: var(--accent); }
535
+
536
+ .footer-bottom {
537
+ text-align: center; padding: 20px 28px;
538
+ border-top: 1px solid var(--border);
539
+ font-size: 12px; color: var(--text-muted);
540
+ }
541
+
542
+ .footer-bottom a { color: var(--accent); text-decoration: none; }
543
+ .footer-bottom a:hover { text-decoration: underline; }
544
+
545
+ /* ── Widget Hint ────────────────────────────────────────────── */
546
+
547
+ /* Removed .widget-hint classes as it's now native to the widget */
548
+
549
+ @keyframes hintPulse {
550
+ 0%, 100% { box-shadow: 0 8px 32px rgba(0,0,0,0.4); }
551
+ 50% { box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 20px var(--accent-glow); }
552
+ }
553
+
554
+ @keyframes hintFadeIn {
555
+ from { opacity: 0; transform: translateY(8px); }
556
+ to { opacity: 1; transform: translateY(0); }
557
+ }
558
+
559
+ /* ── Responsive ─────────────────────────────────────────────── */
560
+
561
+ @media (max-width: 768px) {
562
+ .navbar { padding: 0 16px; }
563
+ .nav-search { display: none; }
564
+ .main { padding: 20px 16px; }
565
+ .product-grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
566
+ .site-footer { padding: 24px 16px; gap: 24px; }
567
+ .newsletter-form { flex-direction: column; }
568
+ }
569
+
570
+ @media (max-width: 480px) {
571
+ .product-grid { grid-template-columns: 1fr; }
572
+ .user-desc { grid-template-columns: 1fr; }
573
+ }
574
+ </style>
575
+ </head>
576
+ <body>
577
+
578
+ <!-- Navbar -->
579
+ <nav class="navbar">
580
+ <a href="#" class="nav-logo">
581
+ <div class="nav-logo-icon">N</div>
582
+ NeonStore
583
+ </a>
584
+ <div class="nav-search">
585
+ <input type="text" placeholder="Produkte suchen…" id="searchInput">
586
+ </div>
587
+ <div class="nav-links">
588
+ <button class="nav-link" id="navNew" onclick="filterCategory('Neu')">Neu</button>
589
+ <button class="nav-link" id="navSale" onclick="filterCategory('Sale')">Sale</button>
590
+ <button class="nav-link" id="navAll" onclick="filterCategory('all')">Alle</button>
591
+ </div>
592
+ <button class="nav-cart" id="cartToggle" onclick="toggleCart()">
593
+ 🛒 Warenkorb
594
+ <span class="cart-badge" id="cartBadge">0</span>
595
+ </button>
596
+ </nav>
597
+
598
+ <!-- Promo Banner -->
599
+ <div class="promo-banner">
600
+ <span class="promo-badge">Sale</span>
601
+ <span><strong>Sommer-Rabatt:</strong> Bis zu 40% auf ausgewählte Produkte — nur dieses Wochenende!</span>
602
+ </div>
603
+
604
+ <!-- Category Pills -->
605
+ <div class="category-nav" id="categoryNav">
606
+ <button class="cat-pill active" onclick="filterCategory('all')">Alle Produkte</button>
607
+ <button class="cat-pill" onclick="filterCategory('Audio')">🎧 Audio</button>
608
+ <button class="cat-pill" onclick="filterCategory('Wearables')">⌚ Wearables</button>
609
+ <button class="cat-pill" onclick="filterCategory('Zubehör')">🔌 Zubehör</button>
610
+ <button class="cat-pill" onclick="filterCategory('Smart Home')">🏠 Smart Home</button>
611
+ <button class="cat-pill" onclick="filterCategory('Gaming')">🎮 Gaming</button>
612
+ </div>
613
+
614
+ <!-- Main Content -->
615
+ <main class="main">
616
+ <h1 class="page-title">Unsere Produkte</h1>
617
+ <p class="page-subtitle">Entdecke die neuesten Tech-Highlights — handverlesen für dich.</p>
618
+
619
+ <div class="product-grid" id="productGrid">
620
+ <!-- Products injected by JS -->
621
+ </div>
622
+
623
+ <!-- Features Section -->
624
+ <div class="features-section">
625
+ <div class="features-title">🛡️ Warum NeonStore?</div>
626
+ <p class="features-subtitle">Einkaufen ohne Kompromisse.</p>
627
+ <div class="features-grid">
628
+ <div class="feature-card">
629
+ <div class="feature-icon">🚚</div>
630
+ <div class="feature-name">Kostenloser Versand</div>
631
+ <div class="feature-desc">Ab 49 € Bestellwert — deutschlandweit in 1-3 Werktagen.</div>
632
+ </div>
633
+ <div class="feature-card">
634
+ <div class="feature-icon">↩️</div>
635
+ <div class="feature-name">30 Tage Rückgabe</div>
636
+ <div class="feature-desc">Nicht zufrieden? Kostenlose Rücksendung innerhalb von 30 Tagen.</div>
637
+ </div>
638
+ <div class="feature-card">
639
+ <div class="feature-icon">🔒</div>
640
+ <div class="feature-name">Sichere Zahlung</div>
641
+ <div class="feature-desc">SSL-verschlüsselt. PayPal, Kreditkarte, Klarna, Apple Pay.</div>
642
+ </div>
643
+ <div class="feature-card">
644
+ <div class="feature-icon">💬</div>
645
+ <div class="feature-name">24/7 Support</div>
646
+ <div class="feature-desc">Unser Team hilft dir jederzeit — per Chat, E-Mail oder Telefon.</div>
647
+ </div>
648
+ </div>
649
+ </div>
650
+
651
+ <!-- Newsletter -->
652
+ <div class="newsletter-section">
653
+ <div class="newsletter-title">📬 Newsletter abonnieren</div>
654
+ <div class="newsletter-desc">Erhalte exklusive Angebote und Neuigkeiten direkt in dein Postfach.</div>
655
+ <form class="newsletter-form" onsubmit="event.preventDefault(); showToast('✅ Erfolgreich angemeldet!')">
656
+ <input type="email" placeholder="deine@email.de" required>
657
+ <button type="submit">Abonnieren</button>
658
+ </form>
659
+ </div>
660
+ </main>
661
+
662
+ <!-- Footer -->
663
+ <footer>
664
+ <div class="site-footer">
665
+ <div class="footer-col">
666
+ <h4>Shop</h4>
667
+ <a href="#" onclick="filterCategory('Neu')">Neuheiten</a>
668
+ <a href="#" onclick="filterCategory('all')">Alle Produkte</a>
669
+ <a href="#" onclick="filterCategory('Sale')">Sale</a>
670
+ <a href="#">Geschenkgutscheine</a>
671
+ </div>
672
+ <div class="footer-col">
673
+ <h4>Service</h4>
674
+ <a href="#">Hilfe & FAQ</a>
675
+ <a href="#">Versand & Lieferung</a>
676
+ <a href="#">Rückgabe & Umtausch</a>
677
+ <a href="#">Kontakt</a>
678
+ </div>
679
+ <div class="footer-col">
680
+ <h4>Unternehmen</h4>
681
+ <a href="#">Über uns</a>
682
+ <a href="#">Karriere</a>
683
+ <a href="#">Blog</a>
684
+ <a href="#">Presse</a>
685
+ </div>
686
+ <div class="footer-col">
687
+ <h4>Rechtliches</h4>
688
+ <a href="#">Impressum</a>
689
+ <a href="#">Datenschutz</a>
690
+ <a href="#">AGB</a>
691
+ <a href="#">Cookie-Einstellungen</a>
692
+ </div>
693
+ </div>
694
+ <div class="footer-bottom">
695
+ © 2026 NeonStore (Demo) — Diese Seite ist eine Demo für das
696
+ <a href="https://github.com/TeamStriebigSebastian/Bug-Report-Widget" target="_blank">Bug Report Widget v2</a>.
697
+ <br>Keine echten Produkte. Kein echter Shop.
698
+ </div>
699
+ </footer>
700
+
701
+ <!-- Cart Drawer -->
702
+ <div class="cart-overlay" id="cartOverlay" onclick="toggleCart()"></div>
703
+ <div class="cart-drawer" id="cartDrawer">
704
+ <div class="cart-header">
705
+ <div class="cart-title">🛒 Warenkorb</div>
706
+ <button class="cart-close" onclick="toggleCart()">✕</button>
707
+ </div>
708
+ <div class="cart-items" id="cartItems">
709
+ <div class="cart-empty">
710
+ <div class="cart-empty-icon">🛒</div>
711
+ <div>Dein Warenkorb ist leer</div>
712
+ </div>
713
+ </div>
714
+ <div class="cart-footer" id="cartFooter" style="display:none">
715
+ <div class="cart-total">
716
+ <span>Gesamt</span>
717
+ <span class="cart-total-price" id="cartTotal">€ 0,00</span>
718
+ </div>
719
+ <button class="btn-checkout" onclick="checkout()">Zur Kasse →</button>
720
+ </div>
721
+ </div>
722
+
723
+ <!-- Toast -->
724
+ <div class="toast" id="toast"></div>
725
+
726
+ <!-- Native tooltip is configured via BugReportWidget.init() -->
727
+
728
+ <script>
729
+ // ═══════════════════════════════════════════════════════════════
730
+ // PRODUCT DATA
731
+ // ═══════════════════════════════════════════════════════════════
732
+
733
+ const products = [
734
+ { id: 1, name: 'AuraBeats Pro', category: 'Audio', emoji: '🎧', price: 249.99, oldPrice: null, badge: 'new', rating: 4.8, reviews: 342, desc: 'Kabellose Over-Ear-Kopfhörer mit Active Noise Cancellation und 40h Akkulaufzeit.' },
735
+ { id: 2, name: 'PulseWatch Ultra', category: 'Wearables', emoji: '⌚', price: 399.00, oldPrice: 499.00, badge: 'sale', rating: 4.6, reviews: 891, desc: 'Smartwatch mit AMOLED-Display, EKG-Sensor und 14 Tagen Akkulaufzeit.' },
736
+ { id: 3, name: 'NeonCharge 65W', category: 'Zubehör', emoji: '🔌', price: 39.99, oldPrice: null, badge: null, rating: 4.9, reviews: 1203, desc: 'Kompaktes GaN-Ladegerät mit 3 Ports — USB-C PD und USB-A Quick Charge.' },
737
+ { id: 4, name: 'CubeLight Mini', category: 'Smart Home', emoji: '💡', price: 29.99, oldPrice: 44.99, badge: 'sale', rating: 4.3, reviews: 567, desc: 'RGBW Smart Light mit App-Steuerung, Alexa und Google Home kompatibel.' },
738
+ { id: 5, name: 'VortexPad Wireless', category: 'Gaming', emoji: '🎮', price: 79.90, oldPrice: null, badge: 'hot', rating: 4.7, reviews: 234, desc: 'Kabelloses Gaming-Mousepad mit RGB-Beleuchtung und Qi-Ladefläche.' },
739
+ { id: 6, name: 'SkyBuds Lite', category: 'Audio', emoji: '🎵', price: 59.99, oldPrice: 89.99, badge: 'sale', rating: 4.4, reviews: 1876, desc: 'True Wireless Earbuds mit IPX5 Wasserschutz und 8h Spielzeit pro Ladung.' },
740
+ { id: 7, name: 'FlexBand Sport', category: 'Wearables', emoji: '📱', price: 49.99, oldPrice: null, badge: 'new', rating: 4.5, reviews: 445, desc: 'Fitness-Tracker mit SpO2-Sensor, Schlafanalyse und 10 Tagen Akkulaufzeit.' },
741
+ { id: 8, name: 'CloudCam 360', category: 'Smart Home', emoji: '📷', price: 69.00, oldPrice: null, badge: null, rating: 4.2, reviews: 312, desc: '360°-Überwachungskamera mit Nachtsicht, 2K-Auflösung und lokaler Speicherung.' },
742
+ { id: 9, name: 'TurboHub 7-in-1', category: 'Zubehör', emoji: '🔗', price: 54.99, oldPrice: 74.99, badge: 'sale', rating: 4.8, reviews: 2103, desc: 'USB-C Hub mit HDMI 4K, SD-Kartenleser, Ethernet und 100W Power Delivery.' },
743
+ { id: 10, name: 'ArcadeStick Pro', category: 'Gaming', emoji: '🕹️', price: 129.00, oldPrice: null, badge: 'hot', rating: 4.9, reviews: 187, desc: 'Premium Arcade Controller mit Sanwa-Buttons und Hall-Effect-Joystick.' },
744
+ { id: 11, name: 'EchoSphere', category: 'Audio', emoji: '🔊', price: 189.00, oldPrice: 229.00, badge: 'sale', rating: 4.6, reviews: 723, desc: '360°-Bluetooth-Lautsprecher mit Multiroom-Support und 20h Akkulaufzeit.' },
745
+ { id: 12, name: 'PixelFrame 10"', category: 'Smart Home', emoji: '🖼️', price: 99.99, oldPrice: null, badge: 'new', rating: 4.1, reviews: 156, desc: 'Digitaler Bilderrahmen mit IPS-Display, Cloud-Sync und Gestenerkennung.' },
746
+ ];
747
+
748
+ // ═══════════════════════════════════════════════════════════════
749
+ // RENDERING
750
+ // ═══════════════════════════════════════════════════════════════
751
+
752
+ function renderStars(rating) {
753
+ const full = Math.floor(rating);
754
+ const half = rating % 1 >= 0.5 ? 1 : 0;
755
+ const empty = 5 - full - half;
756
+ return '★'.repeat(full) + (half ? '½' : '') + '☆'.repeat(empty);
757
+ }
758
+
759
+ function renderProducts(filter = 'all') {
760
+ const grid = document.getElementById('productGrid');
761
+ let filtered = products;
762
+
763
+ if (filter === 'Neu') {
764
+ filtered = products.filter(p => p.badge === 'new');
765
+ } else if (filter === 'Sale') {
766
+ filtered = products.filter(p => p.badge === 'sale');
767
+ } else if (filter !== 'all') {
768
+ filtered = products.filter(p => p.category === filter);
769
+ }
770
+
771
+ grid.innerHTML = filtered.map(p => `
772
+ <div class="product-card" onclick="viewProduct(${p.id})" role="article">
773
+ <div class="product-img-placeholder">${p.emoji}</div>
774
+ ${p.badge ? `<span class="product-badge badge-${p.badge}">${p.badge === 'new' ? 'Neu' : p.badge === 'sale' ? 'Sale' : 'Hot'}</span>` : ''}
775
+ <div class="product-body">
776
+ <div class="product-category">${p.category}</div>
777
+ <div class="product-name">${p.name}</div>
778
+ <div class="rating">
779
+ <span class="rating-stars" style="color: #fbbf24">${renderStars(p.rating)}</span>
780
+ <span class="rating-count">(${p.reviews})</span>
781
+ </div>
782
+ <div class="product-desc">${p.desc}</div>
783
+ <div class="product-footer">
784
+ <div>
785
+ <span class="product-price">€ ${p.price.toFixed(2).replace('.', ',')}</span>
786
+ ${p.oldPrice ? `<span class="product-price-old">€ ${p.oldPrice.toFixed(2).replace('.', ',')}</span>` : ''}
787
+ </div>
788
+ <button class="btn-add-cart" onclick="event.stopPropagation(); addToCart(${p.id})">
789
+ 🛒 Hinzufügen
790
+ </button>
791
+ </div>
792
+ </div>
793
+ </div>
794
+ `).join('');
795
+ }
796
+
797
+ // ═══════════════════════════════════════════════════════════════
798
+ // CART LOGIC
799
+ // ═══════════════════════════════════════════════════════════════
800
+
801
+ let cart = [];
802
+
803
+ function addToCart(productId) {
804
+ const product = products.find(p => p.id === productId);
805
+ if (!product) return;
806
+
807
+ const existing = cart.find(c => c.id === productId);
808
+ if (existing) {
809
+ existing.qty++;
810
+ } else {
811
+ cart.push({ ...product, qty: 1 });
812
+ }
813
+
814
+ updateCartUI();
815
+ showToast(`✅ ${product.name} zum Warenkorb hinzugefügt`);
816
+ console.log(`[Cart] Added: ${product.name} — Cart total: ${cart.reduce((s, i) => s + i.qty, 0)} items`);
817
+ }
818
+
819
+ function removeFromCart(productId) {
820
+ cart = cart.filter(c => c.id !== productId);
821
+ updateCartUI();
822
+ console.log(`[Cart] Removed item ${productId} — Cart total: ${cart.reduce((s, i) => s + i.qty, 0)} items`);
823
+ }
824
+
825
+ function updateCartUI() {
826
+ const badge = document.getElementById('cartBadge');
827
+ const itemsEl = document.getElementById('cartItems');
828
+ const footerEl = document.getElementById('cartFooter');
829
+ const totalEl = document.getElementById('cartTotal');
830
+
831
+ const totalQty = cart.reduce((s, i) => s + i.qty, 0);
832
+ const totalPrice = cart.reduce((s, i) => s + i.price * i.qty, 0);
833
+
834
+ badge.textContent = totalQty;
835
+
836
+ if (cart.length === 0) {
837
+ itemsEl.innerHTML = `
838
+ <div class="cart-empty">
839
+ <div class="cart-empty-icon">🛒</div>
840
+ <div>Dein Warenkorb ist leer</div>
841
+ </div>`;
842
+ footerEl.style.display = 'none';
843
+ } else {
844
+ itemsEl.innerHTML = cart.map(item => `
845
+ <div class="cart-item">
846
+ <div class="cart-item-emoji">${item.emoji}</div>
847
+ <div class="cart-item-info">
848
+ <div class="cart-item-name">${item.name} ${item.qty > 1 ? `× ${item.qty}` : ''}</div>
849
+ <div class="cart-item-price">€ ${(item.price * item.qty).toFixed(2).replace('.', ',')}</div>
850
+ </div>
851
+ <button class="cart-item-remove" onclick="removeFromCart(${item.id})">Entfernen</button>
852
+ </div>
853
+ `).join('');
854
+ footerEl.style.display = 'block';
855
+ totalEl.textContent = `€ ${totalPrice.toFixed(2).replace('.', ',')}`;
856
+ }
857
+ }
858
+
859
+ function toggleCart() {
860
+ const overlay = document.getElementById('cartOverlay');
861
+ const drawer = document.getElementById('cartDrawer');
862
+ const isOpen = overlay.classList.contains('open');
863
+
864
+ if (isOpen) {
865
+ overlay.classList.remove('open');
866
+ drawer.classList.remove('open');
867
+ } else {
868
+ overlay.classList.add('open');
869
+ drawer.classList.add('open');
870
+ }
871
+ }
872
+
873
+ function checkout() {
874
+ if (cart.length === 0) return;
875
+ const total = cart.reduce((s, i) => s + i.price * i.qty, 0);
876
+ console.log(`[Checkout] Processing order: € ${total.toFixed(2)} — ${cart.length} products`);
877
+
878
+ // Simulate a network request
879
+ fetch('https://httpbin.org/post', {
880
+ method: 'POST',
881
+ headers: { 'Content-Type': 'application/json' },
882
+ body: JSON.stringify({ action: 'checkout', total }),
883
+ }).then(() => {
884
+ showToast('🎉 Bestellung erfolgreich aufgegeben!');
885
+ cart = [];
886
+ updateCartUI();
887
+ toggleCart();
888
+ }).catch(() => {
889
+ console.error('[Checkout] Order failed!');
890
+ showToast('❌ Bestellung fehlgeschlagen — bitte erneut versuchen.');
891
+ });
892
+ }
893
+
894
+ // ═══════════════════════════════════════════════════════════════
895
+ // INTERACTIONS
896
+ // ═══════════════════════════════════════════════════════════════
897
+
898
+ function viewProduct(id) {
899
+ const p = products.find(pr => pr.id === id);
900
+ if (p) {
901
+ console.log(`[Product] Viewing: ${p.name} (${p.category}) — € ${p.price}`);
902
+ showToast(`${p.emoji} ${p.name} — € ${p.price.toFixed(2).replace('.', ',')}`);
903
+ }
904
+ }
905
+
906
+ function filterCategory(cat) {
907
+ // Update active pill
908
+ document.querySelectorAll('.cat-pill').forEach(pill => {
909
+ pill.classList.remove('active');
910
+ if (pill.textContent.includes(cat) || (cat === 'all' && pill.textContent.includes('Alle'))) {
911
+ pill.classList.add('active');
912
+ }
913
+ });
914
+ renderProducts(cat);
915
+ console.log(`[Filter] Category: ${cat}`);
916
+ }
917
+
918
+ // Search
919
+ document.getElementById('searchInput').addEventListener('input', (e) => {
920
+ const q = e.target.value.toLowerCase();
921
+ if (q.length < 2) { renderProducts('all'); return; }
922
+ const grid = document.getElementById('productGrid');
923
+ const filtered = products.filter(p =>
924
+ p.name.toLowerCase().includes(q) ||
925
+ p.category.toLowerCase().includes(q) ||
926
+ p.desc.toLowerCase().includes(q)
927
+ );
928
+ grid.innerHTML = filtered.length ? filtered.map(p => `
929
+ <div class="product-card" onclick="viewProduct(${p.id})" role="article">
930
+ <div class="product-img-placeholder">${p.emoji}</div>
931
+ ${p.badge ? `<span class="product-badge badge-${p.badge}">${p.badge === 'new' ? 'Neu' : p.badge === 'sale' ? 'Sale' : 'Hot'}</span>` : ''}
932
+ <div class="product-body">
933
+ <div class="product-category">${p.category}</div>
934
+ <div class="product-name">${p.name}</div>
935
+ <div class="rating">
936
+ <span class="rating-stars" style="color: #fbbf24">${renderStars(p.rating)}</span>
937
+ <span class="rating-count">(${p.reviews})</span>
938
+ </div>
939
+ <div class="product-desc">${p.desc}</div>
940
+ <div class="product-footer">
941
+ <div>
942
+ <span class="product-price">€ ${p.price.toFixed(2).replace('.', ',')}</span>
943
+ ${p.oldPrice ? `<span class="product-price-old">€ ${p.oldPrice.toFixed(2).replace('.', ',')}</span>` : ''}
944
+ </div>
945
+ <button class="btn-add-cart" onclick="event.stopPropagation(); addToCart(${p.id})">
946
+ 🛒 Hinzufügen
947
+ </button>
948
+ </div>
949
+ </div>
950
+ </div>
951
+ `).join('') : '<p style="color: var(--text-muted); grid-column: 1/-1; text-align:center; padding:40px;">Keine Produkte gefunden.</p>';
952
+ });
953
+
954
+ // ═══════════════════════════════════════════════════════════════
955
+ // TOAST
956
+ // ═══════════════════════════════════════════════════════════════
957
+
958
+ let toastTimer = null;
959
+ function showToast(msg) {
960
+ const toast = document.getElementById('toast');
961
+ toast.textContent = msg;
962
+ toast.classList.add('show');
963
+ clearTimeout(toastTimer);
964
+ toastTimer = setTimeout(() => toast.classList.remove('show'), 2500);
965
+ }
966
+
967
+ // ═══════════════════════════════════════════════════════════════
968
+ // WIDGET HINT AUTO-HIDE
969
+ // ═══════════════════════════════════════════════════════════════
970
+
971
+ // Widget configuration using native tooltip
972
+ BugReportWidget.init({
973
+ language: 'de',
974
+ tooltipMessage: 'Klicke auf den <strong>{icon} Button</strong> unten um einen Bug Report zu erstellen!'
975
+ });
976
+
977
+ // ═══════════════════════════════════════════════════════════════
978
+ // INIT
979
+ // ═══════════════════════════════════════════════════════════════
980
+
981
+ renderProducts();
982
+
983
+ // Simulate some background console activity
984
+ console.info('[NeonStore] App initialized — v2.1.0');
985
+ console.log('[NeonStore] Loaded 12 products');
986
+ setTimeout(() => console.warn('[Performance] Slow API response detected: /api/recommendations (1.2s)'), 3000);
987
+ setTimeout(() => {
988
+ fetch('https://httpbin.org/delay/1').then(r => console.log(`[API] Recommendations loaded: ${r.status}`));
989
+ }, 2000);
990
+ </script>
991
+
992
+ <!-- Bug Report Widget v2 -->
993
+ <script src="bug-report.js"></script>
994
+
995
+ </body>
996
+ </html>