Spaces:
Runtime error
Runtime error
| === index.html === | |
| <!DOCTYPE html> | |
| <html lang="en" class="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Brutally Honest AI Nude Rater</title> | |
| <meta name="description" content="Get brutally honest AI ratings for your nude photos. Upload and receive detailed analysis from our unfiltered AI system."> | |
| <link rel="stylesheet" href="assets/css/style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script> | |
| tailwind.config = { | |
| darkMode: 'class', | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#7c3aed', | |
| secondary: '#10b981', | |
| dark: '#1e293b' | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body class="bg-gray-100 dark:bg-dark min-h-screen"> | |
| <!-- Age Verification Overlay --> | |
| <div id="ageVerification" class="fixed inset-0 bg-black bg-opacity-90 z-50 flex items-center justify-center px-4"> | |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-8 text-center"> | |
| <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">Age Verification Required</h2> | |
| <p class="text-gray-600 dark:text-gray-300 mb-6">You must be 18 years or older to access this content. By entering, you confirm you are of legal age.</p> | |
| <div class="space-y-4"> | |
| <button id="enterSite" class="w-full bg-primary hover:bg-primary-600 text-white font-bold py-3 px-6 rounded-lg transition-all transform hover:scale-105"> | |
| I am 18 or older - Enter Site | |
| </button> | |
| <button id="exitSite" class="w-full bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-3 px-6 rounded-lg transition-all"> | |
| I am under 18 - Exit | |
| </button> | |
| </div> | |
| <p class="text-xs text-gray-500 dark:text-gray-400 mt-6">This site contains adult content intended for mature audiences only.</p> | |
| </div> | |
| </div> | |
| <!-- Main Content (hidden until age verification) --> | |
| <div id="mainContent" class="hidden"> | |
| <header class="bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700"> | |
| <div class="container mx-auto px-4 py-4"> | |
| <div class="flex justify-between items-center"> | |
| <h1 class="text-xl font-bold text-gray-900 dark:text-white">Brutally Honest AI Nude Rater</h1> | |
| <div class="flex items-center space-x-4"> | |
| <button id="themeToggle" class="p-2 rounded-lg bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300"> | |
| <i data-feather="moon" class="w-5 h-5"></i> | |
| </button> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="text-xs text-gray-500 hover:text-primary transition-colors">Built with anycoder</a> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="container mx-auto px-4 py-8"> | |
| <section class="max-w-4xl mx-auto text-center mb-12"> | |
| <h1 class="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">Brutally Honest AI Nude Ratings</h1> | |
| <p class="text-xl text-gray-600 dark:text-gray-300 mb-8">Upload your nudes and get unfiltered, detailed analysis from our brutally honest AI</p> | |
| <button id="uploadTrigger" class="bg-primary hover:bg-primary-600 text-white font-bold py-3 px-6 rounded-full text-lg transition-all transform hover:scale-105 shadow-lg"> | |
| Upload Now | |
| </button> | |
| </section> | |
| <section class="mb-16"> | |
| <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6 text-center">Recent Ratings</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <!-- Sample rating cards --> | |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden"> | |
| <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700"> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <i data-feather="image" class="w-16 h-16 text-gray-400"></i> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3> | |
| <span class="bg-secondary text-white text-xs px-2 py-1 rounded-full">8.2/10</span> | |
| </div> | |
| <p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Above average length but slightly curved to the left. Good girth but could use better grooming. Vein definition is decent but not exceptional...</p> | |
| </div> | |
| </div> | |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden"> | |
| <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700"> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <i data-feather="image" class="w-16 h-16 text-gray-400"></i> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">Full Body Rating</h3> | |
| <span class="bg-yellow-500 text-white text-xs px-2 py-1 rounded-full">6.5/10</span> | |
| </div> | |
| <p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Proportions are decent but belly fat is distracting. Shoulders need more definition. Legs are your best feature - show them more...</p> | |
| </div> | |
| </div> | |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden"> | |
| <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700"> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <i data-feather="image" class="w-16 h-16 text-gray-400"></i> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3> | |
| <span class="bg-red-500 text-white text-xs px-2 py-1 rounded-full">4.1/10</span> | |
| </div> | |
| <p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-3">Below average in both length and girth. Poor lighting and angle doesn't help. Consider different angles or better presentation...</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section class="max-w-3xl mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-12"> | |
| <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">How It Works</h2> | |
| <div class="space-y-4"> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4"> | |
| <i data-feather="upload" class="w-5 h-5 text-primary"></i> | |
| </div> | |
| <div> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">1. Upload Your Photos</h3> | |
| <p class="text-gray-600 dark:text-gray-300">Upload your nude or dick pics. We accept JPG, PNG up to 10MB.</p> | |
| </div> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4"> | |
| <i data-feather="cpu" class="w-5 h-5 text-primary"></i> | |
| </div> | |
| <div> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">2. AI Analysis</h3> | |
| <p class="text-gray-600 dark:text-gray-300">Our brutally honest AI analyzes every detail with no filter.</p> | |
| </div> | |
| </div> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4"> | |
| <i data-feather="file-text" class="w-5 h-5 text-primary"></i> | |
| </div> | |
| <div> | |
| <h3 class="font-semibold text-gray-900 dark:text-white">3. Get Your Rating</h3> | |
| <p class="text-gray-600 dark:text-gray-300">Receive detailed feedback on what's working and what needs improvement.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Upload Modal --> | |
| <div id="uploadModal" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden flex items-center justify-center px-4"> | |
| <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-bold text-gray-900 dark:text-white">Upload Your Photo</h3> | |
| <button id="closeModal" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"> | |
| <i data-feather="x" class="w-6 h-6"></i> | |
| </button> | |
| </div> | |
| <div id="uploadArea" class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center cursor-pointer transition-all hover:border-primary hover:bg-primary-50 dark:hover:bg-primary-900/20"> | |
| <i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i> | |
| <p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p> | |
| <p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p> | |
| <input type="file" id="fileInput" class="hidden" accept=".jpg,.jpeg,.png"> | |
| </div> | |
| <div id="uploadProgress" class="hidden mt-4"> | |
| <div class="bg-gray-200 dark:bg-gray-700 rounded-full h-2"> | |
| <div id="progressBar" class="bg-primary h-2 rounded-full transition-all duration-300" style="width: 0%"></div> | |
| </div> | |
| <div id="uploadError" class="hidden mt-4 p-3 bg-red-100 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg"> | |
| <p class="text-red-700 dark:text-red-300 text-sm"></p> | |
| </div> | |
| <div class="mt-6 flex justify-end space-x-3"> | |
| <button id="cancelUpload" class="px-4 py-2 text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-gray-100 transition-colors"> | |
| Cancel | |
| </button> | |
| <button id="confirmUpload" class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-600 transition-colors disabled:opacity-50"> | |
| Upload | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <footer class="bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 py-8"> | |
| <div class="container mx-auto px-4"> | |
| <div class="text-center"> | |
| <p class="text-gray-600 dark:text-gray-300 mb-4">Brutally Honest AI Nude Rater</p> | |
| <div class="flex justify-center space-x-6 text-sm"> | |
| <a href="#" class="text-gray-500 hover:text-primary transition-colors">Privacy Policy</a> | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| </div> | |
| <script src="assets/js/script.js"></script> | |
| </body> | |
| </html> | |
| === assets/css/style.css === | |
| /* Custom styles for the AI Nude Rater */ | |
| .line-clamp-3 { | |
| display: -webkit-box; | |
| -webkit-line-clamp: 3; | |
| -webkit-box-orient: vertical; | |
| overflow: hidden; | |
| } | |
| /* Smooth transitions for theme switching */ | |
| * { | |
| transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; | |
| } | |
| /* Custom scrollbar for webkit browsers */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #f1f5f9; | |
| } | |
| .dark ::-webkit-scrollbar-track { | |
| background: #334155; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #cbd5e1; | |
| border-radius: 4px; | |
| } | |
| .dark ::-webkit-scrollbar-thumb { | |
| background: #475569; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #94a3b8; | |
| } | |
| .dark ::-webkit-scrollbar-thumb:hover { | |
| background: #64748b; | |
| } | |
| /* Upload area animations */ | |
| 0%, 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0.7; | |
| } | |
| } | |
| .upload-pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| /* Rating badge colors */ | |
| .rating-badge { | |
| font-size: 0.75rem; | |
| padding: 0.25rem 0.5rem; | |
| border-radius: 9999px; | |
| color: white; | |
| font-weight: 600; | |
| } | |
| /* Mobile-first responsive adjustments */ | |
| .container { | |
| padding-left: 1rem; | |
| padding-right: 1rem; | |
| } | |
| #uploadModal .max-w-md { | |
| margin: 1rem; | |
| } | |
| } | |
| /* Enhanced focus states for accessibility */ | |
| button:focus-visible, | |
| a:focus-visible { | |
| outline: 2px solid #7c3aed; | |
| outline-offset: 2px; | |
| } | |
| /* Loading animation for AI processing */ | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| .loading-spinner { | |
| animation: spin 1s linear infinite; | |
| } | |
| === assets/js/script.js === | |
| // Age verification functionality | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize feather icons | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| // Age verification logic | |
| const ageVerification = document.getElementById('ageVerification'); | |
| const mainContent = document.getElementById('mainContent'); | |
| const enterButton = document.getElementById('enterSite'); | |
| const exitButton = document.getElementById('exitSite'); | |
| // Check if user has already verified age | |
| const hasVerified = localStorage.getItem('ageVerified'); | |
| if (hasVerified === 'true') { | |
| ageVerification.classList.add('hidden'); | |
| mainContent.classList.remove('hidden'); | |
| } | |
| enterButton.addEventListener('click', function() { | |
| localStorage.setItem('ageVerified', 'true'); | |
| ageVerification.classList.add('hidden'); | |
| mainContent.classList.remove('hidden'); | |
| // Re-initialize feather icons for main content | |
| if (typeof feather !== 'undefined') { | |
| setTimeout(() => feather.replace(), 100); | |
| } | |
| }); | |
| exitButton.addEventListener('click', function() { | |
| window.location.href = 'https://www.google.com'; | |
| }); | |
| // Theme toggle functionality | |
| const themeToggle = document.getElementById('themeToggle'); | |
| const themeIcon = themeToggle.querySelector('i'); | |
| themeToggle.addEventListener('click', function() { | |
| const html = document.documentElement; | |
| if (html.classList.contains('dark')) { | |
| html.classList.remove('dark'); | |
| themeIcon.setAttribute('data-feather', 'moon'); | |
| localStorage.setItem('theme', 'light'); | |
| } else { | |
| html.classList.add('dark'); | |
| themeIcon.setAttribute('data-feather', 'sun'); | |
| localStorage.setItem('theme', 'dark'); | |
| } | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| }); | |
| // Set initial theme based on localStorage or system preference | |
| const savedTheme = localStorage.getItem('theme'); | |
| if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches) { | |
| document.documentElement.classList.add('dark'); | |
| themeIcon.setAttribute('data-feather', 'sun'); | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| } | |
| // Upload modal functionality | |
| const uploadTrigger = document.getElementById('uploadTrigger'); | |
| const uploadModal = document.getElementById('uploadModal'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const cancelUpload = document.getElementById('cancelUpload'); | |
| const uploadArea = document.getElementById('uploadArea'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const uploadProgress = document.getElementById('uploadProgress'); | |
| const progressBar = document.getElementById('progressBar'); | |
| const uploadError = document.getElementById('uploadError'); | |
| const confirmUpload = document.getElementById('confirmUpload'); | |
| let selectedFile = null; | |
| // Open modal | |
| uploadTrigger.addEventListener('click', function() { | |
| uploadModal.classList.remove('hidden'); | |
| resetUploadState(); | |
| }); | |
| // Close modal functions | |
| function closeUploadModal() { | |
| uploadModal.classList.add('hidden'); | |
| resetUploadState(); | |
| } | |
| closeModal.addEventListener('click', closeUploadModal); | |
| cancelUpload.addEventListener('click', closeUploadModal); | |
| // Click outside modal to close | |
| uploadModal.addEventListener('click', function(e) { | |
| if (e.target === uploadModal) { | |
| closeUploadModal(); | |
| } | |
| }); | |
| // File upload handling | |
| uploadArea.addEventListener('click', function() { | |
| fileInput.click(); | |
| }); | |
| uploadArea.addEventListener('dragover', function(e) { | |
| e.preventDefault(); | |
| uploadArea.classList.add('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20'); | |
| }); | |
| uploadArea.addEventListener('dragleave', function() { | |
| uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20'); | |
| }); | |
| uploadArea.addEventListener('drop', function(e) { | |
| e.preventDefault(); | |
| uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20'); | |
| handleFileSelect(e.dataTransfer.files[0]); | |
| }); | |
| fileInput.addEventListener('change', function(e) { | |
| if (e.target.files.length > 0) { | |
| handleFileSelect(e.target.files[0]); | |
| } | |
| }); | |
| function handleFileSelect(file) { | |
| // Validate file type | |
| const validTypes = ['image/jpeg', 'image/jpg', 'image/png']; | |
| if (!validTypes.includes(file.type)) { | |
| showUploadError('Please upload only JPG or PNG files.'); | |
| return; | |
| } | |
| // Validate file size (10MB) | |
| const maxSize = 10 * 1024 * 1024; | |
| if (file.size > maxSize) { | |
| showUploadError('File size must be less than 10MB.'); | |
| return; | |
| } | |
| selectedFile = file; | |
| uploadArea.innerHTML = ` | |
| <i data-feather="check" class="w-12 h-12 text-green-500 mx-auto mb-4"></i> | |
| <p class="text-gray-600 dark:text-gray-300 mb-2">${file.name}</p> | |
| <p class="text-sm text-gray-500 dark:text-gray-400">${(file.size / 1024 / 1024).toFixed(2)} MB</p> | |
| `; | |
| confirmUpload.disabled = false; | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| } | |
| confirmUpload.addEventListener('click', function() { | |
| if (!selectedFile) return; | |
| // Show progress bar | |
| uploadProgress.classList.remove('hidden'); | |
| progressBar.style.width = '0%'; | |
| // Simulate upload progress | |
| let progress = 0; | |
| const interval = setInterval(() => { | |
| progress += Math.random() * 15; | |
| if (progress > 100) progress = 100; | |
| progressBar.style.width = progress + '%'; | |
| if (progress === 100) { | |
| clearInterval(interval); | |
| simulateAIRating(); | |
| } | |
| }, 200); | |
| }); | |
| function simulateAIRating() { | |
| // Simulate AI processing | |
| setTimeout(() => { | |
| // Show success and redirect to results | |
| alert('Your photo has been analyzed! Here is your brutally honest rating...'); | |
| closeUploadModal(); | |
| // In a real implementation, this would redirect to the results page | |
| }, 1500); | |
| } | |
| function resetUploadState() { | |
| selectedFile = null; | |
| uploadArea.innerHTML = ` | |
| <i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i> | |
| <p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p> | |
| <p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p> | |
| `; | |
| uploadProgress.classList.add('hidden'); | |
| uploadError.classList.add('hidden'); | |
| confirmUpload.disabled = true; | |
| fileInput.value = ''; | |
| if (typeof feather !== 'undefined') { | |
| feather.replace(); | |
| } | |
| } | |
| function showUploadError(message) { | |
| uploadError.querySelector('p').textContent = message; | |
| uploadError.classList.remove('hidden'); | |
| setTimeout(() => { | |
| uploadError.classList.add('hidden'); | |
| }, 5000); | |
| } | |
| // Keyboard navigation | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Escape' && !uploadModal.classList.contains('hidden')) { | |
| closeUploadModal(); | |
| } | |
| }); | |
| // Performance optimization: Lazy loading for future implementations | |
| if ('IntersectionObserver' in window) { | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| // Future: Load content when it comes into view | |
| } | |
| }); | |
| }); | |
| } | |
| }); |