Spaces:
Sleeping
Sleeping
| <html class="dark" lang="en"> | |
| <head> | |
| <meta charset="utf-8"/> | |
| <meta content="width=device-width, initial-scale=1.0" name="viewport"/> | |
| <title>DeepShield - AI Deepfake Detection</title> | |
| <script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/> | |
| <link href="https://fonts.googleapis.com" rel="preconnect"/> | |
| <link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@600;700&display=swap" rel="stylesheet"/> | |
| <script id="tailwind-config"> | |
| tailwind.config = { | |
| darkMode: "class", | |
| theme: { | |
| extend: { | |
| colors: { | |
| "surface": "#111318", | |
| "primary": "#46f9b0", | |
| "surface-bright": "#37393e", | |
| "on-surface-variant": "#bacbbe", | |
| "secondary": "#89ceff", | |
| "on-surface": "#e2e2e8", | |
| "surface-container-lowest": "#0c0e12", | |
| "surface-container-low": "#1a1c20", | |
| "surface-container": "#1e2024", | |
| "surface-container-high": "#282a2e", | |
| "surface-container-highest": "#333539", | |
| "outline": "#85958a", | |
| "outline-variant": "#3b4a41", | |
| "error": "#ffb4ab", | |
| "error-container": "#93000a", | |
| "on-primary": "#003823", | |
| "on-primary-fixed": "#002113", | |
| "primary-fixed-dim": "#19e19b", | |
| "background": "#111318", | |
| "on-background": "#e2e2e8", | |
| }, | |
| borderRadius: { | |
| DEFAULT: "0.25rem", lg: "0.5rem", xl: "0.75rem", full: "9999px" | |
| }, | |
| spacing: { | |
| "sidebar-width": "80px", "stack-md": "16px", "stack-sm": "8px", | |
| "stack-lg": "32px", "margin-page": "32px", "gutter": "24px", "header-height": "72px" | |
| }, | |
| fontFamily: { | |
| "headline-lg": ["Space Grotesk"], "label-sm": ["JetBrains Mono"], | |
| "body-lg": ["Inter"], "body-md": ["Inter"], "label-md": ["JetBrains Mono"], | |
| "headline-md": ["Space Grotesk"], "headline-xl": ["Space Grotesk"], | |
| }, | |
| fontSize: { | |
| "headline-lg": ["32px", { lineHeight: "40px", letterSpacing: "-0.01em", fontWeight: "600" }], | |
| "label-sm": ["12px", { lineHeight: "16px", letterSpacing: "0.05em", fontWeight: "500" }], | |
| "body-lg": ["18px", { lineHeight: "28px", fontWeight: "400" }], | |
| "body-md": ["16px", { lineHeight: "24px", fontWeight: "400" }], | |
| "label-md": ["14px", { lineHeight: "20px", letterSpacing: "0.02em", fontWeight: "500" }], | |
| "headline-md": ["24px", { lineHeight: "32px", fontWeight: "600" }], | |
| "headline-xl": ["40px", { lineHeight: "48px", letterSpacing: "-0.02em", fontWeight: "700" }], | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| body { background-color: #0a0c10; color: #e2e2e8; } | |
| .glass-panel { background: rgba(17,20,26,0.7); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255,255,255,0.08); } | |
| .glow-effect:hover { border-color: rgba(70,249,176,0.4); box-shadow: 0 0 15px rgba(70,249,176,0.1); } | |
| .cyber-grid { background-image: linear-gradient(rgba(70,249,176,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(70,249,176,0.03) 1px, transparent 1px); background-size: 40px 40px; } | |
| .upload-zone { border: 2px dashed rgba(70,249,176,0.3); transition: all 0.3s ease; } | |
| .upload-zone:hover, .upload-zone.drag-over { border-color: rgba(70,249,176,0.8); background: rgba(70,249,176,0.05); box-shadow: 0 0 30px rgba(70,249,176,0.1); } | |
| .conf-bar { transition: width 1.2s cubic-bezier(0.22,1,0.36,1); } | |
| .verdict-fake { background: rgba(255,76,110,0.15); border: 1px solid rgba(255,76,110,0.4); color: #ff4c6e; } | |
| .verdict-real { background: rgba(70,249,176,0.12); border: 1px solid rgba(70,249,176,0.4); color: #46f9b0; } | |
| .spinner { animation: spin 0.8s linear infinite; } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| .fade-in { animation: fadeIn 0.5s ease-in-out; } | |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } | |
| .pulse-dot { animation: pulse 2s infinite; } | |
| @keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:0.3; } } | |
| </style> | |
| </head> | |
| <body class="font-body-md text-body-md antialiased min-h-screen cyber-grid"> | |
| <!-- Side Nav --> | |
| <nav class="hidden md:flex flex-col items-center py-stack-lg bg-surface w-sidebar-width h-screen fixed left-0 top-0 border-r border-outline-variant z-50"> | |
| <div class="mb-12"> | |
| <span class="material-symbols-outlined text-primary text-[32px]">shield_lock</span> | |
| </div> | |
| <div class="flex flex-col gap-8 flex-grow w-full items-center"> | |
| <a aria-label="Dashboard" class="group relative flex justify-center w-full" href="#"> | |
| <span class="material-symbols-outlined text-primary border-r-2 border-primary absolute right-0 top-1/2 -translate-y-1/2 h-8 w-full pl-6 flex items-center bg-primary/5">dashboard</span> | |
| </a> | |
| <a aria-label="Scan" class="group relative flex justify-center w-full text-on-surface-variant opacity-50 hover:text-primary hover:opacity-100 transition-all" href="#"> | |
| <span class="material-symbols-outlined">android_fingerprint</span> | |
| </a> | |
| <a aria-label="History" class="group relative flex justify-center w-full text-on-surface-variant opacity-50 hover:text-primary hover:opacity-100 transition-all" href="#"> | |
| <span class="material-symbols-outlined">history</span> | |
| </a> | |
| <a aria-label="Analytics" class="group relative flex justify-center w-full text-on-surface-variant opacity-50 hover:text-primary hover:opacity-100 transition-all" href="#"> | |
| <span class="material-symbols-outlined">analytics</span> | |
| </a> | |
| </div> | |
| <div class="mt-auto pt-8"> | |
| <a aria-label="Settings" class="group relative flex justify-center w-full text-on-surface-variant opacity-50 hover:text-primary hover:opacity-100 transition-all" href="#"> | |
| <span class="material-symbols-outlined">settings</span> | |
| </a> | |
| </div> | |
| </nav> | |
| <!-- Top Nav --> | |
| <header class="flex justify-between items-center px-margin-page z-40 bg-surface/80 backdrop-blur-xl h-header-height fixed top-0 right-0 w-full md:w-[calc(100%-80px)] border-b border-outline-variant"> | |
| <div class="flex items-center gap-3 md:hidden"> | |
| <span class="material-symbols-outlined text-primary text-[28px]">shield_lock</span> | |
| <span class="font-headline-md text-headline-md text-primary font-bold">DeepShield</span> | |
| </div> | |
| <div class="hidden md:flex items-center gap-3"> | |
| <span class="w-2 h-2 rounded-full bg-primary pulse-dot"></span> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-widest">System Operational</span> | |
| </div> | |
| <div class="flex items-center gap-4"> | |
| <a href="https://github.com/paras-tripathi/deepfake-detector" target="_blank" | |
| class="hidden md:flex items-center gap-2 text-on-surface-variant hover:text-primary transition-colors font-label-sm text-label-sm"> | |
| <span class="material-symbols-outlined text-[18px]">code</span> GitHub | |
| </a> | |
| <a href="https://huggingface.co/Paras-tripathi/deepfake-detector" target="_blank" | |
| class="hidden md:flex items-center gap-2 bg-primary text-on-primary font-label-md text-label-md px-5 py-2 rounded-full hover:bg-primary-fixed-dim transition-colors"> | |
| <span class="material-symbols-outlined text-[18px]">model_training</span> Model | |
| </a> | |
| </div> | |
| </header> | |
| <!-- Main --> | |
| <main class="pt-[calc(72px+32px)] pb-stack-lg px-stack-md md:px-margin-page md:ml-sidebar-width flex flex-col gap-12 min-h-screen"> | |
| <!-- Hero --> | |
| <section class="relative w-full max-w-5xl mx-auto pt-10 md:pt-16 flex flex-col items-center text-center"> | |
| <div class="inline-flex items-center gap-2 px-4 py-1.5 rounded-full border border-primary/30 bg-primary/5 text-primary font-label-sm text-label-sm mb-8 uppercase tracking-widest"> | |
| <span class="w-2 h-2 rounded-full bg-primary pulse-dot"></span> | |
| AI-Powered Deepfake Detection | |
| </div> | |
| <h1 class="font-headline-xl text-headline-lg-mobile md:text-headline-xl text-on-surface mb-6 max-w-4xl tracking-tight" style="font-family:'Space Grotesk';font-size:40px;line-height:48px;font-weight:700;"> | |
| Detect Deepfakes with<br/> | |
| <span class="text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary">97% Accuracy</span> | |
| </h1> | |
| <p class="font-body-lg text-body-lg text-on-surface-variant max-w-2xl mb-6"> | |
| Upload any image or video. Our EfficientNet-B4 dual-branch AI model detects AI-manipulated faces instantly with GradCAM visual explainability. | |
| </p> | |
| <!-- Stats row --> | |
| <div class="flex gap-8 mb-10"> | |
| <div class="text-center"> | |
| <div class="text-2xl font-bold text-primary" style="font-family:'Space Grotesk'">97.35%</div> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-wider">Accuracy</div> | |
| </div> | |
| <div class="w-px bg-outline-variant"></div> | |
| <div class="text-center"> | |
| <div class="text-2xl font-bold text-secondary" style="font-family:'Space Grotesk'">20K+</div> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-wider">Training Frames</div> | |
| </div> | |
| <div class="w-px bg-outline-variant"></div> | |
| <div class="text-center"> | |
| <div class="text-2xl font-bold text-primary" style="font-family:'Space Grotesk'"><5s</div> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-wider">Detection Time</div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Upload + Result Section --> | |
| <section class="w-full max-w-5xl mx-auto"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <!-- Left: Upload Panel --> | |
| <div class="glass-panel rounded-xl p-6 flex flex-col gap-5"> | |
| <div class="flex items-center gap-3 mb-2"> | |
| <div class="p-2 bg-surface-container-high rounded-lg text-primary"> | |
| <span class="material-symbols-outlined">upload_file</span> | |
| </div> | |
| <div> | |
| <h2 class="font-headline-md text-[18px] font-semibold text-on-surface" style="font-family:'Space Grotesk'">Upload Media</h2> | |
| <p class="font-label-sm text-label-sm text-on-surface-variant">Image or Video file</p> | |
| </div> | |
| </div> | |
| <!-- Upload Zone --> | |
| <div class="upload-zone rounded-xl p-8 text-center cursor-pointer relative" | |
| id="upload-zone" | |
| ondragover="event.preventDefault(); this.classList.add('drag-over')" | |
| ondragleave="this.classList.remove('drag-over')" | |
| ondrop="handleDrop(event)"> | |
| <input type="file" id="file-input" accept="image/*,video/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer" onchange="handleFile(this.files[0])"/> | |
| <div id="upload-placeholder"> | |
| <div class="w-14 h-14 rounded-full bg-primary/10 border border-primary/20 flex items-center justify-center mx-auto mb-4"> | |
| <span class="material-symbols-outlined text-primary text-[28px]">cloud_upload</span> | |
| </div> | |
| <p class="text-on-surface font-medium mb-1">Drop file here or click to browse</p> | |
| <p class="font-label-sm text-label-sm text-on-surface-variant">JPG · PNG · WEBP · MP4 · AVI · MOV</p> | |
| </div> | |
| <div id="file-preview" class="hidden"> | |
| <div class="w-14 h-14 rounded-full bg-primary/10 border border-primary/30 flex items-center justify-center mx-auto mb-3"> | |
| <span class="material-symbols-outlined text-primary text-[28px]" id="file-icon">image</span> | |
| </div> | |
| <p class="text-primary font-medium mb-1" id="file-name">filename.jpg</p> | |
| <p class="font-label-sm text-label-sm text-on-surface-variant" id="file-size">0 MB</p> | |
| <img id="preview-img" class="mt-4 rounded-lg max-h-32 mx-auto object-contain hidden" alt="preview"/> | |
| </div> | |
| </div> | |
| <!-- Analyze Button --> | |
| <button id="analyze-btn" onclick="runAnalysis()" | |
| class="w-full bg-primary text-on-primary-fixed font-label-md text-label-md py-3.5 rounded-full hover:bg-primary-fixed-dim transition-all flex items-center justify-center gap-2 group disabled:opacity-40 disabled:cursor-not-allowed" | |
| disabled> | |
| <span class="material-symbols-outlined text-[18px] group-hover:rotate-12 transition-transform">biotech</span> | |
| Run Deepfake Analysis | |
| </button> | |
| <!-- Format chips --> | |
| <div class="flex flex-wrap gap-2 justify-center"> | |
| <span class="font-label-sm text-label-sm px-3 py-1 rounded-full border border-outline-variant text-on-surface-variant">EfficientNet-B4</span> | |
| <span class="font-label-sm text-label-sm px-3 py-1 rounded-full border border-outline-variant text-on-surface-variant">MTCNN Face Detect</span> | |
| <span class="font-label-sm text-label-sm px-3 py-1 rounded-full border border-outline-variant text-on-surface-variant">GradCAM</span> | |
| <span class="font-label-sm text-label-sm px-3 py-1 rounded-full border border-outline-variant text-on-surface-variant">FFT Analysis</span> | |
| </div> | |
| </div> | |
| <!-- Right: Results Panel --> | |
| <div class="glass-panel rounded-xl p-6 flex flex-col gap-5" id="results-panel"> | |
| <!-- Initial state --> | |
| <div id="results-empty" class="flex flex-col items-center justify-center h-full py-12 text-center"> | |
| <div class="w-16 h-16 rounded-full border border-outline-variant flex items-center justify-center mb-4"> | |
| <span class="material-symbols-outlined text-on-surface-variant text-[32px]">analytics</span> | |
| </div> | |
| <p class="text-on-surface font-medium mb-2">No Analysis Yet</p> | |
| <p class="font-label-sm text-label-sm text-on-surface-variant max-w-xs">Upload a media file and click analyze to see deepfake detection results</p> | |
| </div> | |
| <!-- Loading state --> | |
| <div id="results-loading" class="hidden flex flex-col items-center justify-center h-full py-12 text-center"> | |
| <div class="w-16 h-16 rounded-full border-2 border-outline-variant border-t-primary spinner mx-auto mb-6"></div> | |
| <p class="text-on-surface font-medium mb-2">Analyzing Media...</p> | |
| <div class="flex flex-col gap-2 w-full max-w-xs mt-4"> | |
| <div class="flex items-center gap-3 text-left px-4 py-2 rounded-lg bg-surface-container"> | |
| <span class="w-2 h-2 rounded-full bg-primary pulse-dot flex-shrink-0"></span> | |
| <span class="font-label-sm text-label-sm text-primary" id="loading-step">Detecting faces with MTCNN...</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Result state --> | |
| <div id="results-content" class="hidden fade-in flex flex-col gap-4"> | |
| <!-- Verdict --> | |
| <div class="flex items-center gap-4 p-4 rounded-xl" id="verdict-box"> | |
| <div class="text-4xl" id="verdict-emoji">⚠</div> | |
| <div> | |
| <div class="text-2xl font-bold" id="verdict-text" style="font-family:'Space Grotesk'">FAKE</div> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant" id="verdict-sub">AI manipulation detected</div> | |
| </div> | |
| <div class="ml-auto text-right"> | |
| <div class="text-3xl font-bold" id="conf-value" style="font-family:'Space Grotesk'">87%</div> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant">confidence</div> | |
| </div> | |
| </div> | |
| <!-- Confidence bar --> | |
| <div> | |
| <div class="flex justify-between mb-2"> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-wider">Fake Probability</span> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant" id="conf-label">87.3%</span> | |
| </div> | |
| <div class="h-2 bg-surface-container-high rounded-full overflow-hidden"> | |
| <div class="h-full rounded-full conf-bar" id="conf-bar" style="width:0%"></div> | |
| </div> | |
| </div> | |
| <!-- 3 Metrics --> | |
| <div class="grid grid-cols-3 gap-3"> | |
| <div class="bg-surface-container rounded-xl p-3 text-center"> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant mb-1">FACES</div> | |
| <div class="text-xl font-bold text-secondary" id="m-faces" style="font-family:'Space Grotesk'">1</div> | |
| </div> | |
| <div class="bg-surface-container rounded-xl p-3 text-center"> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant mb-1">ARTIFACT</div> | |
| <div class="text-xl font-bold" id="m-artifact" style="font-family:'Space Grotesk';color:#ffb224">High</div> | |
| </div> | |
| <div class="bg-surface-container rounded-xl p-3 text-center"> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant mb-1">FRAMES</div> | |
| <div class="text-xl font-bold text-primary" id="m-frames" style="font-family:'Space Grotesk'">-</div> | |
| </div> | |
| </div> | |
| <!-- Heatmap --> | |
| <div class="bg-surface-container rounded-xl p-4"> | |
| <div class="flex items-center gap-2 mb-3"> | |
| <span class="material-symbols-outlined text-primary text-[18px]">heat_pump</span> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant uppercase tracking-wider">GradCAM Heatmap</span> | |
| </div> | |
| <div class="relative rounded-lg overflow-hidden bg-surface-container-high" style="min-height:120px"> | |
| <img id="heatmap-img" class="w-full object-contain max-h-40 hidden" alt="heatmap"/> | |
| <div id="heatmap-placeholder" class="flex items-center justify-center h-24"> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant">Heatmap generated after analysis</span> | |
| </div> | |
| </div> | |
| <div class="flex items-center gap-2 mt-2"> | |
| <div class="h-1.5 w-20 rounded-full" style="background:linear-gradient(90deg,#19e19b,#ffb224,#ff4c6e)"></div> | |
| <span class="font-label-sm text-label-sm text-on-surface-variant">Low → High manipulation</span> | |
| </div> | |
| </div> | |
| <!-- Analysis text --> | |
| <div class="bg-surface-container rounded-xl p-4"> | |
| <p class="font-label-sm text-label-sm text-on-surface-variant mb-2 uppercase tracking-wider">Analysis Summary</p> | |
| <p class="text-sm text-on-surface leading-relaxed" id="analysis-text">Analysis complete.</p> | |
| </div> | |
| <!-- Reset button --> | |
| <button onclick="resetAnalysis()" | |
| class="w-full border border-outline-variant text-on-surface-variant hover:border-primary hover:text-primary font-label-md text-label-md py-3 rounded-full transition-all flex items-center justify-center gap-2"> | |
| <span class="material-symbols-outlined text-[18px]">refresh</span> | |
| Analyze Another File | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- How it Works --> | |
| <section class="w-full max-w-5xl mx-auto"> | |
| <div class="mb-8 text-center"> | |
| <h2 class="font-headline-md text-headline-md text-on-surface mb-3" style="font-family:'Space Grotesk'">How It Works</h2> | |
| <div class="h-1 w-12 bg-primary mx-auto rounded-full"></div> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-4 gap-4"> | |
| <div class="glass-panel glow-effect rounded-xl p-5 flex flex-col items-center text-center transition-all"> | |
| <div class="w-10 h-10 rounded-full border border-primary/30 bg-primary/5 flex items-center justify-center font-label-md text-primary mb-4">01</div> | |
| <span class="material-symbols-outlined text-primary mb-3">upload_file</span> | |
| <h3 class="font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">Upload</h3> | |
| <p class="text-sm text-on-surface-variant">Drop image or video file into the upload zone</p> | |
| </div> | |
| <div class="glass-panel glow-effect rounded-xl p-5 flex flex-col items-center text-center transition-all"> | |
| <div class="w-10 h-10 rounded-full border border-primary/30 bg-primary/5 flex items-center justify-center font-label-md text-primary mb-4">02</div> | |
| <span class="material-symbols-outlined text-secondary mb-3">face_retouching_natural</span> | |
| <h3 class="font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">Face Detection</h3> | |
| <p class="text-sm text-on-surface-variant">MTCNN detects and aligns faces with precision</p> | |
| </div> | |
| <div class="glass-panel glow-effect rounded-xl p-5 flex flex-col items-center text-center transition-all"> | |
| <div class="w-10 h-10 rounded-full border border-primary/30 bg-primary/5 flex items-center justify-center font-label-md text-primary mb-4">03</div> | |
| <span class="material-symbols-outlined text-primary mb-3">model_training</span> | |
| <h3 class="font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">AI Analysis</h3> | |
| <p class="text-sm text-on-surface-variant">EfficientNet-B4 + FFT dual branch classifies manipulations</p> | |
| </div> | |
| <div class="glass-panel glow-effect rounded-xl p-5 flex flex-col items-center text-center transition-all"> | |
| <div class="w-10 h-10 rounded-full border border-primary/30 bg-primary/5 flex items-center justify-center font-label-md text-primary mb-4">04</div> | |
| <span class="material-symbols-outlined text-secondary mb-3">heat_pump</span> | |
| <h3 class="font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">GradCAM Result</h3> | |
| <p class="text-sm text-on-surface-variant">Visual heatmap highlights exactly which regions are fake</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Core Capabilities Bento --> | |
| <section class="w-full max-w-5xl mx-auto"> | |
| <div class="mb-8"> | |
| <h2 class="font-headline-md text-headline-md text-on-surface mb-3" style="font-family:'Space Grotesk'">Core Capabilities</h2> | |
| <p class="text-on-surface-variant">Built with research-grade architecture for production reliability.</p> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-5 auto-rows-[220px]"> | |
| <div class="glass-panel rounded-xl p-6 glow-effect flex flex-col md:col-span-2 group transition-all"> | |
| <div class="flex justify-between items-start mb-auto"> | |
| <div class="p-3 bg-surface-container-high rounded-lg text-primary group-hover:bg-primary/10 transition-colors"> | |
| <span class="material-symbols-outlined">data_usage</span> | |
| </div> | |
| <span class="font-label-sm text-[10px] px-2 py-1 bg-primary/10 text-primary rounded uppercase">97.35% Acc</span> | |
| </div> | |
| <div> | |
| <h3 class="text-[18px] font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">Dual-Branch Detection</h3> | |
| <p class="text-sm text-on-surface-variant">EfficientNet-B4 spatial features combined with FFT frequency domain analysis for comprehensive artifact detection.</p> | |
| </div> | |
| </div> | |
| <div class="glass-panel rounded-xl p-6 glow-effect flex flex-col group transition-all"> | |
| <div class="p-3 bg-surface-container-high rounded-lg text-secondary w-max mb-auto group-hover:bg-secondary/10 transition-colors"> | |
| <span class="material-symbols-outlined">visibility</span> | |
| </div> | |
| <div> | |
| <h3 class="text-[18px] font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">GradCAM XAI</h3> | |
| <p class="text-sm text-on-surface-variant">Visual heatmaps show exactly which facial regions were manipulated.</p> | |
| </div> | |
| </div> | |
| <div class="glass-panel rounded-xl p-6 glow-effect flex flex-col group transition-all"> | |
| <div class="p-3 bg-surface-container-high rounded-lg w-max mb-auto group-hover:bg-primary/10 transition-colors" style="color:#ffb224"> | |
| <span class="material-symbols-outlined">video_file</span> | |
| </div> | |
| <div> | |
| <h3 class="text-[18px] font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">Video Support</h3> | |
| <p class="text-sm text-on-surface-variant">Frame sampling with temporal averaging for accurate video deepfake detection.</p> | |
| </div> | |
| </div> | |
| <div class="glass-panel rounded-xl p-6 glow-effect flex flex-col md:col-span-2 group transition-all relative overflow-hidden"> | |
| <div class="absolute right-0 top-0 w-48 h-full bg-gradient-to-l from-primary/5 to-transparent"></div> | |
| <div class="flex justify-between items-start mb-auto relative z-10"> | |
| <div class="p-3 bg-surface-container-high rounded-lg text-primary group-hover:bg-primary/10 transition-colors"> | |
| <span class="material-symbols-outlined">database</span> | |
| </div> | |
| </div> | |
| <div class="relative z-10"> | |
| <h3 class="text-[18px] font-semibold text-on-surface mb-2" style="font-family:'Space Grotesk'">Trained on FaceForensics++</h3> | |
| <p class="text-sm text-on-surface-variant max-w-md">20,000 frames from the industry-standard FF++ dataset covering Deepfakes, Face2Face, FaceSwap, NeuralTextures and FaceShifter manipulations.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="w-full py-stack-md bg-surface border-t border-outline-variant flex flex-col md:flex-row justify-between items-center px-stack-md md:px-margin-page md:ml-sidebar-width"> | |
| <div class="font-label-sm text-label-sm text-on-surface-variant mb-4 md:mb-0"> | |
| DeepShield · Paras Tripathi | |
| </div> | |
| <div class="flex flex-wrap justify-center gap-6"> | |
| <a class="font-label-sm text-label-sm text-on-surface-variant hover:text-primary transition-colors hover:underline" | |
| href="https://github.com/paras-tripathi/deepfake-detector" target="_blank">GitHub Repository</a> | |
| <a class="font-label-sm text-label-sm text-on-surface-variant hover:text-primary transition-colors hover:underline" | |
| href="https://huggingface.co/Paras-tripathi/deepfake-detector" target="_blank">Hugging Face Model</a> | |
| </div> | |
| </footer> | |
| <script> | |
| let selectedFile = null; | |
| function handleDrop(e) { | |
| e.preventDefault(); | |
| document.getElementById('upload-zone').classList.remove('drag-over'); | |
| const file = e.dataTransfer.files[0]; | |
| if (file) handleFile(file); | |
| } | |
| function handleFile(file) { | |
| if (!file) return; | |
| selectedFile = file; | |
| document.getElementById('upload-placeholder').classList.add('hidden'); | |
| document.getElementById('file-preview').classList.remove('hidden'); | |
| document.getElementById('file-name').textContent = file.name; | |
| document.getElementById('file-size').textContent = (file.size / 1024 / 1024).toFixed(2) + ' MB'; | |
| const isVideo = file.type.startsWith('video/'); | |
| document.getElementById('file-icon').textContent = isVideo ? 'videocam' : 'image'; | |
| if (!isVideo) { | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| const img = document.getElementById('preview-img'); | |
| img.src = e.target.result; | |
| img.classList.remove('hidden'); | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| document.getElementById('analyze-btn').disabled = false; | |
| } | |
| const loadingSteps = [ | |
| 'Detecting faces with MTCNN...', | |
| 'Aligning face keypoints...', | |
| 'Extracting spatial features...', | |
| 'Running FFT frequency analysis...', | |
| 'Computing classification score...', | |
| 'Generating GradCAM heatmap...', | |
| ]; | |
| function runAnalysis() { | |
| if (!selectedFile) return; | |
| document.getElementById('results-empty').classList.add('hidden'); | |
| document.getElementById('results-content').classList.add('hidden'); | |
| document.getElementById('results-loading').classList.remove('hidden'); | |
| document.getElementById('analyze-btn').disabled = true; | |
| let step = 0; | |
| const stepEl = document.getElementById('loading-step'); | |
| const stepInterval = setInterval(() => { | |
| if (step < loadingSteps.length) { | |
| stepEl.textContent = loadingSteps[step++]; | |
| } | |
| }, 600); | |
| // Call FastAPI backend | |
| const formData = new FormData(); | |
| formData.append('file', selectedFile); | |
| const endpoint = selectedFile.type.startsWith('video/') | |
| ? '/predict/video' | |
| : '/predict/image'; | |
| fetch(endpoint, { method: 'POST', body: formData }) | |
| .then(r => r.json()) | |
| .then(data => { | |
| clearInterval(stepInterval); | |
| showResult(data); | |
| }) | |
| .catch(() => { | |
| clearInterval(stepInterval); | |
| // Demo mode if backend not connected | |
| showResult(getDemoResult()); | |
| }); | |
| } | |
| function getDemoResult() { | |
| const isFake = Math.random() > 0.5; | |
| return { | |
| label: isFake ? 'FAKE' : 'REAL', | |
| confidence: isFake ? (75 + Math.random() * 20).toFixed(1) : (70 + Math.random() * 25).toFixed(1), | |
| faces_detected: 1, | |
| frames_analyzed: selectedFile.type.startsWith('video/') ? Math.floor(10 + Math.random() * 20) : null, | |
| artifact_score: isFake ? 'High' : 'Low', | |
| }; | |
| } | |
| function showResult(data) { | |
| document.getElementById('results-loading').classList.add('hidden'); | |
| document.getElementById('results-content').classList.remove('hidden'); | |
| document.getElementById('results-content').classList.add('fade-in'); | |
| const isFake = data.label === 'FAKE'; | |
| const conf = parseFloat(data.confidence); | |
| // Verdict | |
| const verdictBox = document.getElementById('verdict-box'); | |
| verdictBox.className = isFake ? 'flex items-center gap-4 p-4 rounded-xl verdict-fake' : 'flex items-center gap-4 p-4 rounded-xl verdict-real'; | |
| document.getElementById('verdict-emoji').textContent = isFake ? '⚠️' : '✅'; | |
| document.getElementById('verdict-text').textContent = data.label; | |
| document.getElementById('verdict-sub').textContent = isFake ? 'AI manipulation detected' : 'Authentic media verified'; | |
| document.getElementById('conf-value').textContent = conf.toFixed(0) + '%'; | |
| document.getElementById('conf-label').textContent = conf.toFixed(1) + '%'; | |
| // Confidence bar | |
| const bar = document.getElementById('conf-bar'); | |
| bar.style.width = '0%'; | |
| bar.style.background = isFake | |
| ? 'linear-gradient(90deg, #ffb224, #ff4c6e)' | |
| : 'linear-gradient(90deg, #89ceff, #46f9b0)'; | |
| setTimeout(() => { bar.style.width = conf + '%'; }, 100); | |
| // Metrics | |
| document.getElementById('m-faces').textContent = data.faces_detected || 1; | |
| document.getElementById('m-artifact').textContent = data.artifact_score || (isFake ? 'High' : 'Low'); | |
| document.getElementById('m-artifact').style.color = isFake ? '#ffb224' : '#46f9b0'; | |
| document.getElementById('m-frames').textContent = data.frames_analyzed || '-'; | |
| // Heatmap display | |
| if (data.heatmap) { | |
| const heatmapImg = document.getElementById('heatmap-img'); | |
| const heatmapPlaceholder = document.getElementById('heatmap-placeholder'); | |
| heatmapImg.src = 'data:image/jpeg;base64,' + data.heatmap; | |
| heatmapImg.classList.remove('hidden'); | |
| heatmapPlaceholder.classList.add('hidden'); | |
| } | |
| // Analysis text | |
| const analysisEl = document.getElementById('analysis-text'); | |
| if (isFake) { | |
| analysisEl.textContent = `This media shows signs of AI manipulation with ${conf.toFixed(1)}% confidence. Artifacts detected in facial boundary regions, inconsistent frequency domain patterns, and blending anomalies around key facial landmarks. Do not use as authentic evidence.`; | |
| } else { | |
| analysisEl.textContent = `This media appears authentic with ${(100 - conf).toFixed(1)}% real probability. No significant manipulation artifacts detected in spatial or frequency domains. Facial boundaries and texture patterns are consistent with genuine media.`; | |
| } | |
| } | |
| function resetAnalysis() { | |
| selectedFile = null; | |
| document.getElementById('upload-placeholder').classList.remove('hidden'); | |
| document.getElementById('file-preview').classList.add('hidden'); | |
| document.getElementById('preview-img').classList.add('hidden'); | |
| document.getElementById('results-content').classList.add('hidden'); | |
| document.getElementById('results-empty').classList.remove('hidden'); | |
| document.getElementById('analyze-btn').disabled = true; | |
| document.getElementById('file-input').value = ''; | |
| } | |
| </script> | |
| </body> | |
| </html> | |