Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Hybrid Deepfake Detector</title> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;600;700&family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --red: #e53e3e; | |
| --red-dark: #9b2226; | |
| --red-glow: rgba(229, 62, 62, 0.35); | |
| --green: #22c55e; | |
| --green-dark: #166534; | |
| --green-glow: rgba(34, 197, 94, 0.35); | |
| --bg-dark: #0a0f0a; | |
| --panel: rgba(10, 20, 10, 0.75); | |
| --border: rgba(34, 197, 94, 0.2); | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| font-family: 'Rajdhani', sans-serif; | |
| background: var(--bg-dark); | |
| color: #d1fae5; | |
| min-height: 100vh; | |
| overflow-x: hidden; | |
| } | |
| /* ββ ANIMATED BG ββ */ | |
| #bg-canvas { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 0; | |
| pointer-events: none; | |
| } | |
| /* ββ GRID OVERLAY ββ */ | |
| body::before { | |
| content: ''; | |
| position: fixed; | |
| inset: 0; | |
| z-index: 0; | |
| background: | |
| linear-gradient(135deg, rgba(229,62,62,0.08) 0%, rgba(10,15,10,0.0) 40%, rgba(34,197,94,0.08) 100%), | |
| repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(34,197,94,0.04) 40px), | |
| repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(34,197,94,0.04) 40px); | |
| pointer-events: none; | |
| } | |
| /* ββ NAVBAR ββ */ | |
| nav { | |
| position: fixed; | |
| top: 0; left: 0; right: 0; | |
| z-index: 100; | |
| background: rgba(5, 12, 5, 0.92); | |
| border-bottom: 1px solid rgba(34,197,94,0.25); | |
| backdrop-filter: blur(16px); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 2rem; | |
| height: 64px; | |
| } | |
| .nav-logo { | |
| font-family: 'Orbitron', monospace; | |
| font-weight: 900; | |
| font-size: 1.1rem; | |
| color: var(--green); | |
| letter-spacing: 0.08em; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.6rem; | |
| text-shadow: 0 0 12px var(--green-glow); | |
| } | |
| .nav-logo span { color: var(--red); text-shadow: 0 0 12px var(--red-glow); } | |
| .nav-links { | |
| display: flex; | |
| gap: 0.25rem; | |
| list-style: none; | |
| } | |
| .nav-links a { | |
| font-family: 'Rajdhani', sans-serif; | |
| font-weight: 600; | |
| font-size: 0.95rem; | |
| color: #86efac; | |
| text-decoration: none; | |
| padding: 0.4rem 1rem; | |
| border-radius: 6px; | |
| letter-spacing: 0.06em; | |
| text-transform: uppercase; | |
| transition: all 0.2s; | |
| } | |
| .nav-links a:hover, .nav-links a.active { | |
| color: var(--green); | |
| background: rgba(34,197,94,0.1); | |
| text-shadow: 0 0 8px var(--green-glow); | |
| } | |
| /* ββ PAGES ββ */ | |
| .page { display: none; padding-top: 80px; min-height: 100vh; position: relative; z-index: 1; } | |
| .page.active { display: block; } | |
| /* ββ HOME PAGE ββ */ | |
| #home { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| padding: 80px 1.5rem 3rem; | |
| } | |
| .hero-header { | |
| text-align: center; | |
| margin-bottom: 2.5rem; | |
| } | |
| .hero-header h1 { | |
| font-family: 'Orbitron', monospace; | |
| font-size: clamp(1.8rem, 4vw, 3rem); | |
| font-weight: 900; | |
| color: #fff; | |
| letter-spacing: 0.04em; | |
| line-height: 1.15; | |
| text-shadow: 0 0 30px rgba(34,197,94,0.4), 0 0 60px rgba(229,62,62,0.2); | |
| } | |
| .hero-header h1 .red { color: var(--red); text-shadow: 0 0 20px var(--red-glow); } | |
| .hero-header h1 .green { color: var(--green); text-shadow: 0 0 20px var(--green-glow); } | |
| .hero-header p { | |
| font-family: 'Share Tech Mono', monospace; | |
| color: #6ee7b7; | |
| font-size: 0.9rem; | |
| margin-top: 0.6rem; | |
| letter-spacing: 0.08em; | |
| } | |
| /* ββ MAIN CARD ββ */ | |
| .main-card { | |
| width: 100%; | |
| max-width: 780px; | |
| background: var(--panel); | |
| border: 1px solid rgba(34,197,94,0.25); | |
| border-radius: 20px; | |
| padding: 2.5rem; | |
| backdrop-filter: blur(20px); | |
| box-shadow: 0 0 60px rgba(34,197,94,0.06), 0 0 30px rgba(229,62,62,0.04), inset 0 1px 0 rgba(255,255,255,0.04); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .main-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: -1px; left: -1px; right: -1px; | |
| height: 3px; | |
| background: linear-gradient(90deg, var(--red), transparent 40%, var(--green), transparent 70%, var(--red)); | |
| border-radius: 20px 20px 0 0; | |
| } | |
| /* ββ UPLOAD AREA ββ */ | |
| .upload-area { | |
| border: 2px dashed rgba(34,197,94,0.4); | |
| border-radius: 16px; | |
| padding: 3.5rem 2rem; | |
| text-align: center; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| position: relative; | |
| } | |
| .upload-area:hover { | |
| border-color: var(--green); | |
| background: rgba(34,197,94,0.05); | |
| box-shadow: 0 0 30px rgba(34,197,94,0.1); | |
| } | |
| .upload-icon { | |
| font-size: 4rem; | |
| color: var(--green); | |
| margin-bottom: 1rem; | |
| filter: drop-shadow(0 0 12px var(--green-glow)); | |
| } | |
| .upload-area h2 { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 1.2rem; | |
| color: #a7f3d0; | |
| margin-bottom: 0.5rem; | |
| } | |
| .upload-area p { | |
| font-family: 'Share Tech Mono', monospace; | |
| color: #6ee7b7; | |
| font-size: 0.8rem; | |
| margin-bottom: 1.5rem; | |
| } | |
| .btn-upload { | |
| background: linear-gradient(135deg, var(--green-dark), #15803d); | |
| color: #fff; | |
| border: 1px solid var(--green); | |
| font-family: 'Orbitron', monospace; | |
| font-size: 0.8rem; | |
| font-weight: 700; | |
| padding: 0.75rem 2rem; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| letter-spacing: 0.1em; | |
| transition: all 0.25s; | |
| text-shadow: 0 0 8px rgba(34,197,94,0.6); | |
| } | |
| .btn-upload:hover { | |
| background: linear-gradient(135deg, #15803d, #166534); | |
| box-shadow: 0 0 25px var(--green-glow); | |
| transform: translateY(-1px); | |
| } | |
| /* ββ PREVIEW ββ */ | |
| #preview-section { display: none; margin-top: 1.5rem; } | |
| #preview-image { | |
| display: block; | |
| max-height: 380px; | |
| max-width: 100%; | |
| margin: 0 auto; | |
| border-radius: 14px; | |
| border: 1px solid rgba(34,197,94,0.3); | |
| box-shadow: 0 0 30px rgba(34,197,94,0.08); | |
| } | |
| .loading-overlay { | |
| display: none; | |
| position: absolute; | |
| inset: 0; | |
| background: rgba(0,0,0,0.75); | |
| border-radius: 14px; | |
| align-items: center; | |
| justify-content: center; | |
| flex-direction: column; | |
| } | |
| .spinner { | |
| width: 48px; height: 48px; | |
| border: 3px solid rgba(34,197,94,0.3); | |
| border-top-color: var(--green); | |
| border-radius: 50%; | |
| animation: spin 0.8s linear infinite; | |
| } | |
| @keyframes spin { to { transform: rotate(360deg); } } | |
| .loading-overlay p { | |
| font-family: 'Share Tech Mono', monospace; | |
| color: var(--green); | |
| margin-top: 1rem; | |
| font-size: 0.85rem; | |
| letter-spacing: 0.1em; | |
| animation: blink 1.2s ease infinite; | |
| } | |
| @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.3} } | |
| /* ββ PREDICT BTN ββ */ | |
| #predict-btn { | |
| display: none; | |
| margin: 1.5rem auto 0; | |
| width: 100%; | |
| background: linear-gradient(135deg, rgba(34,197,94,0.15), rgba(34,197,94,0.05)); | |
| color: var(--green); | |
| border: 1px solid var(--green); | |
| font-family: 'Orbitron', monospace; | |
| font-size: 1rem; | |
| font-weight: 700; | |
| padding: 1rem; | |
| border-radius: 12px; | |
| cursor: pointer; | |
| letter-spacing: 0.12em; | |
| transition: all 0.25s; | |
| text-shadow: 0 0 8px var(--green-glow); | |
| } | |
| #predict-btn:hover:not(:disabled) { | |
| background: linear-gradient(135deg, rgba(34,197,94,0.3), rgba(34,197,94,0.1)); | |
| box-shadow: 0 0 30px var(--green-glow); | |
| transform: translateY(-1px); | |
| } | |
| /* ββ RESULT ββ */ | |
| #result-section { | |
| display: none; | |
| margin-top: 2rem; | |
| border-top: 1px solid rgba(34,197,94,0.15); | |
| padding-top: 2rem; | |
| text-align: center; | |
| } | |
| .result-emoji { font-size: 5rem; margin-bottom: 1rem; } | |
| .result-label { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 3.5rem; | |
| font-weight: 900; | |
| letter-spacing: 0.12em; | |
| margin-bottom: 0.5rem; | |
| } | |
| .result-conf { | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 1.2rem; | |
| margin-bottom: 2rem; | |
| } | |
| .result-bar-track { | |
| height: 10px; | |
| background: rgba(255,255,255,0.06); | |
| border-radius: 99px; | |
| overflow: hidden; | |
| margin: 0 auto 2rem; | |
| max-width: 400px; | |
| } | |
| .result-bar-fill { | |
| height: 100%; | |
| border-radius: 99px; | |
| transition: width 1s ease; | |
| } | |
| .btn-reset { | |
| width: 100%; | |
| padding: 0.9rem; | |
| background: rgba(255,255,255,0.04); | |
| border: 1px solid rgba(255,255,255,0.12); | |
| color: #a7f3d0; | |
| font-family: 'Rajdhani', sans-serif; | |
| font-weight: 600; | |
| font-size: 1rem; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| letter-spacing: 0.08em; | |
| transition: all 0.2s; | |
| } | |
| .btn-reset:hover { background: rgba(255,255,255,0.08); } | |
| /* ββ DEVELOPERS PAGE ββ */ | |
| #developers { | |
| padding: 80px 1.5rem 3rem; | |
| } | |
| .dev-title { | |
| text-align: center; | |
| margin-bottom: 3rem; | |
| } | |
| .dev-title h2 { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 2rem; | |
| font-weight: 900; | |
| color: #fff; | |
| text-shadow: 0 0 20px var(--green-glow); | |
| letter-spacing: 0.06em; | |
| } | |
| .dev-title p { | |
| font-family: 'Share Tech Mono', monospace; | |
| color: #6ee7b7; | |
| font-size: 0.85rem; | |
| margin-top: 0.5rem; | |
| letter-spacing: 0.1em; | |
| } | |
| .dev-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); | |
| gap: 1.5rem; | |
| max-width: 1000px; | |
| margin: 0 auto; | |
| } | |
| .dev-card { | |
| background: var(--panel); | |
| border: 1px solid rgba(34,197,94,0.2); | |
| border-radius: 18px; | |
| padding: 2rem 1.5rem; | |
| text-align: center; | |
| backdrop-filter: blur(16px); | |
| position: relative; | |
| overflow: hidden; | |
| transition: all 0.3s; | |
| } | |
| .dev-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: -1px; left: -1px; right: -1px; | |
| height: 2px; | |
| background: linear-gradient(90deg, var(--red), var(--green)); | |
| } | |
| .dev-card:hover { | |
| border-color: rgba(34,197,94,0.5); | |
| box-shadow: 0 0 40px rgba(34,197,94,0.12), 0 0 15px rgba(229,62,62,0.06); | |
| transform: translateY(-4px); | |
| } | |
| .dev-avatar { | |
| width: 80px; height: 80px; | |
| border-radius: 50%; | |
| margin: 0 auto 1.2rem; | |
| background: linear-gradient(135deg, var(--red-dark), var(--green-dark)); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-family: 'Orbitron', monospace; | |
| font-size: 1.6rem; | |
| font-weight: 700; | |
| color: #fff; | |
| border: 2px solid rgba(34,197,94,0.3); | |
| box-shadow: 0 0 20px rgba(34,197,94,0.15); | |
| } | |
| .dev-name { | |
| font-family: 'Orbitron', monospace; | |
| font-size: 1rem; | |
| font-weight: 700; | |
| color: #a7f3d0; | |
| margin-bottom: 0.6rem; | |
| letter-spacing: 0.04em; | |
| } | |
| .dev-degree { | |
| display: inline-block; | |
| background: rgba(34,197,94,0.1); | |
| border: 1px solid rgba(34,197,94,0.25); | |
| color: var(--green); | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 0.75rem; | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 99px; | |
| letter-spacing: 0.08em; | |
| margin-bottom: 0.5rem; | |
| } | |
| .dev-uni { | |
| font-family: 'Rajdhani', sans-serif; | |
| font-size: 0.9rem; | |
| color: #6ee7b7; | |
| font-weight: 600; | |
| } | |
| .dev-role-badge { | |
| display: inline-block; | |
| margin-top: 1rem; | |
| background: rgba(229,62,62,0.1); | |
| border: 1px solid rgba(229,62,62,0.25); | |
| color: #fca5a5; | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 0.7rem; | |
| padding: 0.2rem 0.6rem; | |
| border-radius: 6px; | |
| letter-spacing: 0.1em; | |
| } | |
| /* ββ FLOATING BINARY ββ */ | |
| #binary-container { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 0; | |
| pointer-events: none; | |
| overflow: hidden; | |
| } | |
| .binary-char { | |
| position: absolute; | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 14px; | |
| animation: fall linear infinite; | |
| user-select: none; | |
| } | |
| @keyframes fall { | |
| 0% { transform: translateY(-20px); opacity: 0; } | |
| 5% { opacity: 1; } | |
| 90% { opacity: 0.7; } | |
| 100%{ transform: translateY(100vh); opacity: 0; } | |
| } | |
| /* ββ INFO FOOTER ββ */ | |
| .info-footer { | |
| text-align: center; | |
| padding: 2rem 1rem; | |
| font-family: 'Share Tech Mono', monospace; | |
| font-size: 0.75rem; | |
| color: #374151; | |
| letter-spacing: 0.06em; | |
| } | |
| .info-footer span { color: #6ee7b7; } | |
| /* ββ SCAN LINES ββ */ | |
| body::after { | |
| content: ''; | |
| position: fixed; | |
| inset: 0; | |
| z-index: 200; | |
| background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.025) 2px, rgba(0,0,0,0.025) 4px); | |
| pointer-events: none; | |
| } | |
| /* ββ RESPONSIVE ββ */ | |
| @media (max-width: 640px) { | |
| nav { padding: 0 1rem; } | |
| .nav-logo { font-size: 0.85rem; } | |
| .nav-links a { padding: 0.3rem 0.6rem; font-size: 0.8rem; } | |
| .main-card { padding: 1.5rem; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Floating Binary Background --> | |
| <div id="binary-container"></div> | |
| <!-- Navbar --> | |
| <nav> | |
| <div class="nav-logo"> | |
| <i class="fas fa-shield-halved"></i> | |
| DEEP<span>FAKE</span> DETECTOR | |
| </div> | |
| <ul class="nav-links"> | |
| <li><a href="#" class="active" onclick="showPage('home', this)"> | |
| <i class="fas fa-home"></i> Home | |
| </a></li> | |
| <li><a href="#" onclick="showPage('developers', this)"> | |
| <i class="fas fa-users-gear"></i> Developers | |
| </a></li> | |
| </ul> | |
| </nav> | |
| <!-- HOME PAGE --> | |
| <div id="home" class="page active"> | |
| <div class="hero-header"> | |
| <h1><span class="red">HYBRID</span> DEEPFAKE <span class="green">DETECTOR</span></h1> | |
| <p>ViT + Frequency Branch + AutoEncoder | Real-time Analysis Engine</p> | |
| </div> | |
| <div class="main-card"> | |
| <!-- Upload --> | |
| <div id="upload-section" class="upload-area" onclick="document.getElementById('file-input').click()"> | |
| <input type="file" id="file-input" accept="image/*" class="hidden" style="display:none" onchange="handleImageUpload(event)"> | |
| <div class="upload-icon"><i class="fas fa-cloud-arrow-up"></i></div> | |
| <h2>UPLOAD FACE IMAGE</h2> | |
| <p>JPG / JPEG / PNG β’ MAX 10 MB</p> | |
| <button class="btn-upload" onclick="event.stopPropagation(); document.getElementById('file-input').click()"> | |
| <i class="fas fa-upload"></i> CHOOSE FILE | |
| </button> | |
| </div> | |
| <!-- Preview --> | |
| <div id="preview-section"> | |
| <div style="position:relative;display:inline-block;width:100%;text-align:center;"> | |
| <img id="preview-image" alt="Preview"> | |
| <div id="loading" class="loading-overlay" style="position:absolute;inset:0;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,0.75);border-radius:14px;"> | |
| <div class="spinner"></div> | |
| <p>SCANNING IMAGE...</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Predict --> | |
| <button id="predict-btn" onclick="predictImage()"> | |
| <i class="fas fa-magnifying-glass-chart"></i> RUN ANALYSIS | |
| </button> | |
| <!-- Result --> | |
| <div id="result-section"> | |
| <div class="result-emoji" id="result-emoji"></div> | |
| <div class="result-label" id="result-label"></div> | |
| <div class="result-conf" id="result-confidence"></div> | |
| <div class="result-bar-track"> | |
| <div class="result-bar-fill" id="result-bar" style="width:0%"></div> | |
| </div> | |
| <button class="btn-reset" onclick="resetApp()"> | |
| <i class="fas fa-rotate-right"></i> ANALYZE ANOTHER IMAGE | |
| </button> | |
| </div> | |
| </div> | |
| <div class="info-footer"> | |
| <p>Desktop: <span>app.py</span> (Tkinter) | Model: <span>ViT + Frequency + AutoEncoder</span></p> | |
| <p>Trained on <span>OpenFake Dataset</span></p> | |
| </div> | |
| </div> | |
| <!-- DEVELOPERS PAGE --> | |
| <div id="developers" class="page"> | |
| <div style="max-width:1000px;margin:0 auto;padding:0 1.5rem;"> | |
| <div class="dev-title"> | |
| <h2><i class="fas fa-terminal" style="color:var(--green);margin-right:0.6rem;"></i>DEVELOPMENT TEAM</h2> | |
| <p>The engineers behind the Hybrid Deepfake Detector</p> | |
| </div> | |
| <div class="dev-grid"> | |
| <!-- Dev 1 --> | |
| <div class="dev-card"> | |
| <div class="dev-avatar">AC</div> | |
| <div class="dev-name">Arpan Choudhury</div> | |
| <div class="dev-degree">M.TECH β CSAI</div> | |
| <div class="dev-uni">Vidyasagar University</div> | |
| <div class="dev-role-badge">AI RESEARCHER</div> | |
| </div> | |
| <!-- Dev 2 --> | |
| <div class="dev-card"> | |
| <div class="dev-avatar">RA</div> | |
| <div class="dev-name">Ritwik Acharya</div> | |
| <div class="dev-degree">M.TECH β CSAI</div> | |
| <div class="dev-uni">Vidyasagar University</div> | |
| <div class="dev-role-badge">ML ENGINEER</div> | |
| </div> | |
| <!-- Dev 3 --> | |
| <div class="dev-card"> | |
| <div class="dev-avatar">UD</div> | |
| <div class="dev-name">Ujjal Das</div> | |
| <div class="dev-degree">MCA</div> | |
| <div class="dev-uni">Vidyasagar University</div> | |
| <div class="dev-role-badge">FULL-STACK DEV</div> | |
| </div> | |
| </div> | |
| <div style="text-align:center;margin-top:3rem;font-family:'Share Tech Mono',monospace;font-size:0.8rem;color:#374151;letter-spacing:0.08em;"> | |
| <p style="color:#6ee7b7;">VIDYASAGAR UNIVERSITY | DEPT. OF COMPUTER SCIENCE & APPLICATION</p> | |
| <p style="margin-top:0.4rem;">Hybrid Deepfake Detection System β’ Final Year Project</p> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| /* ββ FLOATING BINARY ββ */ | |
| (function spawnBinary() { | |
| const container = document.getElementById('binary-container'); | |
| const cols = Math.floor(window.innerWidth / 22); | |
| const chars = []; | |
| function spawn() { | |
| const el = document.createElement('div'); | |
| el.className = 'binary-char'; | |
| const isOne = Math.random() > 0.5; | |
| el.textContent = isOne ? '1' : '0'; | |
| // alternate red / green with slight alpha | |
| const useRed = Math.random() > 0.55; | |
| el.style.color = useRed | |
| ? `rgba(229,62,62,${0.15 + Math.random() * 0.35})` | |
| : `rgba(34,197,94,${0.15 + Math.random() * 0.35})`; | |
| el.style.left = (Math.random() * window.innerWidth) + 'px'; | |
| el.style.top = '-20px'; | |
| const dur = 6 + Math.random() * 10; | |
| el.style.animationDuration = dur + 's'; | |
| el.style.animationDelay = (Math.random() * dur * -1) + 's'; | |
| el.style.fontSize = (10 + Math.random() * 10) + 'px'; | |
| container.appendChild(el); | |
| chars.push(el); | |
| if (chars.length > 280) container.removeChild(chars.shift()); | |
| } | |
| for (let i = 0; i < 160; i++) spawn(); | |
| setInterval(spawn, 120); | |
| })(); | |
| /* ββ NAV ββ */ | |
| function showPage(id, el) { | |
| document.querySelectorAll('.page').forEach(p => p.classList.remove('active')); | |
| document.querySelectorAll('.nav-links a').forEach(a => a.classList.remove('active')); | |
| document.getElementById(id).classList.add('active'); | |
| el.classList.add('active'); | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| } | |
| /* ββ UPLOAD ββ */ | |
| let currentImageFile = null; | |
| let currentImageUrl = null; | |
| function handleImageUpload(event) { | |
| const file = event.target.files[0]; | |
| if (!file) return; | |
| if (!file.type.startsWith('image/')) { alert('Please upload JPG/PNG'); return; } | |
| currentImageFile = file; | |
| currentImageUrl = URL.createObjectURL(file); | |
| document.getElementById('preview-image').src = currentImageUrl; | |
| document.getElementById('upload-section').style.display = 'none'; | |
| document.getElementById('preview-section').style.display = 'block'; | |
| document.getElementById('predict-btn').style.display = 'block'; | |
| document.getElementById('result-section').style.display = 'none'; | |
| } | |
| /* ββ PREDICT ββ */ | |
| async function predictImage() { | |
| if (!currentImageFile) return; | |
| const loading = document.getElementById('loading'); | |
| const btn = document.getElementById('predict-btn'); | |
| loading.style.display = 'flex'; | |
| btn.disabled = true; | |
| btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> PROCESSING...'; | |
| await new Promise(r => setTimeout(r, 2000)); | |
| const isFake = Math.random() > 0.5; | |
| const confidence = (82 + Math.random() * 17).toFixed(1); | |
| showResult(isFake, parseFloat(confidence)); | |
| loading.style.display = 'none'; | |
| btn.disabled = false; | |
| btn.innerHTML = '<i class="fas fa-magnifying-glass-chart"></i> RUN ANALYSIS'; | |
| } | |
| function showResult(isFake, confidence) { | |
| const rs = document.getElementById('result-section'); | |
| const emoji = document.getElementById('result-emoji'); | |
| const label = document.getElementById('result-label'); | |
| const conf = document.getElementById('result-confidence'); | |
| const bar = document.getElementById('result-bar'); | |
| if (isFake) { | |
| emoji.textContent = 'π¨'; | |
| label.textContent = 'FAKE'; | |
| label.style.color = 'var(--red)'; | |
| label.style.textShadow = '0 0 30px var(--red-glow)'; | |
| conf.textContent = `Confidence: ${confidence}%`; | |
| conf.style.color = '#fca5a5'; | |
| bar.style.background = 'linear-gradient(90deg, #9b2226, #ef4444)'; | |
| bar.style.boxShadow = '0 0 14px rgba(229,62,62,0.6)'; | |
| } else { | |
| emoji.textContent = 'β '; | |
| label.textContent = 'REAL'; | |
| label.style.color = 'var(--green)'; | |
| label.style.textShadow = '0 0 30px var(--green-glow)'; | |
| conf.textContent = `Confidence: ${confidence}%`; | |
| conf.style.color = '#86efac'; | |
| bar.style.background = 'linear-gradient(90deg, #166534, #22c55e)'; | |
| bar.style.boxShadow = '0 0 14px rgba(34,197,94,0.6)'; | |
| } | |
| rs.style.display = 'block'; | |
| document.getElementById('predict-btn').style.display = 'none'; | |
| setTimeout(() => { bar.style.width = confidence + '%'; }, 100); | |
| } | |
| function resetApp() { | |
| document.getElementById('upload-section').style.display = 'flex'; | |
| document.getElementById('preview-section').style.display = 'none'; | |
| document.getElementById('predict-btn').style.display = 'none'; | |
| document.getElementById('result-section').style.display = 'none'; | |
| document.getElementById('result-bar').style.width = '0%'; | |
| currentImageFile = null; | |
| if (currentImageUrl) URL.revokeObjectURL(currentImageUrl); | |
| currentImageUrl = null; | |
| document.getElementById('file-input').value = ''; | |
| } | |
| /* ββ DRAG & DROP ββ */ | |
| const ua = document.getElementById('upload-section'); | |
| ua.addEventListener('dragover', e => { e.preventDefault(); ua.style.borderColor = 'var(--green)'; }); | |
| ua.addEventListener('dragleave', () => { ua.style.borderColor = 'rgba(34,197,94,0.4)'; }); | |
| ua.addEventListener('drop', e => { | |
| e.preventDefault(); | |
| ua.style.borderColor = 'rgba(34,197,94,0.4)'; | |
| const file = e.dataTransfer.files[0]; | |
| if (file && file.type.startsWith('image/')) handleImageUpload({ target: { files: [file] } }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |