Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>RADAI / Analysis</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Inter:wght@400;500;600;700&display=swap" | |
| rel="stylesheet" /> | |
| <style> | |
| /* ───────────────────────────────────────────────────────────── | |
| DESIGN SYSTEM — forensic tool aesthetic | |
| Palette: near-white bg, near-black text, grey structure, | |
| muted red (#b91c1c) for danger, amber for warnings. | |
| No gradients. No box-shadows beyond hairlines. No rounding > 6px. | |
| ───────────────────────────────────────────────────────────── */ | |
| :root { | |
| --bg: #f4f4f4; | |
| --surface: #ffffff; | |
| --border: #d4d4d4; | |
| --border-lg: #e5e5e5; | |
| --text: #111111; | |
| --text2: #525252; | |
| --text3: #737373; | |
| --danger: #b91c1c; | |
| --danger-dim: rgba(185, 28, 28, 0.07); | |
| --warn: #92400e; | |
| --warn-dim: rgba(146, 64, 14, 0.07); | |
| --ok: #14532d; | |
| --ok-dim: rgba(20, 83, 45, 0.07); | |
| --mono: 'IBM Plex Mono', monospace; | |
| --sans: 'Inter', system-ui, sans-serif; | |
| } | |
| [data-theme="dark"] { | |
| --bg: #0f0f0f; | |
| --surface: #1a1a1a; | |
| --border: #303030; | |
| --border-lg: #242424; | |
| --text: #e5e5e5; | |
| --text2: #a3a3a3; | |
| --text3: #737373; | |
| --danger: #ef4444; | |
| --danger-dim: rgba(239, 68, 68, 0.08); | |
| --warn: #f59e0b; | |
| --warn-dim: rgba(245, 158, 11, 0.08); | |
| --ok: #22c55e; | |
| --ok-dim: rgba(34, 197, 94, 0.08); | |
| } | |
| *, | |
| *::before, | |
| *::after { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| html, | |
| body { | |
| height: 100%; | |
| } | |
| body { | |
| font-family: var(--sans); | |
| background: var(--bg); | |
| color: var(--text); | |
| font-size: 13px; | |
| line-height: 1.5; | |
| -webkit-font-smoothing: antialiased; | |
| overflow: hidden; | |
| } | |
| /* ── Panel ── */ | |
| .panel { | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| scrollbar-width: thin; | |
| scrollbar-color: var(--border) transparent; | |
| } | |
| .panel::-webkit-scrollbar { | |
| width: 4px; | |
| } | |
| .panel::-webkit-scrollbar-thumb { | |
| background: var(--border); | |
| } | |
| /* ── Top bar ── */ | |
| .topbar { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 10px 14px; | |
| background: var(--surface); | |
| border-bottom: 1px solid var(--border); | |
| flex-shrink: 0; | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| } | |
| .brand { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .brand-mark { | |
| width: 20px; | |
| height: 20px; | |
| display: grid; | |
| place-items: center; | |
| color: var(--text); | |
| } | |
| .brand-mark svg { | |
| width: 18px; | |
| height: 18px; | |
| } | |
| .brand-name { | |
| font-size: 12px; | |
| font-weight: 700; | |
| letter-spacing: 0.5px; | |
| text-transform: uppercase; | |
| color: var(--text); | |
| } | |
| .brand-sep { | |
| width: 1px; | |
| height: 12px; | |
| background: var(--border); | |
| } | |
| .brand-sub { | |
| font-size: 10px; | |
| color: var(--text3); | |
| font-family: var(--mono); | |
| letter-spacing: 0.5px; | |
| } | |
| .topbar-right { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .topbar-chip { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| font-weight: 500; | |
| color: var(--text3); | |
| border: 1px solid var(--border); | |
| padding: 2px 8px; | |
| border-radius: 2px; | |
| white-space: nowrap; | |
| } | |
| .theme-toggle { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| font-weight: 500; | |
| color: var(--text2); | |
| background: none; | |
| border: 1px solid var(--border); | |
| padding: 2px 8px; | |
| border-radius: 2px; | |
| cursor: pointer; | |
| transition: color 0.1s, border-color 0.1s; | |
| } | |
| .theme-toggle:hover { | |
| color: var(--text); | |
| border-color: var(--text2); | |
| } | |
| /* ── Content area ── */ | |
| .content { | |
| flex: 1; | |
| padding: 14px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 12px; | |
| } | |
| /* ── Empty state ── */ | |
| .empty { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| text-align: center; | |
| padding: 40px 24px; | |
| } | |
| .empty-icon { | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 48px; | |
| height: 48px; | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| color: var(--text3); | |
| margin-bottom: 6px; | |
| } | |
| .empty-icon svg { | |
| width: 22px; | |
| height: 22px; | |
| } | |
| .empty-title { | |
| font-size: 14px; | |
| font-weight: 600; | |
| color: var(--text); | |
| } | |
| .empty-desc { | |
| font-size: 12px; | |
| color: var(--text3); | |
| line-height: 1.55; | |
| max-width: 220px; | |
| } | |
| /* ── Section label ── */ | |
| .section-label { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| font-weight: 500; | |
| letter-spacing: 0.8px; | |
| text-transform: uppercase; | |
| color: var(--text3); | |
| margin-bottom: 6px; | |
| } | |
| /* ── Verdict card ── */ | |
| .verdict-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| padding: 14px; | |
| } | |
| .verdict-top { | |
| display: flex; | |
| align-items: flex-start; | |
| justify-content: space-between; | |
| gap: 12px; | |
| } | |
| .verdict-label { | |
| font-size: 28px; | |
| font-weight: 700; | |
| letter-spacing: -1px; | |
| line-height: 1; | |
| color: var(--text); | |
| } | |
| .verdict-meta { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: flex-end; | |
| gap: 4px; | |
| flex-shrink: 0; | |
| } | |
| .confidence-value { | |
| font-size: 28px; | |
| font-weight: 700; | |
| letter-spacing: -1px; | |
| line-height: 1; | |
| font-family: var(--mono); | |
| color: var(--text); | |
| } | |
| .confidence-label { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| color: var(--text3); | |
| letter-spacing: 0.5px; | |
| } | |
| .verdict-desc { | |
| font-size: 12px; | |
| color: var(--text2); | |
| margin-top: 8px; | |
| line-height: 1.5; | |
| } | |
| /* ── Status bar ── */ | |
| .status-bar { | |
| margin-top: 12px; | |
| padding-top: 10px; | |
| border-top: 1px solid var(--border-lg); | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| } | |
| .status-dot { | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| flex-shrink: 0; | |
| } | |
| .status-text { | |
| font-size: 11px; | |
| font-family: var(--mono); | |
| color: var(--text2); | |
| } | |
| /* ── Risk bar ── */ | |
| .risk-bar-wrap { | |
| margin-top: 12px; | |
| } | |
| .risk-bar-header { | |
| display: flex; | |
| justify-content: space-between; | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| color: var(--text3); | |
| margin-bottom: 5px; | |
| } | |
| .risk-bar-track { | |
| height: 3px; | |
| background: var(--border); | |
| border-radius: 2px; | |
| overflow: hidden; | |
| } | |
| .risk-bar-fill { | |
| height: 100%; | |
| width: 0%; | |
| border-radius: 2px; | |
| transition: width 0.6s ease; | |
| } | |
| /* ── How it works ── */ | |
| .how-it-works-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 4px; | |
| overflow: hidden; | |
| } | |
| .hiw-header { | |
| padding: 10px 14px; | |
| border-bottom: 1px solid var(--border-lg); | |
| } | |
| .hiw-body { | |
| padding: 12px 14px; | |
| } | |
| .hiw-text { | |
| font-size: 12px; | |
| color: var(--text2); | |
| line-height: 1.6; | |
| margin-bottom: 8px; | |
| } | |
| .hiw-list { | |
| list-style-type: disc; | |
| padding-left: 20px; | |
| margin-bottom: 0px; | |
| } | |
| .hiw-list li { | |
| font-size: 12px; | |
| color: var(--text2); | |
| line-height: 1.6; | |
| margin-bottom: 4px; | |
| } | |
| /* ── Footer ── */ | |
| .panel-footer { | |
| padding: 8px 14px; | |
| border-top: 1px solid var(--border); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| flex-shrink: 0; | |
| background: var(--surface); | |
| } | |
| .footer-left { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| color: var(--text3); | |
| } | |
| .footer-right { | |
| font-size: 10px; | |
| font-family: var(--mono); | |
| color: var(--text3); | |
| } | |
| /* ── Loading state ── */ | |
| .loading-bar { | |
| height: 2px; | |
| background: var(--border); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .loading-bar::after { | |
| content: ''; | |
| position: absolute; | |
| left: -40%; | |
| top: 0; | |
| width: 40%; | |
| height: 100%; | |
| background: var(--text3); | |
| animation: loading-slide 1.2s ease-in-out infinite; | |
| } | |
| @keyframes loading-slide { | |
| 0% { | |
| left: -40%; | |
| } | |
| 100% { | |
| left: 110%; | |
| } | |
| } | |
| /* ── Data container toggle ── */ | |
| #dataContainer { | |
| display: none; | |
| } | |
| #dataContainer.visible { | |
| display: contents; | |
| } | |
| #emptyState { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| flex: 1; | |
| } | |
| #emptyState.hidden { | |
| display: none; | |
| } | |
| /* ── Stopped state ── */ | |
| .stopped-banner { | |
| background: var(--warn-dim); | |
| border: 1px solid currentColor; | |
| color: var(--warn); | |
| border-radius: 3px; | |
| padding: 9px 12px; | |
| font-size: 11px; | |
| font-family: var(--mono); | |
| margin-bottom: 12px; | |
| } | |
| /* ── Action buttons ── */ | |
| .btn-row { | |
| display: grid; | |
| grid-template-columns: 1fr auto; | |
| gap: 6px; | |
| margin-bottom: 2px; | |
| flex-shrink: 0; | |
| } | |
| .btn { | |
| border: 1px solid var(--border); | |
| border-radius: 3px; | |
| padding: 8px 12px; | |
| background: var(--surface); | |
| color: var(--text); | |
| font-family: var(--mono); | |
| font-size: 11px; | |
| font-weight: 500; | |
| cursor: pointer; | |
| letter-spacing: 0.3px; | |
| transition: background 0.1s, border-color 0.1s; | |
| } | |
| .btn:hover:not(:disabled) { | |
| background: var(--border-lg); | |
| } | |
| .btn:disabled { | |
| opacity: 0.35; | |
| cursor: default; | |
| } | |
| .btn-danger { | |
| color: var(--danger); | |
| border-color: var(--danger); | |
| } | |
| .btn-danger:hover:not(:disabled) { | |
| background: var(--danger-dim); | |
| } | |
| </style> | |
| </head> | |
| <body data-theme="light"> | |
| <div class="panel" id="panel"> | |
| <!-- Sticky topbar --> | |
| <div class="topbar"> | |
| <div class="brand"> | |
| <div class="brand-mark"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" | |
| stroke-linejoin="round"> | |
| <polygon | |
| points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" /> | |
| </svg> | |
| </div> | |
| <span class="brand-name">RADAI</span> | |
| <div class="brand-sep"></div> | |
| <span class="brand-sub">FORENSIC ANALYSIS</span> | |
| </div> | |
| <div class="topbar-right"> | |
| <div class="topbar-chip" id="statusChip">IDLE</div> | |
| <button class="theme-toggle" id="themeBtn">DARK</button> | |
| </div> | |
| </div> | |
| <!-- Loading bar (hidden by default, shown during initial load) --> | |
| <div class="loading-bar" id="loadingBar" style="display:none"></div> | |
| <!-- Main content --> | |
| <div class="content"> | |
| <!-- Action buttons --> | |
| <div class="btn-row"> | |
| <button class="btn" id="scanBtn">SCAN IMAGES</button> | |
| <button class="btn btn-danger" id="stopBtn" disabled>STOP</button> | |
| </div> | |
| <!-- Empty state --> | |
| <div id="emptyState"> | |
| <div class="empty"> | |
| <div class="empty-icon"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> | |
| <circle cx="11" cy="11" r="8" /> | |
| <line x1="21" y1="21" x2="16.65" y2="16.65" /> | |
| </svg> | |
| </div> | |
| <div class="empty-title">No scan data</div> | |
| <div class="empty-desc">Click "SCAN IMAGES" to analyze the current webpage for AI-generated content.</div> | |
| </div> | |
| </div> | |
| <!-- Data sections --> | |
| <div id="dataContainer"> | |
| <!-- Stopped banner (shown only when scan was stopped) --> | |
| <div class="stopped-banner" id="stoppedBanner" style="display:none"> | |
| SCAN INTERRUPTED — incomplete data. Run a full scan for complete results. | |
| </div> | |
| <!-- Verdict --> | |
| <div class="verdict-card"> | |
| <div class="verdict-top"> | |
| <div> | |
| <div class="verdict-label" id="verdictLabel">—</div> | |
| <div class="verdict-desc" id="verdictDesc" style="white-space: pre-line;">—</div> | |
| </div> | |
| </div> | |
| <div class="risk-bar-wrap"> | |
| <div class="risk-bar-header"> | |
| <span>Risk score</span> | |
| <span id="riskBarLabel">—</span> | |
| </div> | |
| <div class="risk-bar-track"> | |
| <div class="risk-bar-fill" id="riskBarFill"></div> | |
| </div> | |
| </div> | |
| <div class="status-bar"> | |
| <div class="status-dot" id="statusDot"></div> | |
| <div class="status-text" id="statusText">—</div> | |
| </div> | |
| </div> | |
| <!-- How it works --> | |
| <div class="how-it-works-card" id="howItWorks"> | |
| <div class="hiw-header"> | |
| <div class="section-label">How detection works</div> | |
| </div> | |
| <div class="hiw-body"> | |
| <div class="hiw-text"> | |
| Our system utilizes a dual-model ensemble to assess images for forensic anomalies: | |
| </div> | |
| <ul class="hiw-list"> | |
| <li><strong>Vision-Language Model</strong> (OpenCLIP) for broad semantic and texture analysis</li> | |
| <li><strong>Secondary CNN Model</strong> (ConvNeXt) for deep feature pattern matching</li> | |
| </ul> | |
| <div class="hiw-text" style="margin-top: 10px;"> | |
| The algorithms flag synthetic origins by detecting subtle, generated inconsistencies in: <strong>texture | |
| frequencies, lighting coherence, and spatial composition.</strong> | |
| </div> | |
| </div> | |
| </div> | |
| </div><!-- /dataContainer --> | |
| </div><!-- /content --> | |
| <!-- Footer --> | |
| <div class="panel-footer"> | |
| <div class="footer-left" id="footerLeft">RADAI v2.0</div> | |
| <div class="footer-right" id="footerRight">—</div> | |
| </div> | |
| </div><!-- /panel --> | |
| <script src="sidepanel.js"></script> | |
| </body> | |
| </html> |