warlord123456
Deploy HF fix MediaPipe Segfault
30a8d46
Raw
History Blame Contribute Delete
38.1 kB
import React, { useState, useRef } from 'react';
import ReportDashboard from './components/ReportDashboard';
import ModelsOverview from './components/ModelsOverview';
import { useAnalysisPipeline } from './hooks/useAnalysisPipeline';
import {
Shield, Zap, ScanSearch, Info, Lock, BrainCircuit, Target, Database,
BarChart3, Volume2, UploadCloud, CheckCircle2, Loader2, Circle, GitBranch, Settings, Activity, Focus, Camera, Lightbulb, FileText
} from 'lucide-react';
const PIPELINE_STEPS = [
{ label: 'Extracting video frames & audio track', threshold: 5 },
{ label: 'Acoustic Pre-Processing (De-Clipping & Denoising)', threshold: 10 },
{ label: 'Running EfficientNet-B4 visual classifier', threshold: 20 },
{ label: 'Generating GradCAM visual explanations', threshold: 30 },
{ label: 'Frequency domain analysis (DCT + FFT)', threshold: 40 },
{ label: 'Error Level Analysis (JPEG compression)', threshold: 50 },
{ label: 'Biological sensors (Eye Gaze & Heartbeat)', threshold: 60 },
{ label: 'Temporal consistency (Optical Flow & Jitter)', threshold: 68 },
{ label: 'Audio forensics (PyTorch CNN & SyncNet)', threshold: 75 },
{ label: 'Running PyTorch AI Meta-Classifier', threshold: 85 },
{ label: 'Compiling court-grade forensic PDF', threshold: 90 },
];
function App() {
const {
file,
status,
progress,
telemetry,
logs,
jobId,
result,
handleFileUpload,
resetApp
} = useAnalysisPipeline();
const [activeNav, setActiveNav] = useState('analyze');
const fileInputRef = useRef(null);
const [dragActive, setDragActive] = useState(false);
const onDragEnter = (e) => { e.preventDefault(); e.stopPropagation(); setDragActive(true); };
const onDragLeave = (e) => { e.preventDefault(); e.stopPropagation(); setDragActive(false); };
const onDragOver = (e) => { e.preventDefault(); e.stopPropagation(); };
const onDrop = (e) => {
e.preventDefault(); e.stopPropagation(); setDragActive(false);
if (e.dataTransfer.files && e.dataTransfer.files[0]) handleFileUpload(e.dataTransfer.files[0]);
};
const triggerFileSelect = () => fileInputRef.current.click();
const onFileChange = (e) => {
if (e.target.files && e.target.files[0]) handleFileUpload(e.target.files[0]);
};
const getStepStatus = (step, idx) => {
if (progress >= step.threshold + 10 || progress === 100) return 'done';
if (progress >= step.threshold) return 'active';
return 'pending';
};
return (
<>
{/* Navigation Bar */}
<nav className="navbar">
<div className="navbar-inner">
<a className="navbar-brand" href="#" onClick={(e) => { e.preventDefault(); resetApp(); }}>
<div className="navbar-logo"><Shield size={24} color="var(--primary)" /></div>
<div className="navbar-title">Deep<span>Forensics</span></div>
</a>
<div className="navbar-links">
<button
className={`nav-link ${activeNav === 'analyze' ? 'active' : ''}`}
onClick={() => { setActiveNav('analyze'); if (status === 'complete') resetApp(); }}
style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}
>
<ScanSearch size={18} /> Analyze
</button>
<button
className={`nav-link ${activeNav === 'about' ? 'active' : ''}`}
onClick={() => setActiveNav('about')}
style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}
>
<Info size={18} /> How It Works
</button>
<button
className={`nav-link ${activeNav === 'models' ? 'active' : ''}`}
onClick={() => setActiveNav('models')}
style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}
>
<Database size={18} /> Models & Research
</button>
<div className="nav-badge" style={{ display: 'flex', alignItems: 'center', gap: '0.3rem', marginRight: '1.5rem' }}>
<Zap size={14} /> AI Powered
</div>
<div style={{ height: '24px', width: '1px', background: 'var(--glass-border)', margin: '0 0.5rem' }}></div>
<a href="https://github.com/saksham-dev07/Deepfake-Forensics-with-Explainable-AI" target="_blank" rel="noopener noreferrer" className="nav-link" title="Source Code Repository" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '0.5rem' }}>
<GitBranch size={20} />
</a>
</div>
</div>
</nav>
<div className="container">
<div className="page-content">
{/* ====== ANALYZE TAB ====== */}
{activeNav === 'analyze' && (
<>
{/* IDLE STATE: Hero + Upload */}
{status === 'idle' && (
<>
<section className="hero">
<div className="hero-bg-glow"></div>
<div className="hero-badge fade-in-stagger" style={{ animationDelay: '0.1s', display: 'inline-flex', alignItems: 'center', gap: '0.4rem' }}>
<Lock size={14} /> Court-Grade Forensic Analysis
</div>
<h1 className="fade-in-stagger" style={{ animationDelay: '0.2s' }}>Deepfake Detection<br />with Explainable AI</h1>
<p className="hero-subtitle fade-in-stagger" style={{ animationDelay: '0.3s' }}>
An enterprise-grade, multi-modal pipeline for synthetic media detection.
Upload any video or image to generate comprehensive visual evidence and a court-ready PDF report.
</p>
</section>
<div className="stats-grid">
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.4s' }}>
<div className="stat-card-header">
<BrainCircuit size={16} className="stat-card-icon" /> Core Engine
</div>
<div className="stat-card-value">PyTorch Meta-Classifier</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>15-Feature ML Ensemble</div>
</div>
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.5s' }}>
<div className="stat-card-header">
<ScanSearch size={16} className="stat-card-icon" style={{ color: 'var(--primary)' }} /> Explainability
</div>
<div className="stat-card-value">GradCAM & SHAP</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>Visual Evidence Heatmaps</div>
</div>
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.6s' }}>
<div className="stat-card-header">
<Activity size={16} className="stat-card-icon" style={{ color: 'var(--danger)' }} /> Signal Analysis
</div>
<div className="stat-card-value">Frequency & ELA</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>DCT & Compression Analysis</div>
</div>
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.7s' }}>
<div className="stat-card-header">
<Camera size={16} className="stat-card-icon" style={{ color: '#a855f7' }} /> Sensor Forensics
</div>
<div className="stat-card-value">PRNU Extraction</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>Camera Noise Fingerprinting</div>
</div>
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.8s' }}>
<div className="stat-card-header">
<Focus size={16} className="stat-card-icon" style={{ color: 'var(--warning)' }} /> Temporal
</div>
<div className="stat-card-value">Face Geometry</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>Frame-by-frame Jitter Tracking</div>
</div>
<div className="stat-card fade-in-stagger" style={{ animationDelay: '0.9s' }}>
<div className="stat-card-header">
<Volume2 size={16} className="stat-card-icon" style={{ color: 'var(--secondary)' }} /> Audio-Visual
</div>
<div className="stat-card-value">PyTorch 2D-CNN</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)' }}>Anti-Spoofing & SyncNet</div>
</div>
</div>
<div
className={`glass-panel upload-zone ${dragActive ? 'drag-active' : ''}`}
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDragOver={onDragOver}
onDrop={onDrop}
onClick={triggerFileSelect}
>
<input
type="file"
ref={fileInputRef}
onChange={onFileChange}
style={{ display: 'none' }}
accept="video/*,image/*"
/>
<div className="upload-icon-container">
<div className="upload-icon"><UploadCloud size={48} color="var(--primary)" /></div>
</div>
<div className="upload-text">Drag & Drop Media File</div>
<div className="upload-hint">or click to browse from your device</div>
<div className="upload-formats">
<span className="format-tag">MP4</span>
<span className="format-tag">AVI</span>
<span className="format-tag">MOV</span>
<span className="format-tag">MKV</span>
<span className="format-tag">JPG</span>
<span className="format-tag">PNG</span>
<span className="format-tag">WEBP</span>
</div>
</div>
<section className="how-it-works">
<div className="section-title">How It Works</div>
<div className="steps-grid">
<div className="glass-panel step-card step-1">
<div className="step-number">01</div>
<div className="step-title">Upload Media</div>
<div className="step-desc">Upload any video or image file for analysis. Supports all major media formats.</div>
</div>
<div className="glass-panel step-card step-2">
<div className="step-number">02</div>
<div className="step-title">Multi-Modal AI Engine</div>
<div className="step-desc">15 distinct AI sensors extract visual, temporal, and biological anomalies. The PyTorch Meta-Classifier computes the final verdict.</div>
</div>
<div className="glass-panel step-card step-3">
<div className="step-number">03</div>
<div className="step-title">XAI Explanations</div>
<div className="step-desc">GradCAM heatmaps and SHAP features explain exactly why the AI flagged manipulation.</div>
</div>
<div className="glass-panel step-card step-4">
<div className="step-number">04</div>
<div className="step-title">Forensic Report</div>
<div className="step-desc">Download a comprehensive PDF report with visual evidence suitable for court proceedings.</div>
</div>
</div>
</section>
<section className="detailed-features" style={{ marginTop: '5rem', marginBottom: '4rem' }}>
<div className="section-title" style={{ marginBottom: '3rem', textAlign: 'center' }}>How We Detect Deepfakes</div>
<div className="features-grid">
{/* Feature 1 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(34, 211, 238, 0.1)', color: 'var(--primary)' }}>
<Activity size={24} />
</div>
<h3 style={{ color: 'var(--primary)', fontSize: '1.1rem' }}>Spectral & Frequency Analysis</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Real cameras capture high frequencies naturally. AI generators produce mathematically "smooth" pixels. We use <strong>FFT</strong> and <strong>DCT</strong> to detect this unnatural lack of high-frequency energy.
</p>
<ul style={{ color: 'var(--text-muted)', fontSize: '0.85rem', marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: '0.4rem', paddingLeft: '1.2rem' }}>
<li>Switching Noise (SWN) Filters</li>
<li>8x8 Block DCT Disruption</li>
<li>Phase Spectrum Anomalies</li>
</ul>
</div>
{/* Feature 2 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(168, 85, 247, 0.1)', color: '#a855f7' }}>
<ScanSearch size={24} />
</div>
<h3 style={{ color: '#a855f7', fontSize: '1.1rem' }}>Hardware Noise & ELA</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Images have a baked-in Bayer filter pattern (CFA) and uniform JPEG compression. We analyze <strong>Error Level Analysis (ELA)</strong> and missing <strong>CFA Artifacts</strong> to expose splicing.
</p>
<ul style={{ color: 'var(--text-muted)', fontSize: '0.85rem', marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: '0.4rem', paddingLeft: '1.2rem' }}>
<li>Error Level Analysis (ELA)</li>
<li>Color Filter Array (CFA) Democaising</li>
</ul>
</div>
{/* Feature 3 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(251, 191, 36, 0.1)', color: 'var(--warning)' }}>
<Focus size={24} />
</div>
<h3 style={{ color: 'var(--warning)', fontSize: '1.1rem' }}>Face Geometry & Temporal Jitter</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We track 468 facial landmarks across every frame to measure micro-jitters, unnatural head pose variations, and blinking anomalies that human eyes cannot detect.
</p>
<ul style={{ color: 'var(--text-muted)', fontSize: '0.85rem', marginTop: 'auto', display: 'flex', flexDirection: 'column', gap: '0.4rem', paddingLeft: '1.2rem' }}>
<li>Landmark Jitter Detection</li>
<li>Farneback Dense Optical Flow</li>
<li>Eye Aspect Ratio (EAR) Blink Tracking</li>
</ul>
</div>
{/* Feature 4 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(129, 140, 248, 0.1)', color: 'var(--secondary)' }}>
<Volume2 size={24} />
</div>
<h3 style={{ color: 'var(--secondary)', fontSize: '1.1rem' }}>Audio CNN & SyncNet</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We process audio through a lightweight <strong>PyTorch 2D-CNN</strong> to calculate voice spoofing probability, while measuring lip-sync desynchronization using a dual-stream <strong>SyncNet</strong>.
</p>
</div>
{/* Feature 5 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(251, 113, 133, 0.1)', color: 'var(--danger)' }}>
<Activity size={24} />
</div>
<h3 style={{ color: 'var(--danger)', fontSize: '1.1rem' }}>Biological Signal (rPPG)</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Real human faces exhibit microscopic color changes with every heartbeat. AI-generated faces completely lack these <strong>photoplethysmography (rPPG)</strong> signals.
</p>
</div>
{/* Feature 6 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(56, 189, 248, 0.1)', color: 'var(--info)' }}>
<Lightbulb size={24} />
</div>
<h3 style={{ color: 'var(--info)', fontSize: '1.1rem' }}>Illumination & Optics</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We extract and compare the <strong>Corneal Specular Highlights</strong> (reflections in the eyes). GANs notoriously fail to render matching 3D geometric reflections in both eyes.
</p>
</div>
{/* Feature 7 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(52, 211, 153, 0.1)', color: 'var(--success)' }}>
<FileText size={24} />
</div>
<h3 style={{ color: 'var(--success)', fontSize: '1.1rem' }}>EXIF & Metadata Forensics</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We automatically extract and analyze the EXIF payload, detecting manipulation software signatures (Photoshop, Stable Diffusion), stripped metadata, and suspicious timestamps.
</p>
</div>
{/* Feature 8 */}
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(34, 211, 238, 0.1)', color: 'var(--primary)' }}>
<BrainCircuit size={24} />
</div>
<h3 style={{ color: 'var(--primary)', fontSize: '1.1rem' }}>PyTorch AI Meta-Classifier</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Instead of rigid thresholds, a fully trained Multi-Layer Perceptron (MLP) evaluates all 15 visual, biological, and acoustic sensors to determine an ironclad, explainable final verdict.
</p>
</div>
</div>
</section>
</>
)}
{/* PROCESSING STATE */}
{/* PROCESSING STATE */}
{(status === 'uploading' || status === 'processing') && (
<div style={{ maxWidth: '1100px', margin: '2rem auto', animation: 'fade-in-up 0.5s ease-out' }}>
{/* Hero Header */}
<div style={{ textAlign: 'center', marginBottom: '3rem', position: 'relative' }}>
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: '300px', height: '100px', background: 'var(--primary)', filter: 'blur(100px)', opacity: 0.15, pointerEvents: 'none' }}></div>
<div style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '80px', height: '80px', borderRadius: '50%', background: 'rgba(34, 211, 238, 0.05)', border: '1px solid rgba(34, 211, 238, 0.3)', color: 'var(--primary)', marginBottom: '1.5rem', boxShadow: '0 0 30px rgba(34, 211, 238, 0.1)' }}>
{status === 'uploading' ? <UploadCloud size={36} /> : <ScanSearch size={36} className="lucide-spin" style={{ animationDuration: '3s' }} />}
</div>
<h2 style={{ fontSize: '2.5rem', fontWeight: 800, marginBottom: '0.5rem', letterSpacing: '-1px' }}>
{status === 'uploading' ? 'Secure Data Transfer...' : 'Running AI Meta-Classifier...'}
</h2>
<p style={{ color: 'var(--text-secondary)', fontSize: '1.1rem' }}>
{file ? `Target: ${file.name}` : 'Establishing secure connection...'}
</p>
</div>
{/* Main Progress Split */}
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '2rem' }}>
{/* Left: Pipeline Steps */}
<div className="glass-panel" style={{ padding: '2rem', display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.05)', paddingBottom: '1rem' }}>
<div style={{ fontSize: '0.8rem', textTransform: 'uppercase', letterSpacing: '2px', color: 'var(--text-muted)', fontWeight: 700 }}>Forensic Pipeline</div>
<div style={{ fontSize: '2rem', fontWeight: 800, color: 'var(--text-main)', fontFamily: 'monospace' }}>{progress}%</div>
</div>
<div className="progress-bar-bg" style={{ height: '6px', margin: 0, background: 'rgba(0,0,0,0.3)', borderRadius: '10px', overflow: 'hidden' }}>
<div className="progress-bar-fill" style={{ width: `${progress}%`, background: 'linear-gradient(90deg, var(--secondary), var(--primary))', boxShadow: '0 0 10px var(--primary)', transition: 'width 0.4s cubic-bezier(0.4, 0, 0.2, 1)' }}></div>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', marginTop: '0.5rem' }}>
{PIPELINE_STEPS.map((step, idx) => {
const stepStatus = getStepStatus(step, idx);
const isActive = stepStatus === 'active';
const isDone = stepStatus === 'done';
return (
<div key={idx} style={{
display: 'flex', alignItems: 'center', gap: '1rem',
opacity: isDone ? 0.6 : isActive ? 1 : 0.3,
transform: isActive ? 'scale(1.02) translateX(5px)' : 'scale(1) translateX(0)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
background: isActive ? 'rgba(34, 211, 238, 0.08)' : 'transparent',
padding: isActive ? '0.75rem 1rem' : '0.4rem 1rem',
borderRadius: '8px',
border: isActive ? '1px solid rgba(34, 211, 238, 0.2)' : '1px solid transparent'
}}>
<div style={{ color: isDone ? 'var(--success)' : isActive ? 'var(--primary)' : 'var(--text-muted)' }}>
{isDone ? <CheckCircle2 size={18} /> : isActive ? <Loader2 size={18} className="lucide-spin" /> : <Circle size={18} />}
</div>
<div style={{ fontSize: isActive ? '0.95rem' : '0.85rem', fontWeight: isActive ? 600 : 400, color: isActive ? '#fff' : 'inherit' }}>
{step.label}
</div>
</div>
);
})}
</div>
</div>
{/* Right: Technical Readout & Info */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
{/* GPU / Model Stats Card */}
<div className="glass-panel" style={{ padding: '1.5rem', background: 'rgba(10, 15, 30, 0.6)', border: '1px solid rgba(129, 140, 248, 0.15)' }}>
<div style={{ fontSize: '0.75rem', textTransform: 'uppercase', letterSpacing: '1px', color: 'var(--secondary)', fontWeight: 700, marginBottom: '1.25rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<Activity size={14} /> System Telemetry
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
<div style={{ background: 'rgba(0,0,0,0.3)', padding: '1rem', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.03)' }}>
<div style={{ fontSize: '0.65rem', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: '0.35rem' }}>Active Model Weights</div>
<div style={{ fontSize: '0.85rem', color: 'var(--success)', fontWeight: 600, fontFamily: 'monospace' }}>{telemetry?.active_model || 'Loading...'}</div>
</div>
<div style={{ background: 'rgba(0,0,0,0.3)', padding: '1rem', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.03)' }}>
<div style={{ fontSize: '0.65rem', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: '0.35rem' }}>VRAM Allocation</div>
<div style={{ fontSize: '0.85rem', color: 'var(--warning)', fontWeight: 600, fontFamily: 'monospace' }}>{telemetry?.vram_allocation || 'Querying GPU...'}</div>
</div>
<div style={{ background: 'rgba(0,0,0,0.3)', padding: '1rem', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.03)' }}>
<div style={{ fontSize: '0.65rem', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: '0.35rem' }}>Hardware Backend</div>
<div style={{ fontSize: '0.85rem', color: '#fff', fontWeight: 600, fontFamily: 'monospace' }}>{telemetry?.hardware_backend || 'Initializing...'}</div>
</div>
<div style={{ background: 'rgba(0,0,0,0.3)', padding: '1rem', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.03)' }}>
<div style={{ fontSize: '0.65rem', color: 'var(--text-muted)', textTransform: 'uppercase', marginBottom: '0.35rem' }}>Batch Processing</div>
<div style={{ fontSize: '0.85rem', color: '#fff', fontWeight: 600, fontFamily: 'monospace' }}>{telemetry?.batch_processing || 'Waiting for stream...'}</div>
</div>
</div>
</div>
{/* Live Terminal Output Simulation */}
<div className="glass-panel" style={{ padding: '1.5rem', background: '#03050a', border: '1px solid rgba(34, 211, 238, 0.1)', flex: 1, display: 'flex', flexDirection: 'column' }}>
<div style={{ fontSize: '0.75rem', textTransform: 'uppercase', letterSpacing: '1px', color: 'var(--primary)', fontWeight: 700, marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<Shield size={14} /> Live Analysis Log
</div>
<div style={{ fontFamily: 'monospace', fontSize: '0.8rem', color: '#8b9bb4', lineHeight: 1.8, overflow: 'hidden', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', flex: 1, position: 'relative' }}>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '40px', background: 'linear-gradient(to bottom, #03050a 0%, transparent 100%)', zIndex: 1 }}></div>
{logs.map((log, i) => (
<div key={i} style={{ animation: 'fade-in-up 0.3s ease-out' }}>
<span style={{ color: log.type === 'OK' ? 'var(--success)' : log.type === 'WAIT' ? 'var(--warning)' : 'var(--info)' }}>[{log.type}]</span> {log.msg}
</div>
))}
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: 'var(--primary)', marginTop: '0.5rem' }}>
<span style={{ animation: 'pulse 1s infinite' }}>_</span> {progress < 100 ? 'Analyzing tensors...' : 'Finalizing output...'}
</div>
</div>
</div>
</div>
</div>
</div>
)}
{/* COMPLETE STATE */}
{status === 'complete' && result && (
<ReportDashboard result={result} resetApp={resetApp} jobId={jobId} fileName={file?.name} />
)}
</>
)}
{/* ====== MODELS TAB ====== */}
{activeNav === 'models' && <ModelsOverview />}
{/* ====== ABOUT TAB ====== */}
{activeNav === 'about' && (
<div style={{ maxWidth: '800px', margin: '2rem auto' }}>
<section className="hero" style={{ paddingBottom: '1rem' }}>
<h1 style={{ fontSize: '2.5rem' }}>How It Works</h1>
<p className="hero-subtitle">
Our multi-modal forensics pipeline combines state-of-the-art deep learning
with explainable AI techniques to detect and visualize deepfake manipulation.
</p>
</section>
<div className="features-grid">
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(34, 211, 238, 0.1)', color: 'var(--primary)' }}>
<BrainCircuit size={24} />
</div>
<h3 style={{ color: 'var(--primary)', fontSize: '1.1rem' }}>EfficientNet-B4 Classifier</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We use a fine-tuned EfficientNet-B4 backbone trained with a hybrid loss combining
cross-entropy and contrastive learning using the Self-Blended Images (SBI) framework.
The model extracts a 1792-dimensional feature vector from 380×380 face crops, achieving
over 99.8% validation accuracy on FaceForensics++ benchmarks.
</p>
</div>
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(251, 113, 133, 0.1)', color: 'var(--danger)' }}>
<ScanSearch size={24} />
</div>
<h3 style={{ color: 'var(--danger)', fontSize: '1.1rem' }}>GradCAM Visual Explanations</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Gradient-weighted Class Activation Mapping (GradCAM) generates spatial heatmaps
highlighting which regions of the face the neural network focused on when making
its deepfake classification. Red areas indicate strong evidence of manipulation artifacts.
</p>
</div>
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(129, 140, 248, 0.1)', color: 'var(--secondary)' }}>
<BarChart3 size={24} />
</div>
<h3 style={{ color: 'var(--secondary)', fontSize: '1.1rem' }}>SHAP Feature Importance</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
SHapley Additive exPlanations (SHAP) quantify how each facial region contributes
to the model's final decision. This provides human-interpretable evidence that can
be presented alongside the visual heatmaps in forensic proceedings.
</p>
</div>
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(168, 85, 247, 0.1)', color: '#a855f7' }}>
<Activity size={24} />
</div>
<h3 style={{ color: '#a855f7', fontSize: '1.1rem' }}>Frequency & Signal Forensics</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
We analyze the frequency domain (DCT and FFT) to detect unnatural high-frequency suppression typical of GANs. We also measure compression artifacts via Error Level Analysis (ELA) and employ Switching Noise (SWN) filters to reveal hidden splicing boundaries and synthetic noise zero-crossings.
</p>
</div>
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(52, 211, 153, 0.1)', color: 'var(--success)' }}>
<Focus size={24} />
</div>
<h3 style={{ color: 'var(--success)', fontSize: '1.1rem' }}>Biological & Sensor Tracking</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
Deepfakes often fail to replicate perfect temporal consistency and camera hardware fingerprints. Our pipeline tracks facial geometry frame-by-frame to catch temporal jitter, and extracts Photo Response Non-Uniformity (PRNU) to verify sensor consistency across the image.
</p>
</div>
<div className="feature-card-modern">
<div className="feature-card-icon-wrapper" style={{ background: 'rgba(251, 191, 36, 0.1)', color: 'var(--warning)' }}>
<Volume2 size={24} />
</div>
<h3 style={{ color: 'var(--warning)', fontSize: '1.1rem' }}>SyncNet Audio Analysis</h3>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.9rem', lineHeight: '1.6' }}>
For video files with audio, our pipeline uses a SyncNet-based model to detect
micro-desynchronization between lip movements and speech audio — a common
artifact in lip-sync deepfakes that is imperceptible to the human eye.
</p>
</div>
</div>
<div style={{ textAlign: 'center', marginTop: '2rem' }}>
<button className="btn btn-primary" onClick={() => { setActiveNav('analyze'); resetApp(); }} style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5rem' }}>
<ScanSearch size={18} /> Start Analyzing
</button>
</div>
</div>
)}
</div>
</div>
<footer className="footer" style={{ marginTop: '4rem', borderTop: '1px solid var(--glass-border)', padding: '3rem 2rem', background: 'rgba(6, 10, 19, 0.8)', backdropFilter: 'blur(10px)' }}>
<div className="container" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1rem', padding: '0' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', color: 'var(--text-main)', fontWeight: 'bold' }}>
<Shield size={20} color="var(--primary)" /> DeepForensics Platform
</div>
<p style={{ color: 'var(--text-muted)', fontSize: '0.9rem', textAlign: 'center', maxWidth: '600px', lineHeight: '1.6' }}>
Court-grade multimedia forensic analysis powered by EfficientNet-B4, GradCAM spatial grounding, SHAP feature attribution, and SyncNet temporal validation.
</p>
<div style={{ display: 'flex', gap: '1.5rem', marginTop: '1rem', fontSize: '0.85rem' }}>
<span style={{ color: 'var(--success)' }}>Running Custom Fine-Tuned Weights</span>
</div>
<p style={{ color: 'var(--text-muted)', fontSize: '0.8rem', marginTop: '1.5rem' }}>
&copy; {new Date().getFullYear()} DeepForensics. All rights reserved. Version 1.1.0
</p>
</div>
</footer>
</>
);
}
export default App;