rushkid5 commited on
Commit
128987f
·
verified ·
1 Parent(s): efd4b00

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. assets/css/style.css +95 -0
  2. assets/js/script.js +232 -0
  3. index.html +205 -0
assets/css/style.css ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom styles for the AI Nude Rater */
2
+ .line-clamp-3 {
3
+ display: -webkit-box;
4
+ -webkit-line-clamp: 3;
5
+ -webkit-box-orient: vertical;
6
+ overflow: hidden;
7
+ }
8
+
9
+ /* Smooth transitions for theme switching */
10
+ * {
11
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
12
+ }
13
+
14
+ /* Custom scrollbar for webkit browsers */
15
+ ::-webkit-scrollbar {
16
+ width: 8px;
17
+ }
18
+
19
+ ::-webkit-scrollbar-track {
20
+ background: #f1f5f9;
21
+ }
22
+
23
+ .dark ::-webkit-scrollbar-track {
24
+ background: #334155;
25
+ }
26
+
27
+ ::-webkit-scrollbar-thumb {
28
+ background: #cbd5e1;
29
+ border-radius: 4px;
30
+ }
31
+
32
+ .dark ::-webkit-scrollbar-thumb {
33
+ background: #475569;
34
+ }
35
+
36
+ ::-webkit-scrollbar-thumb:hover {
37
+ background: #94a3b8;
38
+ }
39
+
40
+ .dark ::-webkit-scrollbar-thumb:hover {
41
+ background: #64748b;
42
+ }
43
+
44
+ /* Upload area animations */
45
+ @keyframes pulse {
46
+ 0%, 100% {
47
+ opacity: 1;
48
+ }
49
+ 50% {
50
+ opacity: 0.7;
51
+ }
52
+ }
53
+
54
+ .upload-pulse {
55
+ animation: pulse 2s infinite;
56
+ }
57
+
58
+ /* Rating badge colors */
59
+ .rating-badge {
60
+ font-size: 0.75rem;
61
+ padding: 0.25rem 0.5rem;
62
+ border-radius: 9999px;
63
+ color: white;
64
+ font-weight: 600;
65
+ }
66
+
67
+ /* Mobile-first responsive adjustments */
68
+ @media (max-width: 640px) {
69
+ .container {
70
+ padding-left: 1rem;
71
+ padding-right: 1rem;
72
+ }
73
+
74
+ #uploadModal .max-w-md {
75
+ margin: 1rem;
76
+ }
77
+ }
78
+
79
+ /* Enhanced focus states for accessibility */
80
+ button:focus-visible,
81
+ a:focus-visible {
82
+ outline: 2px solid #7c3aed;
83
+ outline-offset: 2px;
84
+ }
85
+
86
+ /* Loading animation for AI processing */
87
+ @keyframes spin {
88
+ to {
89
+ transform: rotate(360deg);
90
+ }
91
+ }
92
+
93
+ .loading-spinner {
94
+ animation: spin 1s linear infinite;
95
+ }
assets/js/script.js ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Age verification functionality
2
+ document.addEventListener('DOMContentLoaded', function() {
3
+ // Initialize feather icons
4
+ if (typeof feather !== 'undefined') {
5
+ feather.replace();
6
+ }
7
+
8
+ // Age verification logic
9
+ const ageVerification = document.getElementById('ageVerification');
10
+ const mainContent = document.getElementById('mainContent');
11
+ const enterButton = document.getElementById('enterSite');
12
+ const exitButton = document.getElementById('exitSite');
13
+
14
+ // Check if user has already verified age
15
+ const hasVerified = localStorage.getItem('ageVerified');
16
+ if (hasVerified === 'true') {
17
+ ageVerification.classList.add('hidden');
18
+ mainContent.classList.remove('hidden');
19
+ }
20
+
21
+ enterButton.addEventListener('click', function() {
22
+ localStorage.setItem('ageVerified', 'true');
23
+ ageVerification.classList.add('hidden');
24
+ mainContent.classList.remove('hidden');
25
+
26
+ // Re-initialize feather icons for main content
27
+ if (typeof feather !== 'undefined') {
28
+ setTimeout(() => feather.replace(), 100);
29
+ }
30
+ });
31
+
32
+ exitButton.addEventListener('click', function() {
33
+ window.location.href = 'https://www.google.com';
34
+ });
35
+
36
+ // Theme toggle functionality
37
+ const themeToggle = document.getElementById('themeToggle');
38
+ const themeIcon = themeToggle.querySelector('i');
39
+
40
+ themeToggle.addEventListener('click', function() {
41
+ const html = document.documentElement;
42
+ if (html.classList.contains('dark')) {
43
+ html.classList.remove('dark');
44
+ themeIcon.setAttribute('data-feather', 'moon');
45
+ localStorage.setItem('theme', 'light');
46
+ } else {
47
+ html.classList.add('dark');
48
+ themeIcon.setAttribute('data-feather', 'sun');
49
+ localStorage.setItem('theme', 'dark');
50
+ }
51
+
52
+ if (typeof feather !== 'undefined') {
53
+ feather.replace();
54
+ }
55
+ });
56
+
57
+ // Set initial theme based on localStorage or system preference
58
+ const savedTheme = localStorage.getItem('theme');
59
+ if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches) {
60
+ document.documentElement.classList.add('dark');
61
+ themeIcon.setAttribute('data-feather', 'sun');
62
+ if (typeof feather !== 'undefined') {
63
+ feather.replace();
64
+ }
65
+ }
66
+
67
+ // Upload modal functionality
68
+ const uploadTrigger = document.getElementById('uploadTrigger');
69
+ const uploadModal = document.getElementById('uploadModal');
70
+ const closeModal = document.getElementById('closeModal');
71
+ const cancelUpload = document.getElementById('cancelUpload');
72
+ const uploadArea = document.getElementById('uploadArea');
73
+ const fileInput = document.getElementById('fileInput');
74
+ const uploadProgress = document.getElementById('uploadProgress');
75
+ const progressBar = document.getElementById('progressBar');
76
+ const uploadError = document.getElementById('uploadError');
77
+ const confirmUpload = document.getElementById('confirmUpload');
78
+
79
+ let selectedFile = null;
80
+
81
+ // Open modal
82
+ uploadTrigger.addEventListener('click', function() {
83
+ uploadModal.classList.remove('hidden');
84
+ resetUploadState();
85
+ });
86
+
87
+ // Close modal functions
88
+ function closeUploadModal() {
89
+ uploadModal.classList.add('hidden');
90
+ resetUploadState();
91
+ }
92
+
93
+ closeModal.addEventListener('click', closeUploadModal);
94
+ cancelUpload.addEventListener('click', closeUploadModal);
95
+
96
+ // Click outside modal to close
97
+ uploadModal.addEventListener('click', function(e) {
98
+ if (e.target === uploadModal) {
99
+ closeUploadModal();
100
+ }
101
+ });
102
+
103
+ // File upload handling
104
+ uploadArea.addEventListener('click', function() {
105
+ fileInput.click();
106
+ });
107
+
108
+ uploadArea.addEventListener('dragover', function(e) {
109
+ e.preventDefault();
110
+ uploadArea.classList.add('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
111
+ });
112
+
113
+ uploadArea.addEventListener('dragleave', function() {
114
+ uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
115
+ });
116
+
117
+ uploadArea.addEventListener('drop', function(e) {
118
+ e.preventDefault();
119
+ uploadArea.classList.remove('border-primary', 'bg-primary-50', 'dark:bg-primary-900/20');
120
+ handleFileSelect(e.dataTransfer.files[0]);
121
+ });
122
+
123
+ fileInput.addEventListener('change', function(e) {
124
+ if (e.target.files.length > 0) {
125
+ handleFileSelect(e.target.files[0]);
126
+ }
127
+ });
128
+
129
+ function handleFileSelect(file) {
130
+ // Validate file type
131
+ const validTypes = ['image/jpeg', 'image/jpg', 'image/png'];
132
+ if (!validTypes.includes(file.type)) {
133
+ showUploadError('Please upload only JPG or PNG files.');
134
+ return;
135
+ }
136
+
137
+ // Validate file size (10MB)
138
+ const maxSize = 10 * 1024 * 1024;
139
+ if (file.size > maxSize) {
140
+ showUploadError('File size must be less than 10MB.');
141
+ return;
142
+ }
143
+
144
+ selectedFile = file;
145
+ uploadArea.innerHTML = `
146
+ <i data-feather="check" class="w-12 h-12 text-green-500 mx-auto mb-4"></i>
147
+ <p class="text-gray-600 dark:text-gray-300 mb-2">${file.name}</p>
148
+ <p class="text-sm text-gray-500 dark:text-gray-400">${(file.size / 1024 / 1024).toFixed(2)} MB</p>
149
+ `;
150
+
151
+ confirmUpload.disabled = false;
152
+
153
+ if (typeof feather !== 'undefined') {
154
+ feather.replace();
155
+ }
156
+ }
157
+
158
+ confirmUpload.addEventListener('click', function() {
159
+ if (!selectedFile) return;
160
+
161
+ // Show progress bar
162
+ uploadProgress.classList.remove('hidden');
163
+ progressBar.style.width = '0%';
164
+
165
+ // Simulate upload progress
166
+ let progress = 0;
167
+ const interval = setInterval(() => {
168
+ progress += Math.random() * 15;
169
+ if (progress > 100) progress = 100;
170
+ progressBar.style.width = progress + '%';
171
+
172
+ if (progress === 100) {
173
+ clearInterval(interval);
174
+ simulateAIRating();
175
+ }
176
+ }, 200);
177
+ });
178
+
179
+ function simulateAIRating() {
180
+ // Simulate AI processing
181
+ setTimeout(() => {
182
+ // Show success and redirect to results
183
+ alert('Your photo has been analyzed! Here is your brutally honest rating...');
184
+ closeUploadModal();
185
+ // In a real implementation, this would redirect to the results page
186
+ }, 1500);
187
+ }
188
+
189
+ function resetUploadState() {
190
+ selectedFile = null;
191
+ uploadArea.innerHTML = `
192
+ <i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i>
193
+ <p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p>
194
+ <p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p>
195
+ `;
196
+ uploadProgress.classList.add('hidden');
197
+ uploadError.classList.add('hidden');
198
+ confirmUpload.disabled = true;
199
+ fileInput.value = '';
200
+
201
+ if (typeof feather !== 'undefined') {
202
+ feather.replace();
203
+ }
204
+ }
205
+
206
+ function showUploadError(message) {
207
+ uploadError.querySelector('p').textContent = message;
208
+ uploadError.classList.remove('hidden');
209
+
210
+ setTimeout(() => {
211
+ uploadError.classList.add('hidden');
212
+ }, 5000);
213
+ }
214
+
215
+ // Keyboard navigation
216
+ document.addEventListener('keydown', function(e) {
217
+ if (e.key === 'Escape' && !uploadModal.classList.contains('hidden')) {
218
+ closeUploadModal();
219
+ }
220
+ });
221
+
222
+ // Performance optimization: Lazy loading for future implementations
223
+ if ('IntersectionObserver' in window) {
224
+ const observer = new IntersectionObserver((entries) => {
225
+ entries.forEach(entry => {
226
+ if (entry.isIntersecting) {
227
+ // Future: Load content when it comes into view
228
+ }
229
+ });
230
+ });
231
+ }
232
+ });
index.html ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Brutally Honest AI Nude Rater</title>
7
+ <meta name="description" content="Get brutally honest AI ratings for your nude photos. Upload and receive detailed analysis from our unfiltered AI system.">
8
+ <link rel="stylesheet" href="assets/css/style.css">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script>
12
+ tailwind.config = {
13
+ darkMode: 'class',
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#7c3aed',
18
+ secondary: '#10b981',
19
+ dark: '#1e293b'
20
+ }
21
+ }
22
+ }
23
+ }
24
+ </script>
25
+ </head>
26
+ <body class="bg-gray-100 dark:bg-dark min-h-screen">
27
+ <!-- Age Verification Overlay -->
28
+ <div id="ageVerification" class="fixed inset-0 bg-black bg-opacity-90 z-50 flex items-center justify-center px-4">
29
+ <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-8 text-center">
30
+ <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">Age Verification Required</h2>
31
+ <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>
32
+ <div class="space-y-4">
33
+ <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">
34
+ I am 18 or older - Enter Site
35
+ </button>
36
+ <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">
37
+ I am under 18 - Exit
38
+ </button>
39
+ </div>
40
+ <p class="text-xs text-gray-500 dark:text-gray-400 mt-6">This site contains adult content intended for mature audiences only.</p>
41
+ </div>
42
+ </div>
43
+
44
+ <!-- Main Content (hidden until age verification) -->
45
+ <div id="mainContent" class="hidden">
46
+ <header class="bg-white dark:bg-gray-800 shadow-sm border-b border-gray-200 dark:border-gray-700">
47
+ <div class="container mx-auto px-4 py-4">
48
+ <div class="flex justify-between items-center">
49
+ <h1 class="text-xl font-bold text-gray-900 dark:text-white">Brutally Honest AI Nude Rater</h1>
50
+ <div class="flex items-center space-x-4">
51
+ <button id="themeToggle" class="p-2 rounded-lg bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300">
52
+ <i data-feather="moon" class="w-5 h-5"></i>
53
+ </button>
54
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="text-xs text-gray-500 hover:text-primary transition-colors">Built with anycoder</a>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </header>
59
+
60
+ <main class="container mx-auto px-4 py-8">
61
+ <section class="max-w-4xl mx-auto text-center mb-12">
62
+ <h1 class="text-4xl md:text-5xl font-bold text-gray-900 dark:text-white mb-4">Brutally Honest AI Nude Ratings</h1>
63
+ <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>
64
+ <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">
65
+ Upload Now
66
+ </button>
67
+ </section>
68
+
69
+ <section class="mb-16">
70
+ <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-6 text-center">Recent Ratings</h2>
71
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
72
+ <!-- Sample rating cards -->
73
+ <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
74
+ <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
75
+ <div class="absolute inset-0 flex items-center justify-center">
76
+ <i data-feather="image" class="w-16 h-16 text-gray-400"></i>
77
+ </div>
78
+ </div>
79
+ <div class="p-4">
80
+ <div class="flex justify-between items-start mb-2">
81
+ <h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3>
82
+ <span class="bg-secondary text-white text-xs px-2 py-1 rounded-full">8.2/10</span>
83
+ </div>
84
+ <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>
85
+ </div>
86
+ </div>
87
+
88
+ <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
89
+ <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
90
+ <div class="absolute inset-0 flex items-center justify-center">
91
+ <i data-feather="image" class="w-16 h-16 text-gray-400"></i>
92
+ </div>
93
+ </div>
94
+ <div class="p-4">
95
+ <div class="flex justify-between items-start mb-2">
96
+ <h3 class="font-semibold text-gray-900 dark:text-white">Full Body Rating</h3>
97
+ <span class="bg-yellow-500 text-white text-xs px-2 py-1 rounded-full">6.5/10</span>
98
+ </div>
99
+ <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>
100
+ </div>
101
+ </div>
102
+
103
+ <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden">
104
+ <div class="relative pt-[75%] bg-gray-200 dark:bg-gray-700">
105
+ <div class="absolute inset-0 flex items-center justify-center">
106
+ <i data-feather="image" class="w-16 h-16 text-gray-400"></i>
107
+ </div>
108
+ </div>
109
+ <div class="p-4">
110
+ <div class="flex justify-between items-start mb-2">
111
+ <h3 class="font-semibold text-gray-900 dark:text-white">Dick Rating</h3>
112
+ <span class="bg-red-500 text-white text-xs px-2 py-1 rounded-full">4.1/10</span>
113
+ </div>
114
+ <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>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </section>
119
+
120
+ <section class="max-w-3xl mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-12">
121
+ <h2 class="text-2xl font-bold text-gray-900 dark:text-white mb-4">How It Works</h2>
122
+ <div class="space-y-4">
123
+ <div class="flex items-start">
124
+ <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
125
+ <i data-feather="upload" class="w-5 h-5 text-primary"></i>
126
+ </div>
127
+ <div>
128
+ <h3 class="font-semibold text-gray-900 dark:text-white">1. Upload Your Photos</h3>
129
+ <p class="text-gray-600 dark:text-gray-300">Upload your nude or dick pics. We accept JPG, PNG up to 10MB.</p>
130
+ </div>
131
+ </div>
132
+ <div class="flex items-start">
133
+ <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
134
+ <i data-feather="cpu" class="w-5 h-5 text-primary"></i>
135
+ </div>
136
+ <div>
137
+ <h3 class="font-semibold text-gray-900 dark:text-white">2. AI Analysis</h3>
138
+ <p class="text-gray-600 dark:text-gray-300">Our brutally honest AI analyzes every detail with no filter.</p>
139
+ </div>
140
+ </div>
141
+ <div class="flex items-start">
142
+ <div class="flex-shrink-0 bg-primary-100 dark:bg-primary-900 p-2 rounded-lg mr-4">
143
+ <i data-feather="file-text" class="w-5 h-5 text-primary"></i>
144
+ </div>
145
+ <div>
146
+ <h3 class="font-semibold text-gray-900 dark:text-white">3. Get Your Rating</h3>
147
+ <p class="text-gray-600 dark:text-gray-300">Receive detailed feedback on what's working and what needs improvement.</p>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </section>
152
+ </main>
153
+
154
+ <!-- Upload Modal -->
155
+ <div id="uploadModal" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden flex items-center justify-center px-4">
156
+ <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-md w-full p-6">
157
+ <div class="flex justify-between items-center mb-4">
158
+ <h3 class="text-xl font-bold text-gray-900 dark:text-white">Upload Your Photo</h3>
159
+ <button id="closeModal" class="text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
160
+ <i data-feather="x" class="w-6 h-6"></i>
161
+ </button>
162
+ </div>
163
+
164
+ <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">
165
+ <i data-feather="upload" class="w-12 h-12 text-gray-400 mx-auto mb-4"></i>
166
+ <p class="text-gray-600 dark:text-gray-300 mb-2">Click to upload or drag and drop</p>
167
+ <p class="text-sm text-gray-500 dark:text-gray-400">JPG, PNG up to 10MB</p>
168
+ <input type="file" id="fileInput" class="hidden" accept=".jpg,.jpeg,.png">
169
+ </div>
170
+
171
+ <div id="uploadProgress" class="hidden mt-4">
172
+ <div class="bg-gray-200 dark:bg-gray-700 rounded-full h-2">
173
+ <div id="progressBar" class="bg-primary h-2 rounded-full transition-all duration-300" style="width: 0%"></div>
174
+ </div>
175
+
176
+ <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">
177
+ <p class="text-red-700 dark:text-red-300 text-sm"></p>
178
+ </div>
179
+
180
+ <div class="mt-6 flex justify-end space-x-3">
181
+ <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">
182
+ Cancel
183
+ </button>
184
+ <button id="confirmUpload" class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-600 transition-colors disabled:opacity-50">
185
+ Upload
186
+ </button>
187
+ </div>
188
+ </div>
189
+ </div>
190
+
191
+ <footer class="bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 py-8">
192
+ <div class="container mx-auto px-4">
193
+ <div class="text-center">
194
+ <p class="text-gray-600 dark:text-gray-300 mb-4">Brutally Honest AI Nude Rater</p>
195
+ <div class="flex justify-center space-x-6 text-sm">
196
+ <a href="#" class="text-gray-500 hover:text-primary transition-colors">Privacy Policy</a>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </footer>
201
+ </div>
202
+
203
+ <script src="assets/js/script.js"></script>
204
+ </body>
205
+ </html>