SerialGuy/ai-vs-human
4
1# app.py2import streamlit as st3from predictor import predict_text4 5# Enhanced page configuration6st.set_page_config(7 page_title="AI vs Human Text Detector",8 page_icon="๐ค",9 layout="wide",10 initial_sidebar_state="collapsed"11)12 13# Custom CSS for stunning dark theme with black, gold, and white14st.markdown("""15<style>16 /* Import Google Fonts */17 @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Inter:wght@300;400;500;600&display=swap');18 19 /* Global Reset and Base Styles */20 * {21 margin: 0;22 padding: 0;23 box-sizing: border-box;24 }25 26 .stApp {27 background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 50%, #0f0f0f 100%);28 font-family: 'Inter', sans-serif;29 min-height: 100vh;30 color: #ffffff;31 }32 33 /* Remove Streamlit default styling */34 #MainMenu, .stDeployButton, footer, header, .stDecoration {35 visibility: hidden !important;36 height: 0px !important;37 }38 39 .block-container {40 padding: 2rem 1rem !important;41 max-width: 1200px !important;42 }43 44 /* Main Header Section */45 .hero-section {46 text-align: center;47 padding: 4rem 2rem;48 background: radial-gradient(ellipse at center, rgba(212, 175, 55, 0.1) 0%, transparent 70%);49 border-radius: 20px;50 margin-bottom: 3rem;51 position: relative;52 overflow: hidden;53 }54 55 .hero-section::before {56 content: '';57 position: absolute;58 top: 0;59 left: 0;60 right: 0;61 bottom: 0;62 background: linear-gradient(45deg, transparent 48%, rgba(212, 175, 55, 0.03) 49%, rgba(212, 175, 55, 0.03) 51%, transparent 52%);63 animation: shimmer 3s infinite;64 }65 66 @keyframes shimmer {67 0% { transform: translateX(-100%); }68 100% { transform: translateX(100%); }69 }70 71 .main-title {72 font-family: 'Playfair Display', serif;73 font-size: 4rem;74 font-weight: 700;75 color: #d4af37 !important;76 margin-bottom: 1.5rem;77 text-shadow: 0 4px 8px rgba(212, 175, 55, 0.3);78 position: relative;79 z-index: 1;80 display: block !important;81 visibility: visible !important;82 opacity: 1 !important;83 }84 85 .subtitle {86 font-size: 1.4rem;87 color: rgba(255, 255, 255, 0.8);88 max-width: 600px;89 margin: 0 auto 2rem;90 line-height: 1.6;91 font-weight: 400;92 position: relative;93 z-index: 1;94 }95 96 /* Feature Cards Grid */97 .features-grid {98 display: grid;99 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));100 gap: 2rem;101 margin: 3rem 0;102 padding: 0 1rem;103 }104 105 .feature-card {106 background: linear-gradient(135deg, rgba(26, 26, 26, 0.9) 0%, rgba(18, 18, 18, 0.9) 100%);107 border: 1px solid rgba(212, 175, 55, 0.2);108 border-radius: 16px;109 padding: 2.5rem 2rem;110 text-align: center;111 transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);112 backdrop-filter: blur(10px);113 position: relative;114 overflow: hidden;115 cursor: pointer;116 }117 118 .feature-card::before {119 content: '';120 position: absolute;121 top: 0;122 left: -100%;123 width: 100%;124 height: 100%;125 background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.1) 50%, transparent 100%);126 transition: left 0.6s;127 }128 129 .feature-card:hover::before {130 left: 100%;131 }132 133 .feature-card:hover {134 transform: translateY(-8px) scale(1.02);135 border-color: rgba(212, 175, 55, 0.5);136 box-shadow: 0 20px 40px rgba(212, 175, 55, 0.2);137 }138 139 .feature-icon {140 font-size: 3rem;141 margin-bottom: 1.5rem;142 filter: drop-shadow(0 0 10px rgba(212, 175, 55, 0.3));143 }144 145 .feature-title {146 font-size: 1.4rem;147 font-weight: 600;148 color: #d4af37;149 margin-bottom: 1rem;150 font-family: 'Playfair Display', serif;151 }152 153 .feature-description {154 color: rgba(255, 255, 255, 0.7);155 font-size: 1rem;156 line-height: 1.6;157 }158 159 /* Input Section */160 .input-section {161 background: linear-gradient(135deg, rgba(26, 26, 26, 0.95) 0%, rgba(18, 18, 18, 0.95) 100%);162 border: 1px solid rgba(212, 175, 55, 0.3);163 border-radius: 20px;164 padding: 3rem 2.5rem;165 margin: 3rem 0;166 backdrop-filter: blur(15px);167 position: relative;168 }169 170 .input-title {171 font-size: 1.8rem;172 font-weight: 600;173 color: #d4af37;174 margin-bottom: 2rem;175 font-family: 'Playfair Display', serif;176 display: flex;177 align-items: center;178 gap: 0.5rem;179 }180 181 /* Enhanced Text Area */182 .stTextArea > div > div > textarea {183 background: linear-gradient(145deg, rgba(10, 10, 10, 0.9) 0%, rgba(20, 20, 20, 0.9) 100%) !important;184 border: 2px solid rgba(212, 175, 55, 0.3) !important;185 border-radius: 12px !important;186 padding: 1.5rem !important;187 font-family: 'Inter', sans-serif !important;188 font-size: 1rem !important;189 line-height: 1.7 !important;190 color: #ffffff !important;191 transition: all 0.3s ease !important;192 min-height: 200px !important;193 resize: vertical !important;194 }195 196 .stTextArea > div > div > textarea:focus {197 border-color: #d4af37 !important;198 box-shadow: 0 0 0 3px rgba(212, 175, 55, 0.2), 0 8px 25px rgba(0, 0, 0, 0.3) !important;199 outline: none !important;200 background: linear-gradient(145deg, rgba(15, 15, 15, 0.95) 0%, rgba(25, 25, 25, 0.95) 100%) !important;201 }202 203 .stTextArea > div > div > textarea::placeholder {204 color: rgba(255, 255, 255, 0.5) !important;205 }206 207 /* Custom Button */208 .stButton > button {209 background: linear-gradient(135deg, #d4af37 0%, #b8860b 100%) !important;210 color: #000000 !important;211 border: none !important;212 border-radius: 50px !important;213 padding: 1rem 3rem !important;214 font-size: 1.1rem !important;215 font-weight: 600 !important;216 font-family: 'Inter', sans-serif !important;217 cursor: pointer !important;218 transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;219 box-shadow: 0 8px 25px rgba(212, 175, 55, 0.3) !important;220 text-transform: uppercase !important;221 letter-spacing: 0.5px !important;222 width: 100% !important;223 max-width: 300px !important;224 margin: 2rem auto !important;225 display: block !important;226 }227 228 .stButton > button:hover {229 transform: translateY(-3px) !important;230 box-shadow: 0 15px 35px rgba(212, 175, 55, 0.4) !important;231 background: linear-gradient(135deg, #ffd700 0%, #d4af37 100%) !important;232 }233 234 .stButton > button:active {235 transform: translateY(-1px) !important;236 }237 238 /* Result Cards */239 .result-card {240 background: linear-gradient(135deg, rgba(26, 26, 26, 0.95) 0%, rgba(18, 18, 18, 0.95) 100%);241 border-radius: 20px;242 padding: 2.5rem;243 margin: 2rem 0;244 backdrop-filter: blur(15px);245 animation: slideUpFade 0.6s cubic-bezier(0.4, 0, 0.2, 1);246 position: relative;247 overflow: hidden;248 }249 250 @keyframes slideUpFade {251 from {252 opacity: 0;253 transform: translateY(30px);254 }255 to {256 opacity: 1;257 transform: translateY(0);258 }259 }260 261 .ai-result {262 border: 1px solid rgba(255, 165, 0, 0.3);263 box-shadow: 0 0 30px rgba(255, 165, 0, 0.1);264 }265 266 .human-result {267 border: 1px solid rgba(212, 175, 55, 0.3);268 box-shadow: 0 0 30px rgba(212, 175, 55, 0.1);269 }270 271 .result-title {272 font-size: 1.8rem;273 font-weight: 700;274 margin-bottom: 1rem;275 font-family: 'Playfair Display', serif;276 display: flex;277 align-items: center;278 gap: 0.8rem;279 }280 281 .ai-result .result-title {282 color: #ffa500;283 }284 285 .human-result .result-title {286 color: #d4af37;287 }288 289 .confidence-text {290 font-size: 1.2rem;291 font-weight: 500;292 margin-bottom: 1.5rem;293 color: rgba(255, 255, 255, 0.9);294 }295 296 /* Confidence Progress Bar */297 .confidence-container {298 margin: 1.5rem 0;299 }300 301 .confidence-bar {302 width: 100%;303 height: 12px;304 background: rgba(255, 255, 255, 0.1);305 border-radius: 6px;306 overflow: hidden;307 position: relative;308 }309 310 .confidence-fill {311 height: 100%;312 border-radius: 6px;313 position: relative;314 transition: width 1.5s cubic-bezier(0.4, 0, 0.2, 1);315 animation: glowPulse 2s infinite alternate;316 }317 318 @keyframes glowPulse {319 0% { box-shadow: 0 0 5px currentColor; }320 100% { box-shadow: 0 0 20px currentColor; }321 }322 323 .ai-confidence {324 background: linear-gradient(90deg, #ff8c00, #ffa500);325 color: #ffa500;326 }327 328 .human-confidence {329 background: linear-gradient(90deg, #b8860b, #d4af37);330 color: #d4af37;331 }332 333 .result-description {334 color: rgba(255, 255, 255, 0.8);335 font-size: 1rem;336 line-height: 1.6;337 margin-top: 1.5rem;338 }339 340 /* Warning Card */341 .warning-card {342 background: linear-gradient(135deg, rgba(139, 69, 19, 0.2) 0%, rgba(160, 82, 45, 0.2) 100%);343 border: 1px solid rgba(205, 92, 92, 0.5);344 border-radius: 16px;345 padding: 2rem;346 margin: 2rem 0;347 color: #ff6b6b;348 font-weight: 500;349 text-align: center;350 animation: warningPulse 1s ease-in-out;351 }352 353 @keyframes warningPulse {354 0%, 100% { transform: scale(1); }355 50% { transform: scale(1.02); }356 }357 358 /* Metrics Section */359 .metrics-grid {360 display: grid;361 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));362 gap: 1.5rem;363 margin: 2rem 0;364 }365 366 .metric-card {367 background: linear-gradient(135deg, rgba(26, 26, 26, 0.8) 0%, rgba(18, 18, 18, 0.8) 100%);368 border: 1px solid rgba(212, 175, 55, 0.2);369 border-radius: 12px;370 padding: 1.5rem;371 text-align: center;372 transition: all 0.3s ease;373 }374 375 .metric-card:hover {376 border-color: rgba(212, 175, 55, 0.4);377 transform: translateY(-2px);378 }379 380 .metric-value {381 font-size: 1.8rem;382 font-weight: 700;383 color: #d4af37;384 font-family: 'Playfair Display', serif;385 }386 387 .metric-label {388 font-size: 0.9rem;389 color: rgba(255, 255, 255, 0.7);390 margin-top: 0.5rem;391 }392 393 /* Footer */394 .footer {395 text-align: center;396 margin-top: 4rem;397 padding: 2rem;398 color: rgba(255, 255, 255, 0.6);399 font-size: 0.9rem;400 border-top: 1px solid rgba(212, 175, 55, 0.1);401 }402 403 /* Responsive Design */404 @media (max-width: 768px) {405 .main-title {406 font-size: 2.5rem;407 }408 409 .subtitle {410 font-size: 1.1rem;411 }412 413 .hero-section {414 padding: 2.5rem 1.5rem;415 }416 417 .input-section {418 padding: 2rem 1.5rem;419 }420 421 .features-grid {422 grid-template-columns: 1fr;423 gap: 1.5rem;424 }425 426 .feature-card {427 padding: 2rem 1.5rem;428 }429 430 .result-card {431 padding: 2rem 1.5rem;432 }433 434 .stButton > button {435 padding: 0.8rem 2rem !important;436 font-size: 1rem !important;437 }438 }439 440 @media (max-width: 480px) {441 .main-title {442 font-size: 2rem;443 }444 445 .hero-section {446 padding: 2rem 1rem;447 }448 449 .input-section {450 padding: 1.5rem 1rem;451 }452 453 .feature-card {454 padding: 1.5rem 1rem;455 }456 457 .result-card {458 padding: 1.5rem 1rem;459 }460 }461 462 /* Touch-friendly hover states for mobile */463 @media (hover: none) and (pointer: coarse) {464 .feature-card:hover {465 transform: none;466 }467 468 .feature-card:active {469 transform: scale(0.98);470 transition: transform 0.1s;471 }472 473 .stButton > button:hover {474 transform: none !important;475 }476 477 .stButton > button:active {478 transform: scale(0.98) !important;479 }480 }481</style>482""", unsafe_allow_html=True)483 484# Hero Section with Streamlit fallback485col1, col2, col3 = st.columns([1, 2, 1])486with col2:487 st.markdown("""488 <div class="hero-section">489 <h1 class="main-title">๐ค AI vs Human Detector</h1>490 <p class="subtitle">Unveil the origin of any text with precision. Advanced AI technology meets elegant design to deliver instant, accurate analysis of whether content was crafted by artificial intelligence or human creativity.</p>491 </div>492 """, unsafe_allow_html=True)493 494# Emergency fallback if CSS fails on HuggingFace495if 'title_shown' not in st.session_state:496 st.session_state.title_shown = True497 # This will show if CSS fails498 st.markdown("""499 <script>500 setTimeout(function() {501 var title = document.querySelector('.main-title');502 if (!title || window.getComputedStyle(title).opacity === '0' || window.getComputedStyle(title).visibility === 'hidden') {503 document.querySelector('.backup-title').style.display = 'block';504 }505 }, 100);506 </script>507 """, unsafe_allow_html=True)508 509# Feature Cards510st.markdown("""511<div class="features-grid">512 <div class="feature-card">513 <div class="feature-icon">โก</div>514 <div class="feature-title">Lightning Analysis</div>515 <div class="feature-description">Instant results powered by state-of-the-art machine learning algorithms trained on millions of text samples.</div>516 </div>517 <div class="feature-card">518 <div class="feature-icon">๐ฏ</div>519 <div class="feature-title">Precision Accuracy</div>520 <div class="feature-description">Advanced neural networks deliver industry-leading accuracy in distinguishing AI from human-generated content.</div>521 </div>522 <div class="feature-card">523 <div class="feature-icon">๐</div>524 <div class="feature-title">Privacy Assured</div>525 <div class="feature-description">Your text is processed securely with zero data retention. Complete privacy and confidentiality guaranteed.</div>526 </div>527</div>528""", unsafe_allow_html=True)529 530# Input Section531st.markdown("""532<div class="input-section">533 <div class="input-title">๐ Text Analysis</div>534""", unsafe_allow_html=True)535 536text_input = st.text_area(537 "Text Input",538 height=200,539 placeholder="Paste your text here for AI detection analysis. Longer texts provide more accurate results. Whether it's an article, essay, or any written content, our advanced algorithms will analyze the linguistic patterns and provide instant results...",540 help="Enter the text you want to analyze. The system works best with at least 50 words.",541 key="text_input",542 label_visibility="hidden"543)544 545# Predict Button546if st.button("๐ Analyze Text", key="predict", type="primary"):547 if text_input.strip() == "":548 st.markdown("""549 <div class="warning-card">550 โ ๏ธ <strong>Please Enter Text</strong><br>551 Add some text in the input field above to begin the analysis.552 </div>553 """, unsafe_allow_html=True)554 else:555 # Loading animation556 with st.spinner('๐ง Analyzing linguistic patterns and AI signatures...'):557 prediction, confidence = predict_text(text_input)558 559 # Display Results560 if prediction == 1:561 confidence_percent = confidence * 100562 st.markdown(f"""563 <div class="result-card ai-result">564 <div class="result-title">๐ค AI-Generated Content</div>565 <div class="confidence-text">Detection Confidence: {confidence_percent:.1f}%</div>566 <div class="confidence-container">567 <div class="confidence-bar">568 <div class="confidence-fill ai-confidence" style="width: {confidence_percent}%;"></div>569 </div>570 </div>571 <div class="result-description">572 This text exhibits characteristics commonly found in AI-generated content, including consistent linguistic patterns, uniform sentence structure, and computational writing markers that suggest machine generation.573 </div>574 </div>575 """, unsafe_allow_html=True)576 else:577 confidence_percent = (1 - confidence) * 100578 st.markdown(f"""579 <div class="result-card human-result">580 <div class="result-title">๐ง Human-Written Content</div>581 <div class="confidence-text">Detection Confidence: {confidence_percent:.1f}%</div>582 <div class="confidence-container">583 <div class="confidence-bar">584 <div class="confidence-fill human-confidence" style="width: {confidence_percent}%;"></div>585 </div>586 </div>587 <div class="result-description">588 This text displays natural human writing characteristics, including varied sentence structures, personal voice, authentic linguistic nuances, and the creative inconsistencies typical of human authors.589 </div>590 </div>591 """, unsafe_allow_html=True)592 593 # Analysis Metrics594 st.markdown("### ๐ Detailed Analysis")595 596 col1, col2, col3 = st.columns(3)597 598 word_count = len(text_input.split())599 char_count = len(text_input)600 sentences = text_input.count('.') + text_input.count('!') + text_input.count('?')601 602 with col1:603 st.markdown(f"""604 <div class="metric-card">605 <div class="metric-value">{word_count}</div>606 <div class="metric-label">Words Analyzed</div>607 </div>608 """, unsafe_allow_html=True)609 610 with col2:611 st.markdown(f"""612 <div class="metric-card">613 <div class="metric-value">{"AI" if prediction == 1 else "Human"}</div>614 <div class="metric-label">Classification</div>615 </div>616 """, unsafe_allow_html=True)617 618 with col3:619 complexity = len(set(text_input.lower().split())) / word_count if word_count > 0 else 0620 st.markdown(f"""621 <div class="metric-card">622 <div class="metric-value">{complexity:.2f}</div>623 <div class="metric-label">Vocabulary Diversity</div>624 </div>625 """, unsafe_allow_html=True)626 627st.markdown('</div>', unsafe_allow_html=True)628 629# Footer630st.markdown("""631<div class="footer">632 <p>๐ฌ Powered by Advanced Machine Learning โข ๐ก๏ธ Privacy-First Design โข โก Real-Time Analysis</p>633 <p>Sophisticated AI detection technology for the modern digital age</p>634</div>635""", unsafe_allow_html=True)