HyperMehfin commited on
Commit
728527b
·
verified ·
1 Parent(s): 9ee5eb7

Upload 10 files

Browse files
templates/detect.html ADDED
@@ -0,0 +1,1018 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="theme-color" content="#0a192f">
8
+ <title>DeepFake Detection - Video Analysis</title>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
10
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
11
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
12
+ <style>
13
+ /* Base styles */
14
+ :root {
15
+ --primary-color: #64ffda;
16
+ --primary-dark: #4cd6b3;
17
+ --bg-dark: #1a1a1a;
18
+ --bg-darker: #111d40;
19
+ --text-light: #8892b0;
20
+ --border-color: rgba(100, 255, 218, 0.1);
21
+ }
22
+
23
+ /* Navigation */
24
+ .navbar {
25
+ background: var(--bg-dark);
26
+ padding: 1rem 2rem;
27
+ height: 70px;
28
+ display: flex;
29
+ justify-content: space-between;
30
+ align-items: center;
31
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
32
+ position: sticky;
33
+ top: 0;
34
+ z-index: 1000;
35
+ }
36
+
37
+ .navbar-brand {
38
+ color: var(--primary-color);
39
+ font-size: 1.5rem;
40
+ font-weight: bold;
41
+ text-decoration: none;
42
+ transition: color 0.3s ease;
43
+ }
44
+
45
+ .navbar-brand:hover {
46
+ color: var(--primary-dark);
47
+ }
48
+
49
+ /* Hamburger Button (Hidden on PC) */
50
+ .hamburger {
51
+ display: none;
52
+ background: none;
53
+ border: none;
54
+ color: #64ffda;
55
+ font-size: 2rem;
56
+ cursor: pointer;
57
+ padding: 0;
58
+ }
59
+
60
+ .navbar-nav {
61
+ display: flex;
62
+ gap: 1rem;
63
+ align-items: center;
64
+ transition: all 0.3s ease;
65
+ }
66
+
67
+ .nav-link {
68
+ color: #fff;
69
+ text-decoration: none;
70
+ padding: 0.5rem 1rem;
71
+ border-radius: 4px;
72
+ transition: all 0.3s ease;
73
+ }
74
+
75
+ .nav-link:hover, .nav-link.active {
76
+ background: rgba(100, 255, 218, 0.1);
77
+ color: var(--primary-color);
78
+ }
79
+
80
+ .nav-link.highlight {
81
+ background: var(--primary-color);
82
+ color: var(--bg-dark);
83
+ }
84
+
85
+ .nav-link.highlight:hover {
86
+ background: var(--primary-dark);
87
+ }
88
+
89
+ /* Content */
90
+ .content {
91
+ padding: 2rem;
92
+ max-width: 1200px;
93
+ margin: 0 auto;
94
+ animation: fadeIn 0.5s ease-in-out;
95
+ }
96
+
97
+ /* Upload Section */
98
+ .upload-section { margin: 2rem 0; }
99
+
100
+ .upload-container {
101
+ display: flex;
102
+ flex-direction: column;
103
+ align-items: center;
104
+ gap: 1.5rem;
105
+ padding: 2rem;
106
+ }
107
+
108
+ .file-input-wrapper {
109
+ position: relative;
110
+ width: 100%;
111
+ max-width: 400px;
112
+ }
113
+
114
+ .file-input-wrapper input[type="file"] {
115
+ position: absolute;
116
+ left: 0;
117
+ top: 0;
118
+ opacity: 0;
119
+ width: 100%;
120
+ height: 100%;
121
+ cursor: pointer;
122
+ }
123
+
124
+ .file-label {
125
+ display: block;
126
+ padding: 1rem 2rem;
127
+ background: rgba(100, 255, 218, 0.1);
128
+ border: 2px dashed var(--primary-color);
129
+ border-radius: 8px;
130
+ text-align: center;
131
+ color: var(--primary-color);
132
+ cursor: pointer;
133
+ transition: all 0.3s ease;
134
+ }
135
+
136
+ .file-label:hover {
137
+ background: rgba(100, 255, 218, 0.2);
138
+ transform: translateY(-2px);
139
+ }
140
+
141
+ /* Loading States */
142
+ .loading-container {
143
+ display: none;
144
+ flex-direction: column;
145
+ align-items: center;
146
+ gap: 1rem;
147
+ margin: 1rem 0;
148
+ }
149
+
150
+ .loading-spinner {
151
+ width: 40px;
152
+ height: 40px;
153
+ border: 3px solid rgba(100, 255, 218, 0.1);
154
+ border-top: 3px solid var(--primary-color);
155
+ border-radius: 50%;
156
+ animation: spin 1s linear infinite;
157
+ }
158
+
159
+ .loading-text {
160
+ color: var(--primary-color);
161
+ font-size: 0.9rem;
162
+ }
163
+
164
+ /* Results Section */
165
+ .result-container {
166
+ background: var(--bg-darker);
167
+ border: 1px solid var(--border-color);
168
+ border-radius: 12px;
169
+ padding: 2rem;
170
+ margin: 2rem 0;
171
+ text-align: center;
172
+ }
173
+
174
+ .result-heading {
175
+ color: var(--primary-color);
176
+ font-size: 1.8rem;
177
+ margin-bottom: 1.5rem;
178
+ font-weight: 600;
179
+ }
180
+
181
+ .result-content {
182
+ display: flex;
183
+ flex-direction: column;
184
+ align-items: center;
185
+ gap: 1rem;
186
+ }
187
+
188
+ .result-text {
189
+ font-size: 3rem;
190
+ font-weight: bold;
191
+ margin: 1rem 0;
192
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
193
+ letter-spacing: 2px;
194
+ }
195
+
196
+ .result-text.fake {
197
+ color: #ff4d4d;
198
+ background: linear-gradient(135deg, #ff4d4d, #ff6b6b);
199
+ -webkit-background-clip: text;
200
+ -webkit-text-fill-color: transparent;
201
+ background-clip: text;
202
+ }
203
+
204
+ .result-text.real {
205
+ color: #4dff4d;
206
+ background: linear-gradient(135deg, #4dff4d, #6bff6b);
207
+ -webkit-background-clip: text;
208
+ -webkit-text-fill-color: transparent;
209
+ background-clip: text;
210
+ }
211
+
212
+ .confidence-text {
213
+ font-size: 1.2rem;
214
+ color: var(--text-light);
215
+ margin-top: 0.5rem;
216
+ font-weight: 500;
217
+ }
218
+
219
+ /* Analysis Details */
220
+ .details-grid {
221
+ display: grid;
222
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
223
+ gap: 1.5rem;
224
+ margin-top: 1rem;
225
+ }
226
+
227
+ .detail-item {
228
+ background: rgba(17, 34, 64, 0.3);
229
+ border: 1px solid var(--border-color);
230
+ border-radius: 8px;
231
+ padding: 1rem;
232
+ text-align: center;
233
+ }
234
+
235
+ .detail-label {
236
+ display: block;
237
+ color: var(--primary-color);
238
+ font-size: 0.9rem;
239
+ margin-bottom: 0.5rem;
240
+ }
241
+
242
+ .detail-value {
243
+ font-size: 1.5rem;
244
+ font-weight: 600;
245
+ color: var(--text-light);
246
+ }
247
+
248
+ /* Frames Grid */
249
+ .frames-container {
250
+ display: grid;
251
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
252
+ gap: 1.5rem;
253
+ margin: 2rem 0;
254
+ }
255
+
256
+ .frame-item {
257
+ position: relative;
258
+ background: rgba(17, 34, 64, 0.5);
259
+ border: 1px solid var(--border-color);
260
+ border-radius: 8px;
261
+ overflow: hidden;
262
+ transition: all 0.3s ease;
263
+ cursor: pointer;
264
+ }
265
+
266
+ .frame-item:hover {
267
+ transform: scale(1.05);
268
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
269
+ }
270
+
271
+ .frame-item img {
272
+ width: 100%;
273
+ height: 200px;
274
+ object-fit: cover;
275
+ display: block;
276
+ }
277
+
278
+ .frame-info {
279
+ position: absolute;
280
+ bottom: 0;
281
+ left: 0;
282
+ right: 0;
283
+ padding: 0.5rem;
284
+ background: rgba(17, 34, 64, 0.8);
285
+ text-align: center;
286
+ transform: translateY(100%);
287
+ transition: transform 0.3s ease;
288
+ }
289
+
290
+ .frame-item:hover .frame-info {
291
+ transform: translateY(0);
292
+ }
293
+
294
+ .frame-number {
295
+ color: var(--primary-color);
296
+ font-weight: 600;
297
+ margin: 0;
298
+ font-size: 0.9rem;
299
+ }
300
+
301
+ /* Footer */
302
+ .footer {
303
+ margin-top: auto;
304
+ padding: 3rem 0;
305
+ background: var(--bg-darker);
306
+ border-top: 1px solid var(--border-color);
307
+ }
308
+
309
+ .footer-content {
310
+ max-width: 1200px;
311
+ margin: 0 auto;
312
+ padding: 0 2rem;
313
+ display: flex;
314
+ justify-content: space-between;
315
+ gap: 2rem;
316
+ }
317
+
318
+ .footer-section { flex: 1; }
319
+ .footer-section h3 { color: var(--primary-color); margin-bottom: 1rem; }
320
+ .footer-link { color: var(--text-light); text-decoration: none; display: block; margin: 0.5rem 0; transition: color 0.3s ease; }
321
+ .footer-link:hover { color: var(--primary-color); }
322
+
323
+ @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
324
+
325
+ .visually-hidden {
326
+ position: absolute;
327
+ width: 1px;
328
+ height: 1px;
329
+ padding: 0;
330
+ margin: -1px;
331
+ overflow: hidden;
332
+ clip: rect(0, 0, 0, 0);
333
+ border: 0;
334
+ }
335
+
336
+ .error-message {
337
+ color: #ff4d4d;
338
+ background: rgba(255, 77, 77, 0.1);
339
+ border: 1px solid #ff4d4d;
340
+ padding: 0.75rem;
341
+ border-radius: 4px;
342
+ margin: 1rem 0;
343
+ text-align: center;
344
+ }
345
+
346
+ .cta-button {
347
+ display: inline-block;
348
+ padding: 1rem 2rem;
349
+ background: var(--primary-color);
350
+ color: var(--bg-dark);
351
+ text-decoration: none;
352
+ border-radius: 4px;
353
+ font-weight: bold;
354
+ transition: all 0.3s ease;
355
+ border: none;
356
+ cursor: pointer;
357
+ }
358
+
359
+ .cta-button:hover {
360
+ background: var(--primary-dark);
361
+ transform: translateY(-2px);
362
+ }
363
+
364
+ /* Feature Cards */
365
+ .feature-card {
366
+ background: var(--bg-darker);
367
+ border: 1px solid var(--border-color);
368
+ border-radius: 8px;
369
+ padding: 2rem;
370
+ margin: 2rem 0;
371
+ }
372
+
373
+ .success-message { margin: 2rem 0; }
374
+
375
+ /* Pie Chart Styles */
376
+ .pie-chart-section {
377
+ display: flex;
378
+ flex-direction: column;
379
+ align-items: center;
380
+ gap: 2rem;
381
+ padding: 2.5rem;
382
+ background: linear-gradient(135deg, rgba(100, 255, 218, 0.08) 0%, rgba(26, 26, 26, 0.9) 100%);
383
+ border: 1px solid rgba(100, 255, 218, 0.15);
384
+ border-radius: 16px;
385
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
386
+ }
387
+
388
+ .pie-chart-section h3 {
389
+ color: #64ffda;
390
+ margin: 0;
391
+ font-size: 1.8rem;
392
+ font-weight: 600;
393
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
394
+ }
395
+
396
+ .pie-chart-container {
397
+ position: relative;
398
+ width: 350px;
399
+ height: 350px;
400
+ margin: 0 auto;
401
+ display: flex;
402
+ flex-direction: column;
403
+ align-items: center;
404
+ background: rgba(26, 26, 26, 0.3);
405
+ border-radius: 50%;
406
+ padding: 20px;
407
+ }
408
+
409
+ #resultPieChart {
410
+ position: relative;
411
+ width: 100%;
412
+ height: 100%;
413
+ border-radius: 50%;
414
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
415
+ background: transparent;
416
+ }
417
+
418
+ .pie-chart-legend {
419
+ display: flex;
420
+ justify-content: center;
421
+ gap: 2.5rem;
422
+ margin-top: 1rem;
423
+ padding: 1.5rem;
424
+ background: rgba(26, 26, 26, 0.8);
425
+ border-radius: 12px;
426
+ border: 1px solid rgba(100, 255, 218, 0.15);
427
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
428
+ width: 100%;
429
+ max-width: 400px;
430
+ }
431
+
432
+ .legend-item {
433
+ display: flex;
434
+ align-items: center;
435
+ gap: 1rem;
436
+ padding: 0.75rem 1.5rem;
437
+ border-radius: 8px;
438
+ transition: all 0.3s ease;
439
+ }
440
+
441
+ .legend-color {
442
+ display: inline-block;
443
+ width: 20px;
444
+ height: 20px;
445
+ border-radius: 6px;
446
+ border: 2px solid rgba(255, 255, 255, 0.2);
447
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
448
+ }
449
+
450
+ .real-color { background: linear-gradient(135deg, #27ae60, #2ecc71); }
451
+ .fake-color { background: linear-gradient(135deg, #e74c3c, #c0392b); }
452
+
453
+ .legend-text {
454
+ color: var(--text-light);
455
+ font-size: 1.1rem;
456
+ font-weight: 600;
457
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
458
+ }
459
+
460
+ /* Heatmap Section Styles */
461
+ .heatmap-section {
462
+ background: var(--bg-darker);
463
+ border: 1px solid var(--border-color);
464
+ border-radius: 12px;
465
+ padding: 2rem;
466
+ margin: 2rem 0;
467
+ text-align: center;
468
+ }
469
+
470
+ .heatmap-container {
471
+ margin-top: 1.5rem;
472
+ display: flex;
473
+ justify-content: center;
474
+ align-items: center;
475
+ gap: 2rem;
476
+ flex-wrap: wrap;
477
+ }
478
+
479
+ .heatmap-image-wrapper {
480
+ position: relative;
481
+ max-width: 100%;
482
+ border-radius: 12px;
483
+ overflow: hidden;
484
+ border: 2px solid var(--primary-color);
485
+ box-shadow: 0 8px 32px rgba(0, 255, 218, 0.2);
486
+ }
487
+
488
+ .heatmap-image {
489
+ width: 100%;
490
+ display: block;
491
+ }
492
+
493
+ .heatmap-legend {
494
+ display: flex;
495
+ flex-direction: column;
496
+ gap: 1rem;
497
+ text-align: left;
498
+ background: rgba(17, 34, 64, 0.5);
499
+ padding: 1.5rem;
500
+ border-radius: 8px;
501
+ border: 1px solid var(--border-color);
502
+ }
503
+
504
+ .heatmap-legend-item { display: flex; align-items: center; gap: 0.75rem; }
505
+ .heatmap-color-scale {
506
+ width: 150px;
507
+ height: 12px;
508
+ background: linear-gradient(to right, #3b4cc0, #b40426);
509
+ border-radius: 6px;
510
+ }
511
+
512
+ .heatmap-info-text {
513
+ color: var(--text-light);
514
+ max-width: 500px;
515
+ margin: 1rem auto 0;
516
+ font-size: 0.95rem;
517
+ line-height: 1.6;
518
+ }
519
+
520
+ /* --- MOBILE HAMBURGER MENU & FIXES --- */
521
+ @media (max-width: 768px) {
522
+ body {
523
+ -webkit-tap-highlight-color: transparent;
524
+ -webkit-touch-callout: none;
525
+ user-select: none;
526
+ }
527
+ .navbar {
528
+ padding: 1rem 1.5rem;
529
+ }
530
+ .hamburger {
531
+ display: block;
532
+ }
533
+ .navbar-nav {
534
+ display: flex;
535
+ flex-direction: column;
536
+ position: absolute;
537
+ top: 70px;
538
+ left: 0;
539
+ width: 100%;
540
+ background: rgba(17, 29, 64, 0.98);
541
+ padding: 0;
542
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
543
+ max-height: 0;
544
+ overflow: hidden;
545
+ opacity: 0;
546
+ transition: all 0.3s ease;
547
+ }
548
+ .navbar-nav.active {
549
+ max-height: 500px;
550
+ padding: 1rem 0;
551
+ opacity: 1;
552
+ }
553
+ .nav-link {
554
+ width: 100%;
555
+ text-align: center;
556
+ padding: 1.2rem;
557
+ border-radius: 0;
558
+ }
559
+ .content { padding: 1rem; }
560
+ .result-content { grid-template-columns: 1fr; }
561
+ .details-grid { grid-template-columns: 1fr; }
562
+ .footer-content { flex-direction: column; text-align: center; }
563
+
564
+ /* FIXED CHART SIZE AND LEGEND OVERLAP */
565
+ .pie-chart-container {
566
+ width: 100% !important;
567
+ max-width: 250px !important;
568
+ height: 250px !important;
569
+ padding: 10px;
570
+ margin: 0 auto;
571
+ box-sizing: border-box;
572
+ }
573
+ #resultPieChart {
574
+ width: 100% !important;
575
+ height: 100% !important;
576
+ }
577
+
578
+ .pie-chart-legend {
579
+ flex-direction: column;
580
+ gap: 1rem;
581
+ padding: 1rem;
582
+ margin-top: 1.5rem;
583
+ }
584
+ .heatmap-container { flex-direction: column; }
585
+ .file-input-wrapper { width: 100%; box-sizing: border-box; }
586
+ .upload-container { padding: 1rem; }
587
+ }
588
+ </style>
589
+ </head>
590
+
591
+ <body>
592
+ {% if data %}
593
+ <script>
594
+ window.data = '{{ data | safe }}';
595
+ </script>
596
+ {% else %}
597
+ <script>
598
+ window.data = null;
599
+ </script>
600
+ {% endif %}
601
+
602
+ <div id="root">
603
+ <nav class="navbar">
604
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a>
605
+
606
+ <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu">
607
+
608
+ </button>
609
+
610
+ <div class="navbar-nav" id="nav-links">
611
+ {% if current_user.is_authenticated %}
612
+ <a href="{{ url_for('detect') }}" class="nav-link active">Upload Video</a>
613
+ <a href="{{ url_for('image_detect') }}" class="nav-link">Detect Image</a>
614
+ <a href="{{ url_for('history') }}" class="nav-link">History</a>
615
+ {% if current_user.is_admin %}
616
+ <a href="{{ url_for('admin') }}" class="nav-link">Admin</a>
617
+ {% endif %}
618
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
619
+ {% else %}
620
+ <a href="{{ url_for('signup') }}" class="nav-link highlight">Sign Up</a>
621
+ {% endif %}
622
+ </div>
623
+ </nav>
624
+
625
+ <main class="content" role="main">
626
+ <h1 class="heading">Detect DeepFake Videos</h1>
627
+ <p class="para">Upload your video for AI-powered analysis to detect potential manipulation.</p>
628
+
629
+ <section class="upload-section" aria-labelledby="upload-heading">
630
+ <h2 id="upload-heading" class="visually-hidden">Video Upload</h2>
631
+ <form action="{{ url_for('detect') }}" method="post" enctype="multipart/form-data" class="feature-card"
632
+ id="upload-form">
633
+ <div class="upload-container">
634
+ <div class="file-input-wrapper">
635
+ <input type="file" name="video" accept="video/*" required id="video-input"
636
+ aria-label="Choose a video file to analyze">
637
+ <label for="video-input" class="file-label">Choose Video</label>
638
+ </div>
639
+ <div id="video-preview-container" style="display: none;" aria-live="polite">
640
+ <video id="video-preview" controls style="max-width: 100%; border-radius: 8px;">
641
+ Your browser does not support the video tag.
642
+ </video>
643
+ </div>
644
+ <div class="loading-container" style="display: none;">
645
+ <div class="loading-spinner"></div>
646
+ <p class="loading-text">Analyzing video...</p>
647
+ </div>
648
+ <div id="error-message" class="error-message" role="alert" style="display: none;"></div>
649
+ <button type="submit" class="cta-button" id="analyze-btn">Analyze Video</button>
650
+ </div>
651
+ <p class="upload-info">Supported formats: MP4, AVI, MOV (Max size: 100MB)</p>
652
+ </form>
653
+ </section>
654
+
655
+ <div id="results" style="display: none;" role="region" aria-label="Analysis Results">
656
+ <div class="result-container">
657
+ <h2 class="result-heading">Analysis Result</h2>
658
+ <div class="result-content">
659
+ <div class="result-text-container">
660
+ <p id="result-text" class="result-text" role="status" aria-live="polite"></p>
661
+ <p id="confidence-text" class="confidence-text" aria-live="polite"></p>
662
+ </div>
663
+ </div>
664
+ </div>
665
+
666
+ <div class="pie-chart-section feature-card">
667
+ <h3>Result Distribution</h3>
668
+ <div class="pie-chart-container">
669
+ <canvas id="resultPieChart" width="350" height="350"></canvas>
670
+ </div>
671
+
672
+ <div class="pie-chart-legend">
673
+ <div class="legend-item">
674
+ <span class="legend-color real-color"></span>
675
+ <span class="legend-text">Real</span>
676
+ </div>
677
+ <div class="legend-item">
678
+ <span class="legend-color fake-color"></span>
679
+ <span class="legend-text">Fake</span>
680
+ </div>
681
+ </div>
682
+ </div>
683
+
684
+ <div id="heatmap-section" class="heatmap-section feature-card" style="display: none;">
685
+ <h3 class="result-heading" style="font-size: 1.5rem;">AI Focus Analysis (Heatmap)</h3>
686
+ <div class="heatmap-container">
687
+ <div class="heatmap-image-wrapper">
688
+ <img id="heatmap-image" src="" alt="AI Focus Heatmap" class="heatmap-image">
689
+ </div>
690
+ <div class="heatmap-legend">
691
+ <div class="heatmap-legend-item">
692
+ <span style="color: var(--primary-color); font-weight: 600;">Attention Scale:</span>
693
+ </div>
694
+ <div class="heatmap-legend-item">
695
+ <span style="color: #4cd6b3; font-size: 0.8rem;">Low</span>
696
+ <div class="heatmap-color-scale"></div>
697
+ <span style="color: #ff4d4d; font-size: 0.8rem;">High</span>
698
+ </div>
699
+ <p style="color: var(--text-light); font-size: 0.85rem; margin-top: 0.5rem;">
700
+ Red areas indicate regions where the AI model detected signs of manipulation.
701
+ </p>
702
+ </div>
703
+ </div>
704
+ <p class="heatmap-info-text">
705
+ The heatmap above visualizes the confidence score of the AI model across the video frames.
706
+ Red areas indicate frames with high probability of manipulation, while blue areas indicate real
707
+ content.
708
+ </p>
709
+ </div>
710
+
711
+ <div class="analysis-details feature-card" id="details-section">
712
+ <h3>Analysis Details</h3>
713
+ <div class="details-grid">
714
+ <div class="detail-item">
715
+ <span class="detail-label">FRAMES ANALYZED</span>
716
+ <span id="frames-analyzed" class="detail-value" aria-live="polite">0</span>
717
+ </div>
718
+ <div class="detail-item">
719
+ <span class="detail-label">PROCESSING TIME</span>
720
+ <span id="processing-time" class="detail-value" aria-live="polite">0s</span>
721
+ </div>
722
+ <div class="detail-item">
723
+ <span class="detail-label">MODEL CONFIDENCE</span>
724
+ <span id="model-confidence" class="detail-value" aria-live="polite">0%</span>
725
+ </div>
726
+ </div>
727
+ </div>
728
+
729
+ <div id="frames-section" class="feature-card" style="display: none;">
730
+ <h3 style="color: var(--primary-color); text-align: center; margin-bottom: 0.5rem;">Analyzed Frames
731
+ </h3>
732
+ <p style="color: var(--text-light); text-align: center; margin-bottom: 1.5rem; font-size: 0.9rem;">
733
+ Key frames extracted and analyzed for manipulation patterns
734
+ </p>
735
+ <div id="frames-grid" class="frames-container">
736
+ </div>
737
+ </div>
738
+ </div>
739
+ </main>
740
+
741
+ <footer class="footer" role="contentinfo">
742
+ <div class="footer-content">
743
+ <div class="footer-section">
744
+ <h3>About Us</h3>
745
+ <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p>
746
+ </div>
747
+ <div class="footer-section">
748
+ <h3>Contact</h3>
749
+ <a href="mailto:contact@deepfakedetect.ai" class="footer-link">contact@deepfakedetect.ai</a>
750
+ <a href="https://github.com/deepfake-detect" target="_blank" rel="noopener noreferrer"
751
+ class="footer-link">GitHub</a>
752
+ </div>
753
+ <div class="footer-section">
754
+ <h3>Legal</h3>
755
+ <a href="{{ url_for('privacy') }}" class="footer-link">Privacy Policy</a>
756
+ <a href="{{ url_for('terms') }}" class="footer-link">Terms of Service</a>
757
+ <p>© 2025 DeepFake Detection</p>
758
+ </div>
759
+ </div>
760
+ </footer>
761
+ </div>
762
+
763
+ <script>
764
+ document.addEventListener('DOMContentLoaded', () => {
765
+ const hamburgerBtn = document.getElementById('hamburger-btn');
766
+ const navLinks = document.getElementById('nav-links');
767
+
768
+ hamburgerBtn.addEventListener('click', () => {
769
+ navLinks.classList.toggle('active');
770
+ });
771
+
772
+ document.querySelectorAll('.nav-link').forEach(link => {
773
+ link.addEventListener('click', () => {
774
+ navLinks.classList.remove('active');
775
+ });
776
+ });
777
+ });
778
+ </script>
779
+
780
+ <script>
781
+ document.addEventListener('DOMContentLoaded', function () {
782
+ const videoInput = document.getElementById('video-input');
783
+ const videoPreview = document.getElementById('video-preview');
784
+ const videoPreviewContainer = document.getElementById('video-preview-container');
785
+ const uploadForm = document.getElementById('upload-form');
786
+ const analyzeBtn = document.getElementById('analyze-btn');
787
+ const loadingContainer = document.querySelector('.loading-container');
788
+ const errorMessage = document.getElementById('error-message');
789
+
790
+ videoInput?.addEventListener('change', function () {
791
+ errorMessage.style.display = 'none';
792
+ if (this.files && this.files[0]) {
793
+ const file = this.files[0];
794
+ if (file.size > 100 * 1024 * 1024) {
795
+ errorMessage.textContent = 'File size exceeds 100MB limit';
796
+ errorMessage.style.display = 'block';
797
+ this.value = '';
798
+ videoPreviewContainer.style.display = 'none';
799
+ return;
800
+ }
801
+
802
+ const fileURL = URL.createObjectURL(file);
803
+ videoPreview.src = fileURL;
804
+ videoPreviewContainer.style.display = 'block';
805
+
806
+ const fileLabel = document.querySelector('.file-label');
807
+ fileLabel.textContent = file.name;
808
+ } else {
809
+ videoPreviewContainer.style.display = 'none';
810
+ videoPreview.src = '';
811
+ }
812
+ });
813
+
814
+ uploadForm?.addEventListener('submit', function (e) {
815
+ if (!videoInput.files || !videoInput.files[0]) {
816
+ e.preventDefault();
817
+ errorMessage.textContent = 'Please select a video file';
818
+ errorMessage.style.display = 'block';
819
+ return;
820
+ }
821
+
822
+ loadingContainer.style.display = 'flex';
823
+ analyzeBtn.disabled = true;
824
+ errorMessage.style.display = 'none';
825
+ });
826
+
827
+ const hasValidData = (
828
+ typeof window.data !== 'undefined' &&
829
+ window.data !== null &&
830
+ window.data !== '' &&
831
+ window.data !== 'null'
832
+ );
833
+
834
+ if (hasValidData) {
835
+ try {
836
+ const parsedData = typeof window.data === 'string' ? JSON.parse(window.data) : window.data;
837
+
838
+ if (!parsedData.output || !parsedData.confidence || !parsedData.processing_time) {
839
+ return;
840
+ }
841
+
842
+ const resultsDiv = document.getElementById('results');
843
+ const resultText = document.getElementById('result-text');
844
+ const confidenceText = document.getElementById('confidence-text');
845
+ const modelConfidence = document.getElementById('model-confidence');
846
+ const processingTime = document.getElementById('processing-time');
847
+ const pieChartCanvas = document.getElementById('resultPieChart');
848
+ const realColor = document.querySelector('.real-color');
849
+ const fakeColor = document.querySelector('.fake-color');
850
+
851
+ loadingContainer.style.display = 'none';
852
+ analyzeBtn.disabled = false;
853
+ resultsDiv.style.display = 'block';
854
+
855
+ resultText.textContent = parsedData.output;
856
+ resultText.className = `result-text ${parsedData.output.toLowerCase()}`;
857
+ confidenceText.textContent = `Confidence: ${parsedData.confidence.toFixed(2)}%`;
858
+
859
+ modelConfidence.textContent = `${parsedData.confidence.toFixed(2)}%`;
860
+ processingTime.textContent = `${parsedData.processing_time}s`;
861
+
862
+ const framesAnalyzed = document.getElementById('frames-analyzed');
863
+ if (framesAnalyzed) {
864
+ framesAnalyzed.textContent = parsedData.frames_analyzed || 0;
865
+ }
866
+
867
+ const heatmapSection = document.getElementById('heatmap-section');
868
+ const heatmapImage = document.getElementById('heatmap-image');
869
+
870
+ if (parsedData.heatmap_url) {
871
+ heatmapImage.src = '/' + parsedData.heatmap_url + '?t=' + new Date().getTime();
872
+ heatmapSection.style.display = 'block';
873
+ } else {
874
+ heatmapSection.style.display = 'none';
875
+ }
876
+
877
+ const framesSection = document.getElementById('frames-section');
878
+ const framesGrid = document.getElementById('frames-grid');
879
+
880
+ if (parsedData.frame_urls && parsedData.frame_urls.length > 0) {
881
+ framesGrid.innerHTML = '';
882
+
883
+ parsedData.frame_urls.forEach((frameUrl, index) => {
884
+ const frameItem = document.createElement('div');
885
+ frameItem.className = 'frame-item';
886
+ frameItem.innerHTML = `
887
+ <img src="/${frameUrl}?t=${new Date().getTime()}" alt="Frame ${index + 1}" loading="lazy">
888
+ <div class="frame-info">
889
+ <p class="frame-number">Frame ${index + 1}</p>
890
+ </div>
891
+ `;
892
+ framesGrid.appendChild(frameItem);
893
+ });
894
+
895
+ framesSection.style.display = 'block';
896
+ } else {
897
+ framesSection.style.display = 'none';
898
+ }
899
+
900
+ const successMessage = document.createElement('div');
901
+ successMessage.className = 'success-message';
902
+ successMessage.innerHTML = `
903
+ <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, rgba(100, 255, 218, 0.1) 0%, rgba(26, 26, 26, 0.8) 100%); border-radius: 12px; margin: 20px 0; border: 1px solid rgba(100, 255, 218, 0.2);">
904
+ <h3 style="color: #64ffda; margin-bottom: 10px; font-size: 1.3rem;">✅ Analysis Complete!</h3>
905
+ <p style="color: #8892b0; margin: 0; font-size: 1rem;">Video processed successfully using advanced AI deep learning technology.</p>
906
+ </div>
907
+ `;
908
+ resultsDiv.insertBefore(successMessage, resultsDiv.firstChild);
909
+
910
+ const ctx = pieChartCanvas.getContext('2d');
911
+ const realPercentage = parsedData.output.toLowerCase() === 'real' ? parsedData.confidence : (100 - parsedData.confidence);
912
+ const fakePercentage = parsedData.output.toLowerCase() === 'fake' ? parsedData.confidence : (100 - parsedData.confidence);
913
+
914
+ if (window.resultChart) {
915
+ window.resultChart.destroy();
916
+ }
917
+
918
+ const chartData = [realPercentage, fakePercentage];
919
+ if (chartData.some(val => isNaN(val) || val < 0)) {
920
+ pieChartCanvas.style.display = 'none';
921
+ const fallbackDiv = document.createElement('div');
922
+ fallbackDiv.innerHTML = `
923
+ <div style="text-align: center; padding: 40px; color: #8892b0;">
924
+ <h4 style="color: #64ffda; margin-bottom: 20px;">Result Distribution</h4>
925
+ <div style="font-size: 2rem; font-weight: bold; color: ${parsedData.output.toLowerCase() === 'real' ? '#27ae60' : '#e74c3c'};">
926
+ ${parsedData.output}
927
+ </div>
928
+ <div style="font-size: 1.2rem; margin-top: 10px;">
929
+ Confidence: ${parsedData.confidence.toFixed(1)}%
930
+ </div>
931
+ </div>
932
+ `;
933
+ pieChartCanvas.parentNode.appendChild(fallbackDiv);
934
+ return;
935
+ }
936
+
937
+ try {
938
+ window.resultChart = new Chart(ctx, {
939
+ type: 'doughnut',
940
+ data: {
941
+ labels: ['Real', 'Fake'],
942
+ datasets: [{
943
+ data: chartData,
944
+ backgroundColor: ['#27ae60', '#e74c3c'],
945
+ borderWidth: 4,
946
+ borderColor: '#1a1a1a',
947
+ hoverBorderWidth: 6,
948
+ hoverBorderColor: '#64ffda'
949
+ }]
950
+ },
951
+ options: {
952
+ responsive: true,
953
+ maintainAspectRatio: false,
954
+ cutout: '65%',
955
+ plugins: {
956
+ legend: { display: false },
957
+ tooltip: {
958
+ enabled: true,
959
+ backgroundColor: 'rgba(26, 26, 26, 0.95)',
960
+ titleColor: '#64ffda',
961
+ bodyColor: '#8892b0',
962
+ borderColor: '#64ffda',
963
+ borderWidth: 2,
964
+ cornerRadius: 8,
965
+ displayColors: false,
966
+ callbacks: {
967
+ title: function (tooltipItems) { return tooltipItems[0].label; },
968
+ label: function (context) { return context.parsed.toFixed(1) + '%'; }
969
+ }
970
+ }
971
+ },
972
+ animation: {
973
+ animateRotate: true,
974
+ duration: 1500,
975
+ easing: 'easeInOutQuart'
976
+ },
977
+ elements: { arc: { borderWidth: 4 } }
978
+ }
979
+ });
980
+
981
+ } catch (chartError) {
982
+ pieChartCanvas.style.display = 'none';
983
+ const fallbackDiv = document.createElement('div');
984
+ fallbackDiv.innerHTML = `
985
+ <div style="text-align: center; padding: 40px; color: #8892b0;">
986
+ <h4 style="color: #64ffda; margin-bottom: 20px;">Result Distribution</h4>
987
+ <div style="font-size: 2rem; font-weight: bold; color: ${parsedData.output.toLowerCase() === 'real' ? '#27ae60' : '#e74c3c'};">
988
+ ${parsedData.output}
989
+ </div>
990
+ <div style="font-size: 1.2rem; margin-top: 10px;">
991
+ Confidence: ${parsedData.confidence.toFixed(1)}%
992
+ </div>
993
+ </div>
994
+ `;
995
+ pieChartCanvas.parentNode.appendChild(fallbackDiv);
996
+ }
997
+
998
+ if (realColor && fakeColor) {
999
+ realColor.style.background = 'linear-gradient(135deg, #27ae60, #2ecc71)';
1000
+ fakeColor.style.background = 'linear-gradient(135deg, #e74c3c, #c0392b)';
1001
+ }
1002
+
1003
+ const legendTexts = document.querySelectorAll('.legend-text');
1004
+ if (legendTexts.length >= 2) {
1005
+ legendTexts[0].textContent = `Real (${realPercentage.toFixed(1)}%)`;
1006
+ legendTexts[1].textContent = `Fake (${fakePercentage.toFixed(1)}%)`;
1007
+ }
1008
+
1009
+ } catch (error) {
1010
+ errorMessage.textContent = 'An error occurred while processing the results';
1011
+ errorMessage.style.display = 'block';
1012
+ }
1013
+ }
1014
+ });
1015
+ </script>
1016
+ </body>
1017
+
1018
+ </html>
templates/history.html ADDED
@@ -0,0 +1,371 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <meta name="theme-color" content="#0a192f">
7
+ <title>Detection History - DeepFake Detection</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
10
+ <style>
11
+ :root {
12
+ --primary-color: #64ffda;
13
+ --primary-dark: #4cd6b3;
14
+ --bg-dark: #1a1a1a;
15
+ --bg-darker: #111d40;
16
+ --text-light: #8892b0;
17
+ --border-color: rgba(100, 255, 218, 0.1);
18
+ }
19
+
20
+ /* Navbar Styling */
21
+ .navbar {
22
+ background: var(--bg-dark);
23
+ padding: 1rem 2rem;
24
+ height: 70px;
25
+ display: flex;
26
+ justify-content: space-between;
27
+ align-items: center;
28
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
29
+ position: sticky;
30
+ top: 0;
31
+ z-index: 1000;
32
+ }
33
+
34
+ .navbar-brand {
35
+ color: var(--primary-color);
36
+ font-size: 1.5rem;
37
+ font-weight: bold;
38
+ text-decoration: none;
39
+ transition: color 0.3s ease;
40
+ }
41
+
42
+ .navbar-brand:hover {
43
+ color: var(--primary-dark);
44
+ }
45
+
46
+ /* Hamburger Button */
47
+ .hamburger {
48
+ display: none;
49
+ background: none;
50
+ border: none;
51
+ color: #64ffda;
52
+ font-size: 2rem;
53
+ cursor: pointer;
54
+ padding: 0;
55
+ }
56
+
57
+ .navbar-nav {
58
+ display: flex;
59
+ gap: 1rem;
60
+ align-items: center;
61
+ transition: all 0.3s ease;
62
+ }
63
+
64
+ .nav-link {
65
+ color: #fff;
66
+ text-decoration: none;
67
+ padding: 0.5rem 1rem;
68
+ border-radius: 4px;
69
+ transition: all 0.3s ease;
70
+ }
71
+
72
+ .nav-link:hover, .nav-link.active {
73
+ background: rgba(100, 255, 218, 0.1);
74
+ color: var(--primary-color);
75
+ }
76
+
77
+ /* History Table Specific Styles */
78
+ .history-container {
79
+ background: rgba(17, 34, 64, 0.3);
80
+ border: 1px solid var(--border-color);
81
+ border-radius: 12px;
82
+ padding: 2rem;
83
+ margin: 2rem auto;
84
+ max-width: 1000px;
85
+ overflow-x: auto;
86
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
87
+ }
88
+
89
+ .history-table {
90
+ width: 100%;
91
+ border-collapse: collapse;
92
+ text-align: left;
93
+ margin-top: 1rem;
94
+ }
95
+
96
+ .history-table th {
97
+ color: var(--primary-color);
98
+ padding: 1.2rem 1rem;
99
+ border-bottom: 2px solid var(--border-color);
100
+ font-weight: 600;
101
+ letter-spacing: 0.5px;
102
+ text-transform: uppercase;
103
+ font-size: 0.9rem;
104
+ }
105
+
106
+ .history-table td {
107
+ color: var(--text-light);
108
+ padding: 1.2rem 1rem;
109
+ border-bottom: 1px solid rgba(100, 255, 218, 0.05);
110
+ vertical-align: middle;
111
+ }
112
+
113
+ .history-table tbody tr {
114
+ transition: all 0.2s ease;
115
+ }
116
+
117
+ .history-table tbody tr:hover {
118
+ background: rgba(100, 255, 218, 0.05);
119
+ transform: scale(1.01);
120
+ }
121
+
122
+ .history-table tr:last-child td {
123
+ border-bottom: none;
124
+ }
125
+
126
+ .badge {
127
+ padding: 0.4rem 0.8rem;
128
+ border-radius: 20px;
129
+ font-size: 0.85rem;
130
+ font-weight: bold;
131
+ display: inline-block;
132
+ }
133
+
134
+ .badge-video {
135
+ background: rgba(52, 152, 219, 0.2);
136
+ color: #3498db;
137
+ border: 1px solid #3498db;
138
+ }
139
+
140
+ .badge-image {
141
+ background: rgba(155, 89, 182, 0.2);
142
+ color: #9b59b6;
143
+ border: 1px solid #9b59b6;
144
+ }
145
+
146
+ .result-fake {
147
+ color: #ff4d4d;
148
+ font-weight: bold;
149
+ text-shadow: 0 0 10px rgba(255, 77, 77, 0.3);
150
+ }
151
+
152
+ .result-real {
153
+ color: #4dff4d;
154
+ font-weight: bold;
155
+ text-shadow: 0 0 10px rgba(77, 255, 77, 0.3);
156
+ }
157
+
158
+ .empty-state {
159
+ text-align: center;
160
+ padding: 3rem;
161
+ color: var(--text-light);
162
+ }
163
+
164
+ .empty-state p {
165
+ font-size: 1.2rem;
166
+ margin-bottom: 1.5rem;
167
+ }
168
+
169
+ .footer {
170
+ margin-top: auto;
171
+ padding: 3rem 0;
172
+ background: var(--bg-darker);
173
+ border-top: 1px solid var(--border-color);
174
+ }
175
+ .footer-content {
176
+ max-width: 1200px;
177
+ margin: 0 auto;
178
+ padding: 0 2rem;
179
+ display: flex;
180
+ justify-content: space-between;
181
+ gap: 2rem;
182
+ }
183
+ .footer-section h3 { color: var(--primary-color); margin-bottom: 1rem; }
184
+ .footer-link { color: var(--text-light); text-decoration: none; display: block; margin: 0.5rem 0; transition: color 0.3s ease; }
185
+ .footer-link:hover { color: var(--primary-color); }
186
+
187
+ /* --- BULLETPROOF MOBILE TABLE FIXES --- */
188
+ @media (max-width: 768px) {
189
+ body, html {
190
+ overflow-x: hidden; /* STOPS the entire screen from swiping sideways */
191
+ width: 100%;
192
+ -webkit-tap-highlight-color: transparent;
193
+ -webkit-touch-callout: none;
194
+ user-select: none;
195
+ }
196
+ .content {
197
+ padding: 1rem 0; /* Remove side padding so table touches edges */
198
+ width: 100%;
199
+ box-sizing: border-box;
200
+ }
201
+ .navbar {
202
+ padding: 1rem 1.5rem;
203
+ }
204
+ .hamburger {
205
+ display: block;
206
+ }
207
+ .navbar-nav {
208
+ display: flex;
209
+ flex-direction: column;
210
+ position: absolute;
211
+ top: 70px;
212
+ left: 0;
213
+ width: 100%;
214
+ background: rgba(17, 29, 64, 0.98);
215
+ padding: 0;
216
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
217
+ max-height: 0;
218
+ overflow: hidden;
219
+ opacity: 0;
220
+ transition: all 0.3s ease;
221
+ }
222
+ .navbar-nav.active {
223
+ max-height: 500px;
224
+ padding: 1rem 0;
225
+ opacity: 1;
226
+ }
227
+ .nav-link {
228
+ width: 100%;
229
+ text-align: center;
230
+ padding: 1.2rem;
231
+ border-radius: 0;
232
+ }
233
+
234
+ /* --- THE SCROLL FIX --- */
235
+ .history-container {
236
+ width: 100%;
237
+ margin: 1rem 0;
238
+ padding: 0;
239
+ border-radius: 0;
240
+ border-left: none;
241
+ border-right: none;
242
+ overflow-x: auto; /* Allow ONLY the table to scroll */
243
+ -webkit-overflow-scrolling: touch;
244
+ }
245
+ .history-table {
246
+ width: max-content; /* Forces table to ignore screen width limits */
247
+ min-width: 100%;
248
+ margin: 0;
249
+ }
250
+ .history-table th, .history-table td {
251
+ white-space: nowrap !important;
252
+ padding: 1rem;
253
+ }
254
+
255
+ /* --- THE FILENAME TRUNCATION FIX --- */
256
+ .history-table td:nth-child(2) {
257
+ max-width: 150px; /* Limits filename width */
258
+ overflow: hidden;
259
+ text-overflow: ellipsis; /* Adds '...' to the end of long names */
260
+ }
261
+
262
+ .footer-content {
263
+ flex-direction: column;
264
+ text-align: center;
265
+ }
266
+ }
267
+ </style>
268
+ </head>
269
+
270
+ <body>
271
+ <div id="root">
272
+ <nav class="navbar">
273
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a>
274
+
275
+ <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu">
276
+
277
+ </button>
278
+
279
+ <div class="navbar-nav" id="nav-links">
280
+ {% if current_user.is_authenticated %}
281
+ <a href="{{ url_for('detect') }}" class="nav-link">Upload Video</a>
282
+ <a href="{{ url_for('image_detect') }}" class="nav-link">Detect Image</a>
283
+ <a href="{{ url_for('history') }}" class="nav-link active">History</a>
284
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
285
+ {% endif %}
286
+ </div>
287
+ </nav>
288
+
289
+ <main class="content" role="main">
290
+ <h1 class="heading" style="padding: 0 1rem;">Detection History</h1>
291
+ <p class="para" style="padding: 0 1rem;">Review your past video and image analysis logs.</p>
292
+
293
+ <div class="history-container">
294
+ {% if logs %}
295
+ <table class="history-table">
296
+ <thead>
297
+ <tr>
298
+ <th>Date & Time</th>
299
+ <th>File Name</th>
300
+ <th>Media Type</th>
301
+ <th>Result</th>
302
+ <th>Confidence</th>
303
+ </tr>
304
+ </thead>
305
+ <tbody>
306
+ {% for log in logs %}
307
+ <tr>
308
+ <td>{{ log.timestamp.strftime('%Y-%m-%d %H:%M') }}</td>
309
+ <td style="color: #fff;" title="{{ log.filename }}">{{ log.filename }}</td>
310
+ <td>
311
+ <span class="badge {% if log.media_type == 'Video' %}badge-video{% else %}badge-image{% endif %}">
312
+ {{ log.media_type }}
313
+ </span>
314
+ </td>
315
+ <td class="{% if log.prediction == 'FAKE' %}result-fake{% else %}result-real{% endif %}">
316
+ {{ log.prediction }}
317
+ </td>
318
+ <td>{{ "%.2f"|format(log.confidence) }}%</td>
319
+ </tr>
320
+ {% endfor %}
321
+ </tbody>
322
+ </table>
323
+ {% else %}
324
+ <div class="empty-state">
325
+ <p>You haven't scanned any files yet.</p>
326
+ <a href="{{ url_for('detect') }}" class="cta-button" style="display: inline-block; padding: 0.8rem 1.5rem; background: #64ffda; color: #1a1a1a; text-decoration: none; border-radius: 4px; font-weight: bold;">Scan a Video Now</a>
327
+ </div>
328
+ {% endif %}
329
+ </div>
330
+ </main>
331
+
332
+ <footer class="footer">
333
+ <div class="footer-content">
334
+ <div class="footer-section">
335
+ <h3>About Us</h3>
336
+ <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p>
337
+ </div>
338
+ <div class="footer-section">
339
+ <h3>Contact</h3>
340
+ <a href="mailto:contact@deepfakedetect.ai" class="footer-link">contact@deepfakedetect.ai</a>
341
+ <a href="https://github.com/deepfake-detect" class="footer-link">GitHub</a>
342
+ </div>
343
+ <div class="footer-section">
344
+ <h3>Legal</h3>
345
+ <a href="{{ url_for('privacy') }}" class="footer-link">Privacy Policy</a>
346
+ <a href="{{ url_for('terms') }}" class="footer-link">Terms of Service</a>
347
+ <p>© 2025 DeepFake Detection</p>
348
+ </div>
349
+ </div>
350
+ </footer>
351
+ </div>
352
+
353
+ <script>
354
+ // Hamburger Menu Script
355
+ document.addEventListener('DOMContentLoaded', () => {
356
+ const hamburgerBtn = document.getElementById('hamburger-btn');
357
+ const navLinks = document.getElementById('nav-links');
358
+
359
+ hamburgerBtn.addEventListener('click', () => {
360
+ navLinks.classList.toggle('active');
361
+ });
362
+
363
+ document.querySelectorAll('.nav-link').forEach(link => {
364
+ link.addEventListener('click', () => {
365
+ navLinks.classList.remove('active');
366
+ });
367
+ });
368
+ });
369
+ </script>
370
+ </body>
371
+ </html>
templates/home.html ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>DeepFake Detection</title>
8
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
9
+ <style>
10
+ * {
11
+ box-sizing: border-box;
12
+ margin: 0;
13
+ padding: 0;
14
+ }
15
+
16
+ html {
17
+ scroll-behavior: smooth;
18
+ scroll-padding-top: 80px;
19
+ }
20
+
21
+ .navbar {
22
+ background: rgba(26, 26, 26, 0.95);
23
+ padding: 1rem 2rem;
24
+ height: 70px;
25
+ box-sizing: border-box;
26
+ display: flex;
27
+ justify-content: space-between;
28
+ align-items: center;
29
+ box-shadow: 0 2px 20px rgba(0, 0, 0, 0.2);
30
+ position: fixed;
31
+ width: 100%;
32
+ left: 0;
33
+ top: 0;
34
+ z-index: 1000;
35
+ backdrop-filter: blur(10px);
36
+ }
37
+
38
+ .navbar-brand {
39
+ color: #64ffda;
40
+ font-size: 1.6rem;
41
+ font-weight: bold;
42
+ text-decoration: none;
43
+ text-transform: uppercase;
44
+ letter-spacing: 1px;
45
+ transition: all 0.3s ease;
46
+ }
47
+
48
+ /* Hamburger Button (Hidden on PC) */
49
+ .hamburger {
50
+ display: none;
51
+ background: none;
52
+ border: none;
53
+ color: #64ffda;
54
+ font-size: 2rem;
55
+ cursor: pointer;
56
+ padding: 0;
57
+ }
58
+
59
+ .navbar-nav {
60
+ display: flex;
61
+ gap: 1rem;
62
+ align-items: center;
63
+ transition: all 0.3s ease;
64
+ }
65
+
66
+ .nav-link {
67
+ color: #fff;
68
+ text-decoration: none;
69
+ padding: 0.6rem 1.2rem;
70
+ border-radius: 6px;
71
+ transition: all 0.3s ease;
72
+ position: relative;
73
+ font-weight: 500;
74
+ }
75
+
76
+ .nav-link:hover {
77
+ background: #2a2a2a;
78
+ }
79
+
80
+ .nav-link.highlight {
81
+ background: #64ffda;
82
+ color: #1a1a1a;
83
+ }
84
+
85
+ .nav-link.highlight:hover {
86
+ background: #4cd6b3;
87
+ }
88
+
89
+ .hero {
90
+ text-align: center;
91
+ padding: 5rem 2rem;
92
+ margin-top: -1rem;
93
+ background: linear-gradient(135deg, #111d40 0%, #0a0d30 100%);
94
+ color: white;
95
+ position: relative;
96
+ overflow: hidden;
97
+ }
98
+
99
+ .hero h1 {
100
+ font-size: 3.5rem;
101
+ margin-bottom: 1.5rem;
102
+ color: #64ffda;
103
+ text-shadow: 0 2px 10px rgba(100, 255, 218, 0.3);
104
+ animation: fadeInUp 0.8s ease-out;
105
+ }
106
+
107
+ .hero p {
108
+ font-size: 1.2rem;
109
+ color: #8892b0;
110
+ max-width: 800px;
111
+ margin: 0 auto 2rem;
112
+ }
113
+
114
+ .hero-buttons {
115
+ display: flex;
116
+ gap: 1rem;
117
+ justify-content: center;
118
+ flex-wrap: wrap;
119
+ }
120
+
121
+ .cta-button {
122
+ background: #64ffda;
123
+ color: #1a1a1a;
124
+ padding: 1rem 2rem;
125
+ border-radius: 8px;
126
+ text-decoration: none;
127
+ font-weight: bold;
128
+ transition: all 0.3s ease;
129
+ text-transform: uppercase;
130
+ letter-spacing: 1px;
131
+ }
132
+
133
+ .cta-button:hover {
134
+ background: #4cd6b3;
135
+ transform: translateY(-2px);
136
+ box-shadow: 0 5px 15px rgba(100, 255, 218, 0.3);
137
+ }
138
+
139
+ .cta-button.secondary {
140
+ background: transparent;
141
+ color: #64ffda;
142
+ border: 2px solid #64ffda;
143
+ }
144
+
145
+ .cta-button.secondary:hover {
146
+ background: #64ffda;
147
+ color: #1a1a1a;
148
+ }
149
+
150
+ .features {
151
+ padding: 6rem 2rem;
152
+ background: linear-gradient(180deg, #1a1a1a 0%, #111111 100%);
153
+ position: relative;
154
+ }
155
+
156
+ .container {
157
+ max-width: 1200px;
158
+ margin: 0 auto;
159
+ }
160
+
161
+ .features h2 {
162
+ text-align: center;
163
+ color: #64ffda;
164
+ margin-bottom: 3rem;
165
+ font-size: 2.5rem;
166
+ text-transform: uppercase;
167
+ letter-spacing: 2px;
168
+ text-shadow: 0 2px 10px rgba(100, 255, 218, 0.2);
169
+ position: relative;
170
+ }
171
+
172
+ .features h2::after {
173
+ content: '';
174
+ position: absolute;
175
+ bottom: -10px;
176
+ left: 50%;
177
+ transform: translateX(-50%);
178
+ width: 60px;
179
+ height: 3px;
180
+ background: #64ffda;
181
+ border-radius: 2px;
182
+ }
183
+
184
+ .features-grid {
185
+ display: grid;
186
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
187
+ gap: 2rem;
188
+ max-width: 1200px;
189
+ margin: 0 auto;
190
+ }
191
+
192
+ .feature-card {
193
+ background: rgba(42, 42, 42, 0.8);
194
+ padding: 2.5rem;
195
+ border-radius: 12px;
196
+ text-align: center;
197
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
198
+ border: 1px solid rgba(100, 255, 218, 0.1);
199
+ backdrop-filter: blur(10px);
200
+ opacity: 0;
201
+ transform: translateY(20px);
202
+ animation: fadeInUp 0.6s ease-out forwards;
203
+ }
204
+
205
+ .feature-card:hover {
206
+ transform: translateY(-5px);
207
+ border-color: rgba(100, 255, 218, 0.3);
208
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
209
+ }
210
+
211
+ .feature-icon {
212
+ font-size: 3rem;
213
+ margin-bottom: 1rem;
214
+ }
215
+
216
+ .feature-card h3 {
217
+ color: #64ffda;
218
+ margin-bottom: 1.2rem;
219
+ font-size: 1.5rem;
220
+ text-transform: uppercase;
221
+ letter-spacing: 1px;
222
+ }
223
+
224
+ .feature-card p {
225
+ color: #8892b0;
226
+ line-height: 1.6;
227
+ margin-bottom: 1.5rem;
228
+ }
229
+
230
+ .feature-link {
231
+ display: inline-block;
232
+ background: rgba(100, 255, 218, 0.1);
233
+ color: #64ffda;
234
+ padding: 0.75rem 1.5rem;
235
+ border-radius: 6px;
236
+ text-decoration: none;
237
+ border: 1px solid rgba(100, 255, 218, 0.2);
238
+ transition: all 0.3s ease;
239
+ }
240
+
241
+ .feature-link:hover {
242
+ background: rgba(100, 255, 218, 0.2);
243
+ transform: translateY(-2px);
244
+ }
245
+
246
+ @keyframes fadeInUp {
247
+ from {
248
+ opacity: 0;
249
+ transform: translateY(20px);
250
+ }
251
+ to {
252
+ opacity: 1;
253
+ transform: translateY(0);
254
+ }
255
+ }
256
+
257
+ body {
258
+ margin: 0;
259
+ padding-top: 70px;
260
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
261
+ background: #1a1a1a;
262
+ min-height: 100vh;
263
+ }
264
+
265
+ .about,
266
+ .contact {
267
+ padding: 6rem 2rem;
268
+ position: relative;
269
+ color: white;
270
+ text-align: center;
271
+ }
272
+
273
+ .about {
274
+ background: linear-gradient(45deg, #111d40 0%, #131a61 100%);
275
+ }
276
+
277
+ .contact {
278
+ background: linear-gradient(135deg, #111d40 0%, #0a0d30 100%);
279
+ }
280
+
281
+ .about h2,
282
+ .contact h2 {
283
+ color: #64ffda;
284
+ margin-bottom: 2.5rem;
285
+ font-size: 2.8rem;
286
+ text-transform: uppercase;
287
+ letter-spacing: 2px;
288
+ text-shadow: 0 2px 10px rgba(100, 255, 218, 0.2);
289
+ position: relative;
290
+ display: inline-block;
291
+ }
292
+
293
+ .about h2::after,
294
+ .contact h2::after {
295
+ content: '';
296
+ position: absolute;
297
+ bottom: -10px;
298
+ left: 50%;
299
+ transform: translateX(-50%);
300
+ width: 60px;
301
+ height: 3px;
302
+ background: #64ffda;
303
+ border-radius: 2px;
304
+ }
305
+
306
+ .about p,
307
+ .contact p {
308
+ color: #8892b0;
309
+ max-width: 800px;
310
+ margin: 0 auto 2rem;
311
+ line-height: 1.6;
312
+ }
313
+
314
+ .contact-form {
315
+ max-width: 600px;
316
+ margin: 0 auto;
317
+ text-align: left;
318
+ }
319
+
320
+ .contact-form input,
321
+ .contact-form textarea {
322
+ width: 100%;
323
+ padding: 1rem;
324
+ margin-bottom: 1.2rem;
325
+ border: 1px solid rgba(100, 255, 218, 0.2);
326
+ border-radius: 8px;
327
+ color: white;
328
+ transition: all 0.3s ease;
329
+ backdrop-filter: blur(5px);
330
+ background: rgba(26, 26, 26, 0.5);
331
+ }
332
+
333
+ .contact-form input:focus,
334
+ .contact-form textarea:focus {
335
+ outline: none;
336
+ border-color: #64ffda;
337
+ box-shadow: 0 0 0 2px rgba(100, 255, 218, 0.2);
338
+ }
339
+
340
+ .contact-form button {
341
+ background: #64ffda;
342
+ color: #1a1a1a;
343
+ border: none;
344
+ padding: 1rem 2.5rem;
345
+ border-radius: 8px;
346
+ cursor: pointer;
347
+ font-weight: bold;
348
+ transition: all 0.3s ease;
349
+ text-transform: uppercase;
350
+ letter-spacing: 1px;
351
+ }
352
+
353
+ .contact-form button:hover {
354
+ background: #4cd6b3;
355
+ transform: translateY(-2px);
356
+ box-shadow: 0 5px 15px rgba(100, 255, 218, 0.3);
357
+ }
358
+
359
+ footer {
360
+ background: #1a1a1a;
361
+ color: #8892b0;
362
+ padding: 3rem 2rem;
363
+ text-align: center;
364
+ border-top: 1px solid rgba(42, 42, 42, 0.8);
365
+ position: relative;
366
+ }
367
+
368
+ footer a {
369
+ color: #64ffda;
370
+ text-decoration: none;
371
+ }
372
+
373
+ footer a:hover {
374
+ text-decoration: underline;
375
+ }
376
+
377
+ /* --- MOBILE HAMBURGER MENU & FIXES --- */
378
+ @media (max-width: 768px) {
379
+ body {
380
+ -webkit-tap-highlight-color: transparent;
381
+ -webkit-touch-callout: none;
382
+ user-select: none;
383
+ }
384
+ .navbar {
385
+ padding: 1rem 1.5rem;
386
+ }
387
+ .hamburger {
388
+ display: block; /* Show hamburger button */
389
+ }
390
+ .navbar-nav {
391
+ display: flex;
392
+ flex-direction: column;
393
+ position: absolute;
394
+ top: 70px; /* Push below the navbar */
395
+ left: 0;
396
+ width: 100%;
397
+ background: rgba(17, 29, 64, 0.98); /* Dark solid background */
398
+ padding: 0;
399
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
400
+
401
+ /* Hidden state */
402
+ max-height: 0;
403
+ overflow: hidden;
404
+ opacity: 0;
405
+ }
406
+ .navbar-nav.active {
407
+ /* Visible state */
408
+ max-height: 500px;
409
+ padding: 1rem 0;
410
+ opacity: 1;
411
+ }
412
+ .nav-link {
413
+ width: 100%;
414
+ text-align: center;
415
+ padding: 1.2rem;
416
+ border-radius: 0;
417
+ }
418
+ .hero h1 {
419
+ font-size: clamp(2rem, 8vw, 3rem);
420
+ }
421
+ .features-grid {
422
+ grid-template-columns: 1fr;
423
+ }
424
+ }
425
+ </style>
426
+ </head>
427
+
428
+ <body>
429
+ <nav class="navbar">
430
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">TrueVision</a>
431
+
432
+ <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu">
433
+
434
+ </button>
435
+
436
+ <div class="navbar-nav" id="nav-links">
437
+ <a href="#about" class="nav-link">About</a>
438
+ <a href="#contact" class="nav-link">Contact</a>
439
+ {% if current_user.is_authenticated %}
440
+ <a href="{{ url_for('detect') }}" class="nav-link">Detect Video</a>
441
+ <a href="{{ url_for('image_detect') }}" class="nav-link">Detect Image</a>
442
+ <a href="{{ url_for('history') }}" class="nav-link">History</a>
443
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
444
+ {% else %}
445
+ <a href="{{ url_for('login') }}" class="nav-link">Login</a>
446
+ <a href="{{ url_for('signup') }}" class="nav-link highlight">Sign Up</a>
447
+ {% endif %}
448
+ </div>
449
+ </nav>
450
+
451
+ <section class="hero">
452
+ <h1>DeepFake Detection</h1>
453
+ <p>Advanced AI-powered video analysis to detect manipulated content with high accuracy</p>
454
+ <div class="hero-buttons">
455
+ {% if current_user.is_authenticated %}
456
+ <a href="{{ url_for('detect') }}" class="cta-button">Upload Video</a>
457
+ <a href="{{ url_for('image_detect') }}" class="cta-button secondary">Detect Image</a>
458
+ {% else %}
459
+ <a href="{{ url_for('signup') }}" class="cta-button">Get Started</a>
460
+ {% endif %}
461
+ </div>
462
+ </section>
463
+
464
+ <section class="features" id="features">
465
+ <div class="container">
466
+ <h2>Our Features</h2>
467
+ <div class="features-grid">
468
+ <div class="feature-card">
469
+ <div class="feature-icon">📁</div>
470
+ <h3>Video Upload</h3>
471
+ <p>Upload your video files directly for analysis. Supports MP4, AVI, and MOV formats up to 100MB.</p>
472
+ {% if current_user.is_authenticated %}
473
+ <a href="{{ url_for('detect') }}" class="feature-link">Try Upload</a>
474
+ {% else %}
475
+ <a href="{{ url_for('signup') }}" class="feature-link">Sign Up</a>
476
+ {% endif %}
477
+ </div>
478
+ <div class="feature-card">
479
+ <div class="feature-icon">🖼️</div>
480
+ <h3>Image Analysis</h3>
481
+ <p>Analyze static images to detect potential AI-generated or manipulated content using advanced deep learning algorithms.</p>
482
+ {% if current_user.is_authenticated %}
483
+ <a href="{{ url_for('image_detect') }}" class="feature-link">Try Image</a>
484
+ {% else %}
485
+ <a href="{{ url_for('signup') }}" class="feature-link">Sign Up</a>
486
+ {% endif %}
487
+ </div>
488
+ <div class="feature-card">
489
+ <div class="feature-icon">🤖</div>
490
+ <h3>AI-Powered</h3>
491
+ <p>Advanced deep learning models trained on extensive datasets for accurate DeepFake detection.</p>
492
+ </div>
493
+ <div class="feature-card">
494
+ <div class="feature-icon">⚡</div>
495
+ <h3>Fast Results</h3>
496
+ <p>Get results in seconds with our optimized processing pipeline and real-time analysis.</p>
497
+ </div>
498
+ </div>
499
+ </div>
500
+ </section>
501
+
502
+ <section id="about" class="about">
503
+ <h2>About Our Technology</h2>
504
+ <p>Our DeepFake Detection system utilizes state-of-the-art deep learning algorithms to analyze videos and
505
+ identify potential manipulations. We combine advanced facial recognition with temporal analysis to detect
506
+ inconsistencies that are typical in deepfake videos.</p>
507
+ <p>Built with privacy and security in mind, our system processes videos locally and provides detailed analysis
508
+ with confidence scores and visual explanations. We're committed to helping combat the spread of manipulated
509
+ media by making detection technology accessible to everyone.</p>
510
+ </section>
511
+
512
+ <section id="contact" class="contact">
513
+ <h2>Contact Us</h2>
514
+ <p>Have questions or feedback? We'd love to hear from you. Get in touch with our team using the form below.</p>
515
+ <div class="contact-form">
516
+ <form>
517
+ <input type="text" placeholder="Your Name" required>
518
+ <input type="email" placeholder="Your Email" required>
519
+ <textarea rows="4" placeholder="Your Message" required></textarea>
520
+ <button type="submit">Send Message</button>
521
+ </form>
522
+ </div>
523
+ </section>
524
+
525
+ <footer>
526
+ <p>&copy; 2025 TrueVision. All rights reserved.</p>
527
+ <p>
528
+ <a href="{{ url_for('privacy') }}">Privacy Policy</a> |
529
+ <a href="{{ url_for('terms') }}">Terms of Service</a>
530
+ </p>
531
+ </footer>
532
+
533
+ <script>
534
+ document.addEventListener('DOMContentLoaded', () => {
535
+ const hamburgerBtn = document.getElementById('hamburger-btn');
536
+ const navLinks = document.getElementById('nav-links');
537
+
538
+ // Toggle menu on hamburger click
539
+ hamburgerBtn.addEventListener('click', () => {
540
+ navLinks.classList.toggle('active');
541
+ });
542
+
543
+ // Close menu when a link is clicked (useful for mobile navigation)
544
+ document.querySelectorAll('.nav-link').forEach(link => {
545
+ link.addEventListener('click', () => {
546
+ navLinks.classList.remove('active');
547
+ });
548
+ });
549
+ });
550
+ </script>
551
+ </body>
552
+
553
+ </html>
templates/image.html ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
7
+ <title>DeepFake Detection</title>
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ padding: 0;
12
+ background-color: #0d0b1f;
13
+ color: #ffffff;
14
+ font-family: 'Inter', sans-serif;
15
+ text-align: center;
16
+ }
17
+
18
+ .navbar {
19
+ background: #12122c;
20
+ padding: 1rem 2rem;
21
+ display: flex;
22
+ justify-content: space-between;
23
+ align-items: center;
24
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
25
+ position: sticky;
26
+ top: 0;
27
+ z-index: 1000;
28
+ }
29
+
30
+ .navbar-brand {
31
+ color: #00f2ff;
32
+ font-size: 1.8rem;
33
+ font-weight: bold;
34
+ text-decoration: none;
35
+ transition: color 0.3s ease;
36
+ }
37
+
38
+ .navbar-brand:hover {
39
+ color: #00c2cc;
40
+ }
41
+
42
+ /* Hamburger Button (Hidden on PC) */
43
+ .hamburger {
44
+ display: none;
45
+ background: none;
46
+ border: none;
47
+ color: #00f2ff;
48
+ font-size: 2rem;
49
+ cursor: pointer;
50
+ padding: 0;
51
+ }
52
+
53
+ .navbar-nav {
54
+ display: flex;
55
+ gap: 1rem;
56
+ align-items: center;
57
+ transition: all 0.3s ease;
58
+ }
59
+
60
+ .nav-link {
61
+ color: white;
62
+ text-decoration: none;
63
+ padding: 0.6rem 1.2rem;
64
+ font-size: 1rem;
65
+ border-radius: 5px;
66
+ transition: all 0.3s ease-in-out;
67
+ }
68
+
69
+ .nav-link:hover {
70
+ background: rgba(0, 242, 255, 0.2);
71
+ color: #00f2ff;
72
+ }
73
+
74
+ .nav-link.highlight {
75
+ background: #00f2ff;
76
+ color: #0a091b;
77
+ font-weight: 600;
78
+ padding: 0.7rem 1.5rem;
79
+ border-radius: 8px;
80
+ }
81
+
82
+ .nav-link.highlight:hover {
83
+ background: #00c2cc;
84
+ }
85
+
86
+ .container {
87
+ margin-top: 30px;
88
+ display: flex;
89
+ flex-direction: column;
90
+ align-items: center;
91
+ }
92
+
93
+ h1 {
94
+ font-size: 2.8rem;
95
+ margin-bottom: 10px;
96
+ color: #00f2ff;
97
+ }
98
+
99
+ .form-container {
100
+ background: #1b1b3a;
101
+ padding: 30px;
102
+ border-radius: 12px;
103
+ width: 400px;
104
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
105
+ text-align: center;
106
+ margin-top: 20px;
107
+ }
108
+
109
+ .upload-box {
110
+ border: 2px dashed #00f2ff;
111
+ padding: 20px;
112
+ width: 100%;
113
+ border-radius: 10px;
114
+ cursor: pointer;
115
+ margin-bottom: 20px;
116
+ }
117
+
118
+ .upload-box input {
119
+ display: none;
120
+ }
121
+
122
+ .btn {
123
+ background-color: #00f2ff;
124
+ color: black;
125
+ padding: 14px 28px;
126
+ font-size: 18px;
127
+ font-weight: bold;
128
+ border: none;
129
+ border-radius: 8px;
130
+ cursor: pointer;
131
+ transition: 0.3s;
132
+ }
133
+
134
+ .btn:hover {
135
+ background-color: #00c2cc;
136
+ }
137
+
138
+ .result {
139
+ margin-top: 15px;
140
+ font-size: 1.2rem;
141
+ }
142
+
143
+ .footer {
144
+ margin-top: 50px;
145
+ padding: 20px;
146
+ background-color: #12122c;
147
+ color: white;
148
+ font-size: 14px;
149
+ }
150
+
151
+ /* --- MOBILE FIXES FOR IMAGE DETECT --- */
152
+ @media (max-width: 768px) {
153
+ body {
154
+ -webkit-tap-highlight-color: transparent;
155
+ -webkit-touch-callout: none;
156
+ user-select: none;
157
+ }
158
+ .navbar {
159
+ padding: 1rem 1.5rem;
160
+ }
161
+ .hamburger {
162
+ display: block;
163
+ }
164
+ .navbar-nav {
165
+ display: flex;
166
+ flex-direction: column;
167
+ position: absolute;
168
+ top: 70px;
169
+ left: 0;
170
+ width: 100%;
171
+ background: rgba(18, 18, 44, 0.98);
172
+ padding: 0;
173
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
174
+ max-height: 0;
175
+ overflow: hidden;
176
+ opacity: 0;
177
+ transition: all 0.3s ease;
178
+ }
179
+ .navbar-nav.active {
180
+ max-height: 500px;
181
+ padding: 1rem 0;
182
+ opacity: 1;
183
+ }
184
+ .nav-link {
185
+ width: 100%;
186
+ text-align: center;
187
+ padding: 1.2rem;
188
+ border-radius: 0;
189
+ }
190
+ .form-container {
191
+ width: 90% !important;
192
+ max-width: 400px;
193
+ padding: 20px;
194
+ box-sizing: border-box;
195
+ }
196
+ .container h1 {
197
+ font-size: clamp(2rem, 8vw, 2.8rem);
198
+ }
199
+ }
200
+ </style>
201
+ </head>
202
+ <body>
203
+
204
+ <div class="navbar">
205
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a>
206
+
207
+ <button class="hamburger" id="hamburger-btn" aria-label="Toggle menu">
208
+
209
+ </button>
210
+
211
+ <div class="navbar-nav" id="nav-links">
212
+ <a href="{{ url_for('detect') }}" class="nav-link highlight">Video Detect</a>
213
+ <a href="{{ url_for('history') }}" class="nav-link highlight">History</a>
214
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
215
+ </div>
216
+ </div>
217
+
218
+ <div class="container">
219
+ <h1>Detect DeepFake Image</h1>
220
+ <p>Upload your image for AI-powered analysis to detect potential manipulation.</p>
221
+ </div>
222
+
223
+ <div class="container">
224
+ <h2>Upload an Image</h2>
225
+ <div class="form-container">
226
+ <form action="/image-detect" method="post" enctype="multipart/form-data">
227
+ <input type="file" id="fileUpload" style="margin: 20px;" name="image" accept="image/*" required onchange="previewImage(event)"><br>
228
+ <img id="preview" class="image-preview" style="width: 100px; margin: auto; display: none;">
229
+ <br>
230
+ <button class="btn" type="submit">Detect</button>
231
+ </form>
232
+
233
+ {% if output %}
234
+ <div class="result">
235
+ <p>Prediction: <strong>{{ output }}</strong></p>
236
+ <p>Confidence: <strong>{{ confidence }}%</strong></p>
237
+ </div>
238
+ {% endif %}
239
+ {% if error %}
240
+ <p class="error">{{ error }}</p>
241
+ {% endif %}
242
+ </div>
243
+ </div>
244
+
245
+ <div class="footer">
246
+ <p>&copy; 2025 DeepFake Detection</p>
247
+ </div>
248
+
249
+ <script>
250
+ function previewImage(event) {
251
+ const file = event.target.files[0];
252
+ if (file) {
253
+ const reader = new FileReader();
254
+ reader.onload = function(e) {
255
+ const preview = document.getElementById('preview');
256
+ preview.src = e.target.result;
257
+ preview.style.display = 'block';
258
+ };
259
+ reader.readAsDataURL(file);
260
+ }
261
+ }
262
+
263
+ // Hamburger Menu Script
264
+ document.addEventListener('DOMContentLoaded', () => {
265
+ const hamburgerBtn = document.getElementById('hamburger-btn');
266
+ const navLinks = document.getElementById('nav-links');
267
+
268
+ hamburgerBtn.addEventListener('click', () => {
269
+ navLinks.classList.toggle('active');
270
+ });
271
+
272
+ document.querySelectorAll('.nav-link').forEach(link => {
273
+ link.addEventListener('click', () => {
274
+ navLinks.classList.remove('active');
275
+ });
276
+ });
277
+ });
278
+ </script>
279
+ </body>
280
+ </html>
templates/index.css ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
+ sans-serif;
6
+ -webkit-font-smoothing: antialiased;
7
+ -moz-osx-font-smoothing: grayscale;
8
+ background: linear-gradient(135deg, #0a192f 0%, #1e293b 100%);
9
+ color: #8892b0;
10
+ min-height: 100vh;
11
+ }
12
+
13
+ code {
14
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
15
+ monospace;
16
+ }
17
+
18
+ #root {
19
+ min-height: 100vh;
20
+ display: flex;
21
+ flex-direction: column;
22
+ }
23
+
24
+ .nav {
25
+ backdrop-filter: blur(10px);
26
+ -webkit-backdrop-filter: blur(10px);
27
+ border-bottom: 1px solid rgba(100, 255, 218, 0.1);
28
+ }
29
+
30
+ .nav ul {
31
+ display: flex;
32
+ justify-content: center;
33
+ gap: 3rem;
34
+ margin: 0;
35
+ padding: 1.5rem 0;
36
+ }
37
+
38
+ .nav li {
39
+ color: #64ffda;
40
+ transition: all 0.3s ease;
41
+ }
42
+
43
+ .nav li:hover {
44
+ color: #00ffd5;
45
+ background: rgba(100, 255, 218, 0.1);
46
+ }
47
+
48
+ .button {
49
+ background: transparent;
50
+ color: #64ffda;
51
+ border: 2px solid #64ffda;
52
+ padding: 1rem 2rem;
53
+ border-radius: 8px;
54
+ font-weight: 600;
55
+ cursor: pointer;
56
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
57
+ }
58
+
59
+ .button:hover {
60
+ background: rgba(100, 255, 218, 0.1);
61
+ transform: translateY(-2px);
62
+ box-shadow: 0 4px 12px rgba(100, 255, 218, 0.2);
63
+ }
64
+
65
+ .content {
66
+ padding: 2rem;
67
+ max-width: 1200px;
68
+ margin: 0 auto;
69
+ animation: fadeIn 0.5s ease-in-out;
70
+ }
71
+
72
+ @keyframes fadeIn {
73
+ from {
74
+ opacity: 0;
75
+ transform: translateY(20px);
76
+ }
77
+ to {
78
+ opacity: 1;
79
+ transform: translateY(0);
80
+ }
81
+ }
82
+
83
+ .heading {
84
+ color: #64ffda;
85
+ font-size: clamp(2rem, 4vw, 3.5rem);
86
+ text-align: center;
87
+ margin-bottom: 2rem;
88
+ }
89
+
90
+ .para {
91
+ color: #8892b0;
92
+ font-size: clamp(1rem, 1.5vw, 1.25rem);
93
+ line-height: 1.6;
94
+ text-align: center;
95
+ max-width: 800px;
96
+ margin: 0 auto 3rem;
97
+ }
98
+
99
+ .feature-card {
100
+ background: rgba(17, 34, 64, 0.5);
101
+ border: 1px solid rgba(100, 255, 218, 0.1);
102
+ border-radius: 8px;
103
+ padding: 2rem;
104
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
105
+ }
106
+
107
+ .feature-card:hover {
108
+ transform: translateY(-5px);
109
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
110
+ }
111
+
112
+ .analysis-graph {
113
+ background: rgba(17, 34, 64, 0.3);
114
+ border: 1px solid rgba(100, 255, 218, 0.1);
115
+ border-radius: 8px;
116
+ padding: 1rem;
117
+ margin: 2rem 0;
118
+ height: 400px;
119
+ }
120
+
121
+ /* New styles for frame display */
122
+ .frames-container {
123
+ display: grid;
124
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
125
+ gap: 1.5rem;
126
+ margin: 2rem 0;
127
+ }
128
+
129
+ .frame-item {
130
+ background: rgba(17, 34, 64, 0.5);
131
+ border: 1px solid rgba(100, 255, 218, 0.1);
132
+ border-radius: 8px;
133
+ overflow: hidden;
134
+ transition: all 0.3s ease;
135
+ }
136
+
137
+ .frame-item:hover {
138
+ transform: scale(1.05);
139
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
140
+ }
141
+
142
+ .frame-item img {
143
+ width: 100%;
144
+ height: 200px;
145
+ object-fit: cover;
146
+ display: block;
147
+ }
148
+
149
+ .frame-info {
150
+ padding: 1rem;
151
+ text-align: center;
152
+ }
153
+
154
+ .frame-number {
155
+ color: #64ffda;
156
+ font-weight: 600;
157
+ margin: 0;
158
+ }
159
+
160
+ .result-container {
161
+ background: rgba(17, 34, 64, 0.5);
162
+ border: 1px solid rgba(100, 255, 218, 0.1);
163
+ border-radius: 8px;
164
+ padding: 2rem;
165
+ margin: 2rem 0;
166
+ text-align: center;
167
+ }
168
+
169
+ .result-heading {
170
+ color: #64ffda;
171
+ font-size: 1.5rem;
172
+ margin-bottom: 1rem;
173
+ }
174
+
175
+ .result-text {
176
+ font-size: 2.5rem;
177
+ font-weight: bold;
178
+ margin: 1rem 0;
179
+ }
180
+
181
+ .result-text.fake {
182
+ color: #ff4d4d;
183
+ }
184
+
185
+ .result-text.real {
186
+ color: #4dff4d;
187
+ }
188
+
189
+ .confidence-text {
190
+ color: #8892b0;
191
+ font-size: 1.1rem;
192
+ }
193
+
194
+ .footer {
195
+ margin-top: auto;
196
+ padding: 3rem 0;
197
+ background: rgba(10, 25, 47, 0.95);
198
+ border-top: 1px solid rgba(100, 255, 218, 0.1);
199
+ }
200
+
201
+ .footer-content {
202
+ max-width: 1200px;
203
+ margin: 0 auto;
204
+ padding: 0 2rem;
205
+ display: flex;
206
+ justify-content: space-between;
207
+ gap: 2rem;
208
+ }
209
+
210
+ .footer-section {
211
+ flex: 1;
212
+ }
213
+
214
+ .footer-section h3 {
215
+ color: #64ffda;
216
+ margin-bottom: 1rem;
217
+ }
218
+
219
+ .footer-section p {
220
+ color: #8892b0;
221
+ line-height: 1.6;
222
+ }
223
+
224
+ @media (max-width: 768px) {
225
+ .nav ul {
226
+ gap: 1.5rem;
227
+ padding: 1rem 0;
228
+ }
229
+
230
+ .content {
231
+ padding: 1rem;
232
+ }
233
+
234
+ .footer-content {
235
+ flex-direction: column;
236
+ text-align: center;
237
+ }
238
+
239
+ .frames-container {
240
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
241
+ gap: 1rem;
242
+ }
243
+
244
+ .frame-item img {
245
+ height: 150px;
246
+ }
247
+ }
248
+ /* MOBILE FIXES (Ignored by Desktop PCs) */
249
+ @media (max-width: 768px) {
250
+ /* 1. Fix the Header Text */
251
+ .hero h1 {
252
+ font-size: clamp(2rem, 8vw, 3.5rem);
253
+ }
254
+
255
+ /* 2. Fix the Navbar Overlap */
256
+ .navbar-nav {
257
+ overflow-x: auto;
258
+ white-space: nowrap;
259
+ padding-bottom: 5px;
260
+ -webkit-overflow-scrolling: touch;
261
+ justify-content: flex-start;
262
+ }
263
+
264
+ /* 3. Fix the Image/Video Upload Box */
265
+ .form-container, .file-input-wrapper {
266
+ width: 100%;
267
+ max-width: 400px;
268
+ box-sizing: border-box;
269
+ }
270
+
271
+ /* 4. Fix the Pie Chart */
272
+ .pie-chart-container {
273
+ width: 100%;
274
+ max-width: 350px;
275
+ aspect-ratio: 1 / 1;
276
+ height: auto;
277
+ }
278
+
279
+ /* 5. Add the "Native App" Feel */
280
+ body {
281
+ -webkit-tap-highlight-color: transparent;
282
+ -webkit-touch-callout: none;
283
+ user-select: none;
284
+ }
285
+ }
templates/index.html ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="/static/react/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
7
+ <meta name="theme-color" content="#000000" />
8
+ <meta name="description" content="DeepFake Detection - Advanced AI-powered video analysis" />
9
+ <link rel="manifest" href="/static/react/manifest.json" />
10
+ <title>DeepFake Detection</title>
11
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
12
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
13
+ <link href="/static/react/css/main.03d2e280.chunk.css" rel="stylesheet" />
14
+ <link href="/static/index.css" rel="stylesheet" />
15
+ <style>
16
+ * {
17
+ box-sizing: border-box;
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+
22
+ html {
23
+ scroll-behavior: smooth;
24
+ }
25
+
26
+ body {
27
+ margin: 0;
28
+ padding-top: 70px;
29
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
30
+ background: #1a1a1a;
31
+ color: white;
32
+ min-height: 100vh;
33
+ }
34
+
35
+ .nav-brand {
36
+ color: #64ffda;
37
+ font-size: 1.6rem;
38
+ font-weight: bold;
39
+ text-decoration: none;
40
+ text-transform: uppercase;
41
+ letter-spacing: 1px;
42
+ transition: all 0.3s ease;
43
+ }
44
+
45
+ .nav-link {
46
+ color: white;
47
+ text-decoration: none;
48
+ padding: 0.6rem 1.2rem;
49
+ border-radius: 6px;
50
+ transition: all 0.3s ease;
51
+ font-weight: 500;
52
+ text-transform: uppercase;
53
+ letter-spacing: 0.5px;
54
+ }
55
+
56
+ .nav-link:hover {
57
+ background: #2a2a2a;
58
+ color: #64ffda;
59
+ }
60
+
61
+ .nav-link.highlight {
62
+ background: #64ffda;
63
+ color: #1a1a1a;
64
+ }
65
+
66
+ .nav-link.highlight:hover {
67
+ background: #4cd6b3;
68
+ }
69
+
70
+ .nav {
71
+ background: rgba(26, 26, 26, 0.95);
72
+ padding: 1rem 2rem;
73
+ height: 70px;
74
+ position: fixed;
75
+ width: 100%;
76
+ top: 0;
77
+ left: 0;
78
+ z-index: 1000;
79
+ backdrop-filter: blur(10px);
80
+ box-shadow: 0 2px 20px rgba(0, 0, 0, 0.2);
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: space-between;
84
+ }
85
+
86
+ .nav ul {
87
+ display: flex;
88
+ gap: 1.5rem;
89
+ list-style: none;
90
+ margin: 0;
91
+ padding: 0;
92
+ }
93
+
94
+ .content {
95
+ padding: 6rem 2rem;
96
+ min-height: calc(100vh - 70px);
97
+ background: linear-gradient(135deg, #111d40 0%, #1a237e 100%);
98
+ text-align: center;
99
+ }
100
+
101
+ .heading {
102
+ font-size: 3.5rem;
103
+ color: #64ffda;
104
+ margin-bottom: 1.5rem;
105
+ text-shadow: 0 2px 10px rgba(100, 255, 218, 0.3);
106
+ animation: fadeInUp 0.8s ease-out;
107
+ }
108
+
109
+ .para {
110
+ font-size: 1.2rem;
111
+ color: #8892b0;
112
+ max-width: 800px;
113
+ margin: 0 auto 3rem;
114
+ }
115
+
116
+ .feature-card {
117
+ background: rgba(42, 42, 42, 0.8);
118
+ padding: 3rem;
119
+ border-radius: 12px;
120
+ max-width: 600px;
121
+ margin: 0 auto;
122
+ border: 1px solid rgba(100, 255, 218, 0.1);
123
+ backdrop-filter: blur(10px);
124
+ animation: fadeInUp 0.6s ease-out;
125
+ }
126
+
127
+ .button {
128
+ background: #64ffda;
129
+ color: #1a1a1a;
130
+ border: none;
131
+ padding: 1rem 2.5rem;
132
+ border-radius: 8px;
133
+ font-weight: bold;
134
+ cursor: pointer;
135
+ transition: all 0.3s ease;
136
+ text-transform: uppercase;
137
+ letter-spacing: 1px;
138
+ box-shadow: 0 4px 15px rgba(100, 255, 218, 0.2);
139
+ }
140
+
141
+ .button:hover {
142
+ background: #4cd6b3;
143
+ transform: translateY(-2px);
144
+ box-shadow: 0 6px 20px rgba(100, 255, 218, 0.3);
145
+ }
146
+
147
+ .file-upload {
148
+ position: relative;
149
+ width: 100%;
150
+ max-width: 400px;
151
+ text-align: center;
152
+ }
153
+
154
+ input[type="file"] {
155
+ background: rgba(42, 42, 42, 0.8);
156
+ padding: 3rem 1.5rem;
157
+ border-radius: 12px;
158
+ border: 2px dashed rgba(100, 255, 218, 0.3);
159
+ color: white;
160
+ width: 100%;
161
+ cursor: pointer;
162
+ transition: all 0.3s ease;
163
+ position: relative;
164
+ z-index: 1;
165
+ }
166
+
167
+ input[type="file"]:hover {
168
+ border-color: #64ffda;
169
+ background: rgba(42, 42, 42, 0.9);
170
+ }
171
+
172
+ .upload-hint {
173
+ position: absolute;
174
+ top: 50%;
175
+ left: 50%;
176
+ transform: translate(-50%, -50%);
177
+ color: #8892b0;
178
+ font-size: 0.9rem;
179
+ pointer-events: none;
180
+ z-index: 0;
181
+ width: 100%;
182
+ transition: all 0.3s ease;
183
+ }
184
+
185
+ .file-upload:hover .upload-hint {
186
+ color: #64ffda;
187
+ }
188
+
189
+ .result-container {
190
+ background: rgba(42, 42, 42, 0.8);
191
+ padding: 2rem;
192
+ border-radius: 12px;
193
+ margin: 3rem auto;
194
+ max-width: 800px;
195
+ border: 1px solid rgba(100, 255, 218, 0.1);
196
+ animation: fadeInUp 0.6s ease-out;
197
+ }
198
+
199
+ .result-heading {
200
+ color: #64ffda;
201
+ margin-bottom: 1.5rem;
202
+ font-size: 2rem;
203
+ }
204
+
205
+ .result-text {
206
+ font-size: 1.5rem;
207
+ margin-bottom: 1rem;
208
+ }
209
+
210
+ .result-text.fake {
211
+ color: #e74c3c;
212
+ }
213
+
214
+ .result-text.real {
215
+ color: #2ecc71;
216
+ }
217
+
218
+ .confidence-text {
219
+ color: #8892b0;
220
+ font-size: 1.2rem;
221
+ }
222
+
223
+ .frames-container {
224
+ display: grid;
225
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
226
+ gap: 2rem;
227
+ max-width: 1200px;
228
+ margin: 3rem auto;
229
+ padding: 0 1rem;
230
+ }
231
+
232
+ .frame-item {
233
+ background: rgba(42, 42, 42, 0.8);
234
+ border-radius: 8px;
235
+ overflow: hidden;
236
+ border: 1px solid rgba(100, 255, 218, 0.1);
237
+ transition: transform 0.3s ease;
238
+ }
239
+
240
+ .frame-item:hover {
241
+ transform: translateY(-5px);
242
+ }
243
+
244
+ .frame-item img {
245
+ width: 100%;
246
+ height: auto;
247
+ display: block;
248
+ }
249
+
250
+ .frame-info {
251
+ padding: 1rem;
252
+ background: rgba(26, 26, 26, 0.9);
253
+ }
254
+
255
+ .frame-number {
256
+ color: #8892b0;
257
+ margin: 0;
258
+ }
259
+
260
+ .footer {
261
+ background: #1a1a1a;
262
+ color: #8892b0;
263
+ padding: 4rem 2rem;
264
+ border-top: 1px solid rgba(42, 42, 42, 0.8);
265
+ }
266
+
267
+ .footer-content {
268
+ display: grid;
269
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
270
+ gap: 3rem;
271
+ max-width: 1200px;
272
+ margin: 0 auto;
273
+ }
274
+
275
+ .footer-section h3 {
276
+ color: #64ffda;
277
+ margin-bottom: 1rem;
278
+ font-size: 1.2rem;
279
+ }
280
+
281
+ .footer-section p {
282
+ margin: 0.5rem 0;
283
+ font-size: 0.9rem;
284
+ }
285
+
286
+ @keyframes fadeInUp {
287
+ from {
288
+ opacity: 0;
289
+ transform: translateY(20px);
290
+ }
291
+ to {
292
+ opacity: 1;
293
+ transform: translateY(0);
294
+ }
295
+ }
296
+ </style>
297
+ <script type="text/JavaScript">
298
+ window.data = {% if data %} {{ data|safe }} {% else %} null {% endif %};
299
+ </script>
300
+ </head>
301
+ <body>
302
+ <div id="root">
303
+ <nav class="nav">
304
+ <a href="/" class="nav-brand">DeepFake Detection</a>
305
+ <ul>
306
+ <li><a href="/" class="nav-link">Home</a></li>
307
+ <li><a href="/Detect" class="nav-link highlight">Detect</a></li>
308
+ </ul>
309
+ </nav>
310
+
311
+ <main class="content">
312
+ <h1 class="heading">IS YOUR VIDEO FAKE? CHECK IT!</h1>
313
+ <p class="para">Upload your video and our advanced AI will analyze it for signs of manipulation.</p>
314
+
315
+ <form action="/Detect" method="post" enctype="multipart/form-data" class="feature-card">
316
+ <div style="display: flex; flex-direction: column; align-items: center; gap: 2rem;">
317
+ <div class="file-upload">
318
+ <input type="file" name="video" accept="video/*" required />
319
+ <p class="upload-hint">Click to select or drag a video file here</p>
320
+ </div>
321
+ <button type="submit" class="button">Analyze Video</button>
322
+ </div>
323
+ </form>
324
+
325
+ <div id="results" style="display: none;">
326
+ <div class="result-container">
327
+ <h2 class="result-heading">Analysis Result</h2>
328
+ <p id="result-text" class="result-text"></p>
329
+ <p id="confidence-text" class="confidence-text"></p>
330
+ </div>
331
+
332
+ <div class="frames-container" id="frames-grid">
333
+ <!-- Frames will be inserted here dynamically -->
334
+ </div>
335
+ </div>
336
+ </main>
337
+
338
+ <footer class="footer">
339
+ <div class="footer-content">
340
+ <div class="footer-section">
341
+ <h3>About Us</h3>
342
+ <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p>
343
+ </div>
344
+ <div class="footer-section">
345
+ <h3>Contact</h3>
346
+ <p>Email: contact@deepfakedetect.ai</p>
347
+ <p>GitHub: github.com/deepfake-detect</p>
348
+ </div>
349
+ <div class="footer-section">
350
+ <h3>Legal</h3>
351
+ <p>© 2025 TrueVision</p>
352
+ <p>All Rights Reserved</p>
353
+ </div>
354
+ </div>
355
+ </footer>
356
+ </div>
357
+
358
+ <script>
359
+ document.addEventListener('DOMContentLoaded', function() {
360
+ const data = window.data;
361
+ if (data) {
362
+ try {
363
+ const parsedData = typeof data === 'string' ? JSON.parse(data) : data;
364
+ const resultsDiv = document.getElementById('results');
365
+ const resultText = document.getElementById('result-text');
366
+ const confidenceText = document.getElementById('confidence-text');
367
+ const framesGrid = document.getElementById('frames-grid');
368
+
369
+ resultsDiv.style.display = 'block';
370
+
371
+ // Display result and confidence
372
+ resultText.textContent = parsedData.output;
373
+ resultText.className = `result-text ${parsedData.output.toLowerCase()}`;
374
+ confidenceText.textContent = `Confidence: ${parsedData.confidence.toFixed(2)}%`;
375
+
376
+ // Display frames if available
377
+ if (parsedData.frames && parsedData.frames.length > 0) {
378
+ framesGrid.innerHTML = parsedData.frames.map((frame, index) => `
379
+ <div class="frame-item">
380
+ <img src="/static/frames/${frame}" alt="Frame ${index + 1}" />
381
+ <div class="frame-info">
382
+ <p class="frame-number">Frame ${index + 1}</p>
383
+ </div>
384
+ </div>
385
+ `).join('');
386
+ }
387
+ } catch (error) {
388
+ console.error('Error parsing data:', error);
389
+ }
390
+ }
391
+ });
392
+ </script>
393
+ </body>
394
+ </html>
templates/login.html ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Login - DeepFake Detection</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ padding: 0;
13
+ min-height: 100vh;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ background: linear-gradient(135deg, #0a192f 0%, #112240 100%);
18
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
19
+ }
20
+
21
+ .auth-container {
22
+ width: 100%;
23
+ max-width: 400px;
24
+ padding: 40px;
25
+ background: rgba(17, 25, 40, 0.95);
26
+ border-radius: 16px;
27
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
28
+ backdrop-filter: blur(8px);
29
+ }
30
+
31
+ h2 {
32
+ color: #fff;
33
+ text-align: center;
34
+ margin: 0 0 30px 0;
35
+ font-size: 28px;
36
+ font-weight: 600;
37
+ }
38
+
39
+ .form-group {
40
+ margin-bottom: 24px;
41
+ }
42
+
43
+ .form-group label {
44
+ display: block;
45
+ color: #8892b0;
46
+ margin-bottom: 8px;
47
+ font-size: 14px;
48
+ }
49
+
50
+ .input-group {
51
+ position: relative;
52
+ }
53
+
54
+ .input-group input {
55
+ width: 100%;
56
+ padding: 12px 12px 12px 40px;
57
+ background: rgba(255, 255, 255, 0.05);
58
+ border: 1px solid rgba(255, 255, 255, 0.1);
59
+ border-radius: 8px;
60
+ color: #fff;
61
+ font-size: 16px;
62
+ transition: all 0.3s ease;
63
+ box-sizing: border-box;
64
+ }
65
+
66
+ .input-group input:focus {
67
+ outline: none;
68
+ border-color: #64ffda;
69
+ background: rgba(255, 255, 255, 0.07);
70
+ }
71
+
72
+ .input-group i {
73
+ position: absolute;
74
+ left: 14px;
75
+ top: 50%;
76
+ transform: translateY(-50%);
77
+ color: #8892b0;
78
+ font-size: 16px;
79
+ }
80
+
81
+ .password-toggle {
82
+ position: absolute;
83
+ right: 14px;
84
+ top: 50%;
85
+ transform: translateY(-50%);
86
+ color: #8892b0;
87
+ cursor: pointer;
88
+ font-size: 16px;
89
+ background: none;
90
+ border: none;
91
+ padding: 0;
92
+ }
93
+
94
+ .auth-btn {
95
+ width: 100%;
96
+ padding: 14px;
97
+ background: #64ffda;
98
+ color: #0a192f;
99
+ border: none;
100
+ border-radius: 8px;
101
+ font-size: 16px;
102
+ font-weight: 600;
103
+ cursor: pointer;
104
+ transition: all 0.3s ease;
105
+ margin-top: 8px;
106
+ }
107
+
108
+ .auth-btn:hover {
109
+ background: #4cd6b3;
110
+ transform: translateY(-1px);
111
+ }
112
+
113
+ .auth-btn:active {
114
+ transform: translateY(0);
115
+ }
116
+
117
+ .auth-links {
118
+ text-align: center;
119
+ margin-top: 24px;
120
+ color: #8892b0;
121
+ font-size: 14px;
122
+ }
123
+
124
+ .auth-links a {
125
+ color: #64ffda;
126
+ text-decoration: none;
127
+ font-weight: 500;
128
+ transition: color 0.3s ease;
129
+ }
130
+
131
+ .auth-links a:hover {
132
+ color: #4cd6b3;
133
+ }
134
+
135
+ .error-message {
136
+ background: rgba(255, 69, 58, 0.1);
137
+ border: 1px solid rgba(255, 69, 58, 0.2);
138
+ color: #ff453a;
139
+ padding: 12px;
140
+ border-radius: 8px;
141
+ margin-bottom: 20px;
142
+ font-size: 14px;
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 8px;
146
+ }
147
+
148
+ @keyframes shake {
149
+ 0%, 100% { transform: translateX(0); }
150
+ 25% { transform: translateX(-5px); }
151
+ 75% { transform: translateX(5px); }
152
+ }
153
+
154
+ .input-invalid {
155
+ animation: shake 0.5s ease-in-out;
156
+ border-color: #ff453a !important;
157
+ }
158
+
159
+ .validation-message {
160
+ color: #ff453a;
161
+ font-size: 12px;
162
+ margin-top: 4px;
163
+ display: none;
164
+ }
165
+
166
+ .input-invalid + .validation-message {
167
+ display: block;
168
+ }
169
+
170
+ @media (max-width: 480px) {
171
+ .auth-container {
172
+ padding: 30px 20px;
173
+ margin: 20px;
174
+ }
175
+ }
176
+ </style>
177
+ </head>
178
+ <body>
179
+ <div class="auth-container">
180
+ <h2>Welcome Back</h2>
181
+ {% if error %}
182
+ <div class="error-message">
183
+ <i class="fas fa-exclamation-circle"></i>
184
+ {{ error }}
185
+ </div>
186
+ {% endif %}
187
+ <form method="POST" action="{{ url_for('login') }}" id="loginForm" novalidate>
188
+ <div class="form-group">
189
+ <label for="email">Email</label>
190
+ <div class="input-group">
191
+ <i class="fas fa-envelope"></i>
192
+ <input type="email" id="email" name="email" required
193
+ placeholder="Enter your email"
194
+ aria-label="Email address">
195
+ <div class="validation-message">Please enter a valid email address</div>
196
+ </div>
197
+ </div>
198
+ <div class="form-group">
199
+ <label for="password">Password</label>
200
+ <div class="input-group">
201
+ <i class="fas fa-lock"></i>
202
+ <input type="password" id="password" name="password" required
203
+ placeholder="Enter your password"
204
+ aria-label="Password">
205
+ <button type="button" class="password-toggle" onclick="togglePassword()">
206
+ <i class="fas fa-eye"></i>
207
+ </button>
208
+ <div class="validation-message">Password is required</div>
209
+ </div>
210
+ </div>
211
+ <button type="submit" class="auth-btn" id="submitBtn">Login</button>
212
+ </form>
213
+ <div class="auth-links">
214
+ Don't have an account? <a href="{{ url_for('signup') }}">Sign up</a>
215
+ </div>
216
+ </div>
217
+
218
+ <script>
219
+ function togglePassword() {
220
+ const passwordInput = document.getElementById('password');
221
+ const toggleIcon = document.querySelector('.password-toggle i');
222
+
223
+ if (passwordInput.type === 'password') {
224
+ passwordInput.type = 'text';
225
+ toggleIcon.classList.remove('fa-eye');
226
+ toggleIcon.classList.add('fa-eye-slash');
227
+ } else {
228
+ passwordInput.type = 'password';
229
+ toggleIcon.classList.remove('fa-eye-slash');
230
+ toggleIcon.classList.add('fa-eye');
231
+ }
232
+ }
233
+
234
+ document.getElementById('loginForm').addEventListener('submit', function(e) {
235
+ let isValid = true;
236
+ const email = document.getElementById('email');
237
+ const password = document.getElementById('password');
238
+ const submitBtn = document.getElementById('submitBtn');
239
+
240
+ // Email validation
241
+ if (!email.value || !email.value.match(/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i)) {
242
+ email.classList.add('input-invalid');
243
+ isValid = false;
244
+ } else {
245
+ email.classList.remove('input-invalid');
246
+ }
247
+
248
+ // Password validation
249
+ if (!password.value) {
250
+ password.classList.add('input-invalid');
251
+ isValid = false;
252
+ } else {
253
+ password.classList.remove('input-invalid');
254
+ }
255
+
256
+ if (!isValid) {
257
+ e.preventDefault();
258
+ } else {
259
+ submitBtn.textContent = 'Logging in...';
260
+ submitBtn.disabled = true;
261
+ }
262
+ });
263
+
264
+ // Real-time validation
265
+ const inputs = document.querySelectorAll('input');
266
+ inputs.forEach(input => {
267
+ input.addEventListener('input', function() {
268
+ if (this.value) {
269
+ this.classList.remove('input-invalid');
270
+ }
271
+ });
272
+ });
273
+ </script>
274
+ </body>
275
+ </html>
templates/privacy.html ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <meta name="description" content="Privacy Policy - DeepFake Detection">
7
+ <title>Privacy Policy - DeepFake Detection</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
10
+ <style>
11
+ .privacy-content {
12
+ max-width: 800px;
13
+ margin: 0 auto;
14
+ padding: 2rem;
15
+ }
16
+
17
+ .privacy-section {
18
+ margin-bottom: 2rem;
19
+ background: rgba(17, 34, 64, 0.3);
20
+ border: 1px solid rgba(100, 255, 218, 0.1);
21
+ border-radius: 8px;
22
+ padding: 2rem;
23
+ }
24
+
25
+ .privacy-section h2 {
26
+ color: #64ffda;
27
+ margin-bottom: 1rem;
28
+ }
29
+
30
+ .privacy-section p {
31
+ color: #8892b0;
32
+ line-height: 1.6;
33
+ margin-bottom: 1rem;
34
+ }
35
+
36
+ .privacy-section ul {
37
+ list-style-type: none;
38
+ padding-left: 0;
39
+ }
40
+
41
+ .privacy-section li {
42
+ color: #8892b0;
43
+ margin-bottom: 0.5rem;
44
+ padding-left: 1.5rem;
45
+ position: relative;
46
+ }
47
+
48
+ .privacy-section li::before {
49
+ content: "→";
50
+ position: absolute;
51
+ left: 0;
52
+ color: #64ffda;
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="root">
58
+ <nav class="navbar">
59
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a>
60
+ <div class="navbar-nav">
61
+ {% if current_user.is_authenticated %}
62
+ <a href="{{ url_for('detect') }}" class="nav-link">Detect</a>
63
+ <a href="{{ url_for('history') }}" class="nav-link">History</a>
64
+ {% if current_user.is_admin %}
65
+ <a href="{{ url_for('admin') }}" class="nav-link">Admin</a>
66
+ {% endif %}
67
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
68
+ {% else %}
69
+ <a href="{{ url_for('login') }}" class="nav-link">Login</a>
70
+ <a href="{{ url_for('signup') }}" class="nav-link highlight">Sign Up</a>
71
+ {% endif %}
72
+ </div>
73
+ </nav>
74
+
75
+ <main class="content">
76
+ <h1 class="heading">Privacy Policy</h1>
77
+
78
+ <div class="privacy-content">
79
+ <div class="privacy-section">
80
+ <h2>Introduction</h2>
81
+ <p>At DeepFake Detection, we take your privacy seriously. This policy explains how we collect, use, and protect your personal information.</p>
82
+ </div>
83
+
84
+ <div class="privacy-section">
85
+ <h2>Information We Collect</h2>
86
+ <ul>
87
+ <li>Account information (email, username)</li>
88
+ <li>Uploaded videos for analysis</li>
89
+ <li>Analysis results and metadata</li>
90
+ <li>Usage statistics and preferences</li>
91
+ </ul>
92
+ </div>
93
+
94
+ <div class="privacy-section">
95
+ <h2>How We Use Your Information</h2>
96
+ <ul>
97
+ <li>To provide deepfake detection services</li>
98
+ <li>To improve our detection algorithms</li>
99
+ <li>To maintain and secure your account</li>
100
+ <li>To communicate important updates</li>
101
+ </ul>
102
+ </div>
103
+
104
+ <div class="privacy-section">
105
+ <h2>Data Security</h2>
106
+ <p>We implement robust security measures to protect your data:</p>
107
+ <ul>
108
+ <li>Secure data encryption</li>
109
+ <li>Regular security audits</li>
110
+ <li>Limited access to personal information</li>
111
+ <li>Automatic data deletion after analysis</li>
112
+ </ul>
113
+ </div>
114
+
115
+ <div class="privacy-section">
116
+ <h2>Your Rights</h2>
117
+ <ul>
118
+ <li>Access your personal data</li>
119
+ <li>Request data deletion</li>
120
+ <li>Opt-out of communications</li>
121
+ <li>Report privacy concerns</li>
122
+ </ul>
123
+ </div>
124
+
125
+ <div class="privacy-section">
126
+ <h2>Contact Us</h2>
127
+ <p>If you have any questions about our privacy policy, please contact us at:</p>
128
+ <p>Email: privacy@deepfakedetect.ai</p>
129
+ </div>
130
+ </div>
131
+ </main>
132
+
133
+ <footer class="footer">
134
+ <div class="footer-content">
135
+ <div class="footer-section">
136
+ <h3>About Us</h3>
137
+ <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p>
138
+ </div>
139
+ <div class="footer-section">
140
+ <h3>Contact</h3>
141
+ <a href="mailto:contact@deepfakedetect.ai" class="footer-link">contact@deepfakedetect.ai</a>
142
+ <a href="https://github.com/deepfake-detect" target="_blank" rel="noopener noreferrer" class="footer-link">GitHub</a>
143
+ </div>
144
+ <div class="footer-section">
145
+ <h3>Legal</h3>
146
+ <a href="#" class="footer-link">Privacy Policy</a>
147
+ <a href="{{ url_for('terms') }}" class="footer-link">Terms of Service</a>
148
+ <p>© 2024 DeepFake Detection</p>
149
+ </div>
150
+ </div>
151
+ </footer>
152
+ </div>
153
+ </body>
154
+ </html>
templates/signup.html ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Sign Up - DeepFake Detection</title>
7
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
9
+ <style>
10
+ body {
11
+ margin: 0;
12
+ padding: 0;
13
+ min-height: 100vh;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ background: linear-gradient(135deg, #0a192f 0%, #112240 100%);
18
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
19
+ }
20
+
21
+ .auth-container {
22
+ width: 100%;
23
+ max-width: 400px;
24
+ padding: 40px;
25
+ background: rgba(17, 25, 40, 0.95);
26
+ border-radius: 16px;
27
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
28
+ backdrop-filter: blur(8px);
29
+ margin: 20px;
30
+ }
31
+
32
+ h2 {
33
+ color: #fff;
34
+ text-align: center;
35
+ margin: 0 0 30px 0;
36
+ font-size: 28px;
37
+ font-weight: 600;
38
+ }
39
+
40
+ .form-group {
41
+ margin-bottom: 24px;
42
+ }
43
+
44
+ .form-group label {
45
+ display: block;
46
+ color: #8892b0;
47
+ margin-bottom: 8px;
48
+ font-size: 14px;
49
+ }
50
+
51
+ .input-group {
52
+ position: relative;
53
+ }
54
+
55
+ .input-group input {
56
+ width: 100%;
57
+ padding: 12px 12px 12px 40px;
58
+ background: rgba(255, 255, 255, 0.05);
59
+ border: 1px solid rgba(255, 255, 255, 0.1);
60
+ border-radius: 8px;
61
+ color: #fff;
62
+ font-size: 16px;
63
+ transition: all 0.3s ease;
64
+ box-sizing: border-box;
65
+ }
66
+
67
+ .input-group input:focus {
68
+ outline: none;
69
+ border-color: #64ffda;
70
+ background: rgba(255, 255, 255, 0.07);
71
+ }
72
+
73
+ .input-group i {
74
+ position: absolute;
75
+ left: 14px;
76
+ top: 50%;
77
+ transform: translateY(-50%);
78
+ color: #8892b0;
79
+ font-size: 16px;
80
+ }
81
+
82
+ .password-toggle {
83
+ position: absolute;
84
+ right: 14px;
85
+ top: 50%;
86
+ transform: translateY(-50%);
87
+ color: #8892b0;
88
+ cursor: pointer;
89
+ font-size: 16px;
90
+ background: none;
91
+ border: none;
92
+ padding: 0;
93
+ }
94
+
95
+ .auth-btn {
96
+ width: 100%;
97
+ padding: 14px;
98
+ background: #64ffda;
99
+ color: #0a192f;
100
+ border: none;
101
+ border-radius: 8px;
102
+ font-size: 16px;
103
+ font-weight: 600;
104
+ cursor: pointer;
105
+ transition: all 0.3s ease;
106
+ margin-top: 8px;
107
+ }
108
+
109
+ .auth-btn:hover {
110
+ background: #4cd6b3;
111
+ transform: translateY(-1px);
112
+ }
113
+
114
+ .auth-btn:active {
115
+ transform: translateY(0);
116
+ }
117
+
118
+ .auth-links {
119
+ text-align: center;
120
+ margin-top: 24px;
121
+ color: #8892b0;
122
+ font-size: 14px;
123
+ }
124
+
125
+ .auth-links a {
126
+ color: #64ffda;
127
+ text-decoration: none;
128
+ font-weight: 500;
129
+ transition: color 0.3s ease;
130
+ }
131
+
132
+ .auth-links a:hover {
133
+ color: #4cd6b3;
134
+ }
135
+
136
+ .error-message {
137
+ background: rgba(255, 69, 58, 0.1);
138
+ border: 1px solid rgba(255, 69, 58, 0.2);
139
+ color: #ff453a;
140
+ padding: 12px;
141
+ border-radius: 8px;
142
+ margin-bottom: 20px;
143
+ font-size: 14px;
144
+ display: flex;
145
+ align-items: center;
146
+ gap: 8px;
147
+ }
148
+
149
+ .password-strength {
150
+ margin-top: 8px;
151
+ }
152
+
153
+ .strength-meter {
154
+ height: 4px;
155
+ background: rgba(255, 255, 255, 0.1);
156
+ border-radius: 2px;
157
+ overflow: hidden;
158
+ }
159
+
160
+ .strength-meter div {
161
+ height: 100%;
162
+ width: 0;
163
+ transition: all 0.3s ease;
164
+ }
165
+
166
+ .strength-weak { background: #ff453a; }
167
+ .strength-medium { background: #ff9f0a; }
168
+ .strength-strong { background: #64ffda; }
169
+
170
+ .strength-text {
171
+ color: #8892b0;
172
+ font-size: 12px;
173
+ margin-top: 4px;
174
+ }
175
+
176
+ @keyframes shake {
177
+ 0%, 100% { transform: translateX(0); }
178
+ 25% { transform: translateX(-5px); }
179
+ 75% { transform: translateX(5px); }
180
+ }
181
+
182
+ .input-invalid {
183
+ animation: shake 0.5s ease-in-out;
184
+ border-color: #ff453a !important;
185
+ }
186
+
187
+ .validation-message {
188
+ color: #ff453a;
189
+ font-size: 12px;
190
+ margin-top: 4px;
191
+ display: none;
192
+ }
193
+
194
+ .input-invalid + .validation-message {
195
+ display: block;
196
+ }
197
+
198
+ @media (max-width: 480px) {
199
+ .auth-container {
200
+ padding: 30px 20px;
201
+ }
202
+ }
203
+ </style>
204
+ </head>
205
+ <body>
206
+ <div class="auth-container">
207
+ <h2>Create Account</h2>
208
+ {% if error %}
209
+ <div class="error-message">
210
+ <i class="fas fa-exclamation-circle"></i>
211
+ {{ error }}
212
+ </div>
213
+ {% endif %}
214
+ <form method="POST" action="{{ url_for('signup') }}" id="signupForm" novalidate>
215
+ <div class="form-group">
216
+ <label for="username">Username</label>
217
+ <div class="input-group">
218
+ <i class="fas fa-user"></i>
219
+ <input type="text" id="username" name="username" required
220
+ placeholder="Choose a username"
221
+ aria-label="Username">
222
+ <div class="validation-message">Username must be 3-20 characters</div>
223
+ </div>
224
+ </div>
225
+ <div class="form-group">
226
+ <label for="email">Email</label>
227
+ <div class="input-group">
228
+ <i class="fas fa-envelope"></i>
229
+ <input type="email" id="email" name="email" required
230
+ placeholder="Enter your email"
231
+ aria-label="Email address">
232
+ <div class="validation-message">Please enter a valid email address</div>
233
+ </div>
234
+ </div>
235
+ <div class="form-group">
236
+ <label for="password">Password</label>
237
+ <div class="input-group">
238
+ <i class="fas fa-lock"></i>
239
+ <input type="password" id="password" name="password" required
240
+ placeholder="Create a password"
241
+ aria-label="Password">
242
+ <button type="button" class="password-toggle" onclick="togglePassword('password')">
243
+ <i class="fas fa-eye"></i>
244
+ </button>
245
+ <div class="validation-message">Password must be at least 8 characters</div>
246
+ </div>
247
+ <div class="password-strength">
248
+ <div class="strength-meter">
249
+ <div id="strengthBar"></div>
250
+ </div>
251
+ <div class="strength-text" id="strengthText">Password strength</div>
252
+ </div>
253
+ </div>
254
+ <div class="form-group">
255
+ <label for="confirm_password">Confirm Password</label>
256
+ <div class="input-group">
257
+ <i class="fas fa-lock"></i>
258
+ <input type="password" id="confirm_password" name="confirm_password" required
259
+ placeholder="Confirm your password"
260
+ aria-label="Confirm password">
261
+ <button type="button" class="password-toggle" onclick="togglePassword('confirm_password')">
262
+ <i class="fas fa-eye"></i>
263
+ </button>
264
+ <div class="validation-message">Passwords do not match</div>
265
+ </div>
266
+ </div>
267
+ <button type="submit" class="auth-btn" id="submitBtn">Sign Up</button>
268
+ </form>
269
+ <div class="auth-links">
270
+ Already have an account? <a href="{{ url_for('login') }}">Login</a>
271
+ </div>
272
+ </div>
273
+
274
+ <script>
275
+ function togglePassword(inputId) {
276
+ const passwordInput = document.getElementById(inputId);
277
+ const toggleIcon = passwordInput.nextElementSibling.querySelector('i');
278
+
279
+ if (passwordInput.type === 'password') {
280
+ passwordInput.type = 'text';
281
+ toggleIcon.classList.remove('fa-eye');
282
+ toggleIcon.classList.add('fa-eye-slash');
283
+ } else {
284
+ passwordInput.type = 'password';
285
+ toggleIcon.classList.remove('fa-eye-slash');
286
+ toggleIcon.classList.add('fa-eye');
287
+ }
288
+ }
289
+
290
+ function checkPasswordStrength(password) {
291
+ let strength = 0;
292
+ const strengthBar = document.getElementById('strengthBar');
293
+ const strengthText = document.getElementById('strengthText');
294
+
295
+ if (password.length >= 8) strength += 1;
296
+ if (password.length >= 12) strength += 1;
297
+ if (/[A-Z]/.test(password)) strength += 1;
298
+ if (/[0-9]/.test(password)) strength += 1;
299
+ if (/[^A-Za-z0-9]/.test(password)) strength += 1;
300
+
301
+ strengthBar.className = '';
302
+ if (strength <= 2) {
303
+ strengthBar.classList.add('strength-weak');
304
+ strengthText.textContent = 'Weak password';
305
+ strengthBar.style.width = '33%';
306
+ } else if (strength <= 4) {
307
+ strengthBar.classList.add('strength-medium');
308
+ strengthText.textContent = 'Medium password';
309
+ strengthBar.style.width = '66%';
310
+ } else {
311
+ strengthBar.classList.add('strength-strong');
312
+ strengthText.textContent = 'Strong password';
313
+ strengthBar.style.width = '100%';
314
+ }
315
+ }
316
+
317
+ document.getElementById('password').addEventListener('input', function() {
318
+ checkPasswordStrength(this.value);
319
+ });
320
+
321
+ document.getElementById('signupForm').addEventListener('submit', function(e) {
322
+ let isValid = true;
323
+ const username = document.getElementById('username');
324
+ const email = document.getElementById('email');
325
+ const password = document.getElementById('password');
326
+ const confirmPassword = document.getElementById('confirm_password');
327
+ const submitBtn = document.getElementById('submitBtn');
328
+
329
+ if (!username.value.match(/^[a-zA-Z0-9_]{3,20}$/)) {
330
+ username.classList.add('input-invalid');
331
+ isValid = false;
332
+ } else {
333
+ username.classList.remove('input-invalid');
334
+ }
335
+
336
+ if (!email.value.match(/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i)) {
337
+ email.classList.add('input-invalid');
338
+ isValid = false;
339
+ } else {
340
+ email.classList.remove('input-invalid');
341
+ }
342
+
343
+ if (password.value.length < 8) {
344
+ password.classList.add('input-invalid');
345
+ isValid = false;
346
+ } else {
347
+ password.classList.remove('input-invalid');
348
+ }
349
+
350
+ if (password.value !== confirmPassword.value) {
351
+ confirmPassword.classList.add('input-invalid');
352
+ isValid = false;
353
+ } else {
354
+ confirmPassword.classList.remove('input-invalid');
355
+ }
356
+
357
+ if (!isValid) {
358
+ e.preventDefault();
359
+ } else {
360
+ submitBtn.textContent = 'Creating account...';
361
+ submitBtn.disabled = true;
362
+ }
363
+ });
364
+
365
+ const inputs = document.querySelectorAll('input');
366
+ inputs.forEach(input => {
367
+ input.addEventListener('input', function() {
368
+ if (this.value) {
369
+ this.classList.remove('input-invalid');
370
+ }
371
+
372
+ if (this.id === 'password' || this.id === 'confirm_password') {
373
+ const password = document.getElementById('password');
374
+ const confirmPassword = document.getElementById('confirm_password');
375
+ if (confirmPassword.value) {
376
+ if (password.value === confirmPassword.value) {
377
+ confirmPassword.classList.remove('input-invalid');
378
+ } else {
379
+ confirmPassword.classList.add('input-invalid');
380
+ }
381
+ }
382
+ }
383
+ });
384
+ });
385
+ </script>
386
+ </body>
387
+ </html>
templates/terms.html ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <meta name="description" content="Terms of Service - DeepFake Detection">
7
+ <title>Terms of Service - DeepFake Detection</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
10
+ <style>
11
+ .terms-content {
12
+ max-width: 800px;
13
+ margin: 0 auto;
14
+ padding: 2rem;
15
+ }
16
+
17
+ .terms-section {
18
+ margin-bottom: 2rem;
19
+ background: rgba(17, 34, 64, 0.3);
20
+ border: 1px solid rgba(100, 255, 218, 0.1);
21
+ border-radius: 8px;
22
+ padding: 2rem;
23
+ }
24
+
25
+ .terms-section h2 {
26
+ color: #64ffda;
27
+ margin-bottom: 1rem;
28
+ }
29
+
30
+ .terms-section p {
31
+ color: #8892b0;
32
+ line-height: 1.6;
33
+ margin-bottom: 1rem;
34
+ }
35
+
36
+ .terms-section ul {
37
+ list-style-type: none;
38
+ padding-left: 0;
39
+ }
40
+
41
+ .terms-section li {
42
+ color: #8892b0;
43
+ margin-bottom: 0.5rem;
44
+ padding-left: 1.5rem;
45
+ position: relative;
46
+ }
47
+
48
+ .terms-section li::before {
49
+ content: "→";
50
+ position: absolute;
51
+ left: 0;
52
+ color: #64ffda;
53
+ }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div id="root">
58
+ <nav class="navbar">
59
+ <a href="{{ url_for('homepage') }}" class="navbar-brand">DeepFake Detection</a>
60
+ <div class="navbar-nav">
61
+ {% if current_user.is_authenticated %}
62
+ <a href="{{ url_for('detect') }}" class="nav-link">Detect</a>
63
+ <a href="{{ url_for('history') }}" class="nav-link">History</a>
64
+ {% if current_user.is_admin %}
65
+ <a href="{{ url_for('admin') }}" class="nav-link">Admin</a>
66
+ {% endif %}
67
+ <a href="{{ url_for('logout') }}" class="nav-link">Logout</a>
68
+ {% else %}
69
+ <a href="{{ url_for('login') }}" class="nav-link">Login</a>
70
+ <a href="{{ url_for('signup') }}" class="nav-link highlight">Sign Up</a>
71
+ {% endif %}
72
+ </div>
73
+ </nav>
74
+
75
+ <main class="content">
76
+ <h1 class="heading">Terms of Service</h1>
77
+
78
+ <div class="terms-content">
79
+ <div class="terms-section">
80
+ <h2>1. Acceptance of Terms</h2>
81
+ <p>By accessing and using DeepFake Detection, you agree to be bound by these Terms of Service and all applicable laws and regulations.</p>
82
+ </div>
83
+
84
+ <div class="terms-section">
85
+ <h2>2. Service Description</h2>
86
+ <p>DeepFake Detection provides AI-powered video analysis to detect potential manipulated content. Our service:</p>
87
+ <ul>
88
+ <li>Analyzes uploaded video content</li>
89
+ <li>Provides confidence scores and detailed analysis</li>
90
+ <li>Stores temporary data for processing</li>
91
+ <li>Maintains user accounts and preferences</li>
92
+ </ul>
93
+ </div>
94
+
95
+ <div class="terms-section">
96
+ <h2>3. User Obligations</h2>
97
+ <ul>
98
+ <li>Provide accurate account information</li>
99
+ <li>Maintain account security</li>
100
+ <li>Use the service legally and ethically</li>
101
+ <li>Respect intellectual property rights</li>
102
+ </ul>
103
+ </div>
104
+
105
+ <div class="terms-section">
106
+ <h2>4. Content Guidelines</h2>
107
+ <p>Users must not upload:</p>
108
+ <ul>
109
+ <li>Illegal or harmful content</li>
110
+ <li>Copyrighted material without permission</li>
111
+ <li>Malicious software or code</li>
112
+ <li>Content that violates privacy rights</li>
113
+ </ul>
114
+ </div>
115
+
116
+ <div class="terms-section">
117
+ <h2>5. Service Limitations</h2>
118
+ <ul>
119
+ <li>Maximum file size: 100MB per upload</li>
120
+ <li>Supported formats: MP4, AVI, MOV</li>
121
+ <li>Processing time may vary</li>
122
+ <li>Results accuracy not guaranteed</li>
123
+ </ul>
124
+ </div>
125
+
126
+ <div class="terms-section">
127
+ <h2>6. Privacy & Data</h2>
128
+ <p>We handle your data according to our Privacy Policy. Key points:</p>
129
+ <ul>
130
+ <li>Data is processed securely</li>
131
+ <li>Uploaded content is temporarily stored</li>
132
+ <li>Analysis results are confidential</li>
133
+ <li>User data is protected</li>
134
+ </ul>
135
+ </div>
136
+
137
+ <div class="terms-section">
138
+ <h2>7. Changes to Terms</h2>
139
+ <p>We reserve the right to modify these terms at any time. Continued use of the service constitutes acceptance of updated terms.</p>
140
+ </div>
141
+
142
+ <div class="terms-section">
143
+ <h2>8. Contact Information</h2>
144
+ <p>For questions about these terms, contact us at:</p>
145
+ <p>Email: legal@deepfakedetect.ai</p>
146
+ </div>
147
+ </div>
148
+ </main>
149
+
150
+ <footer class="footer">
151
+ <div class="footer-content">
152
+ <div class="footer-section">
153
+ <h3>About Us</h3>
154
+ <p>We are dedicated to detecting and preventing deepfake videos using advanced AI technology.</p>
155
+ </div>
156
+ <div class="footer-section">
157
+ <h3>Contact</h3>
158
+ <a href="mailto:contact@deepfakedetect.ai" class="footer-link">contact@deepfakedetect.ai</a>
159
+ <a href="https://github.com/deepfake-detect" target="_blank" rel="noopener noreferrer" class="footer-link">GitHub</a>
160
+ </div>
161
+ <div class="footer-section">
162
+ <h3>Legal</h3>
163
+ <a href="{{ url_for('privacy') }}" class="footer-link">Privacy Policy</a>
164
+ <a href="#" class="footer-link">Terms of Service</a>
165
+ <p>© 2024 DeepFake Detection</p>
166
+ </div>
167
+ </div>
168
+ </footer>
169
+ </div>
170
+ </body>
171
+ </html>