pauloyatowo commited on
Commit
fd4baa4
·
verified ·
1 Parent(s): fd72d0b

Upload 2 files

Browse files
Files changed (2) hide show
  1. index.html +922 -16
  2. style.css +14 -27
index.html CHANGED
@@ -1,21 +1,927 @@
1
-
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Soc.io - AI Ad Generator</title>
8
- <link rel="stylesheet" href="style.css" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </head>
10
- <body>
11
- <div class="card">
12
- <h1>Soc.io</h1>
13
- <p>Enter your ad concept below and let AI generate a stunning visual.</p>
14
- <textarea id="promptInput" rows="4" style="width: 100%;"></textarea>
15
- <button onclick="generateAd()">Generate Ad</button>
16
- <p id="status"></p>
17
- <img id="outputImage" style="margin-top: 16px; max-width: 100%; border-radius: 12px;" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </div>
19
- <script src="script.js"></script>
20
- </body>
21
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>soc.io | AI-Powered Social Content Creator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700&family=Inter:wght@300;400;500;600&display=swap');
11
+
12
+ :root {
13
+ --primary: #6d28d9;
14
+ --primary-light: #8b5cf6;
15
+ --secondary: #10b981;
16
+ --dark: #0f172a;
17
+ --light: #f8fafc;
18
+ --accent: #f59e0b;
19
+ }
20
+
21
+ body {
22
+ font-family: 'Inter', sans-serif;
23
+ background-color: var(--dark);
24
+ color: var(--light);
25
+ overflow-x: hidden;
26
+ }
27
+
28
+ .tech-font {
29
+ font-family: 'Orbitron', sans-serif;
30
+ }
31
+
32
+ .gradient-text {
33
+ background: linear-gradient(90deg, var(--primary-light), var(--secondary));
34
+ -webkit-background-clip: text;
35
+ background-clip: text;
36
+ color: transparent;
37
+ }
38
+
39
+ .glow-box {
40
+ box-shadow: 0 0 15px rgba(139, 92, 246, 0.5);
41
+ }
42
+
43
+ .glow-box:hover {
44
+ box-shadow: 0 0 25px rgba(139, 92, 246, 0.7);
45
+ }
46
+
47
+ .neon-border {
48
+ border: 1px solid rgba(139, 92, 246, 0.3);
49
+ position: relative;
50
+ }
51
+
52
+ .neon-border::before {
53
+ content: '';
54
+ position: absolute;
55
+ top: -2px;
56
+ left: -2px;
57
+ right: -2px;
58
+ bottom: -2px;
59
+ border: 2px solid transparent;
60
+ background: linear-gradient(135deg, var(--primary-light), var(--secondary)) border-box;
61
+ -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0);
62
+ -webkit-mask-composite: destination-out;
63
+ mask-composite: exclude;
64
+ border-radius: inherit;
65
+ pointer-events: none;
66
+ }
67
+
68
+ .grid-pattern {
69
+ background-image:
70
+ linear-gradient(rgba(139, 92, 246, 0.1) 1px, transparent 1px),
71
+ linear-gradient(90deg, rgba(139, 92, 246, 0.1) 1px, transparent 1px);
72
+ background-size: 30px 30px;
73
+ }
74
+
75
+ .pulse-animation {
76
+ animation: pulse 2s infinite;
77
+ }
78
+
79
+ @keyframes pulse {
80
+ 0% { opacity: 0.7; }
81
+ 50% { opacity: 1; }
82
+ 100% { opacity: 0.7; }
83
+ }
84
+
85
+ .slide-in {
86
+ animation: slideIn 0.5s ease-out forwards;
87
+ }
88
+
89
+ @keyframes slideIn {
90
+ from { transform: translateY(20px); opacity: 0; }
91
+ to { transform: translateY(0); opacity: 1; }
92
+ }
93
+
94
+ .terminal-text {
95
+ font-family: 'Courier New', monospace;
96
+ color: #50fa7b;
97
+ }
98
+
99
+ .loading-spinner {
100
+ width: 24px;
101
+ height: 24px;
102
+ border: 3px solid rgba(255,255,255,0.3);
103
+ border-radius: 50%;
104
+ border-top-color: var(--primary-light);
105
+ animation: spin 1s ease-in-out infinite;
106
+ }
107
+
108
+ @keyframes spin {
109
+ to { transform: rotate(360deg); }
110
+ }
111
+
112
+ .api-key-modal {
113
+ display: none;
114
+ position: fixed;
115
+ top: 0;
116
+ left: 0;
117
+ right: 0;
118
+ bottom: 0;
119
+ background-color: rgba(0,0,0,0.8);
120
+ z-index: 100;
121
+ justify-content: center;
122
+ align-items: center;
123
+ }
124
+
125
+ .api-key-modal.active {
126
+ display: flex;
127
+ }
128
+
129
+ .generated-image {
130
+ max-width: 100%;
131
+ max-height: 400px;
132
+ border-radius: 0.5rem;
133
+ object-fit: contain;
134
+ }
135
+ </style>
136
  </head>
137
+ <body class="min-h-screen grid-pattern">
138
+ <!-- Navigation -->
139
+ <nav class="bg-black bg-opacity-80 backdrop-blur-md border-b border-purple-900 fixed w-full z-50">
140
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
141
+ <div class="flex items-center justify-between h-16">
142
+ <div class="flex items-center">
143
+ <div class="flex-shrink-0 flex items-center">
144
+ <i class="fas fa-robot text-purple-500 text-2xl mr-2"></i>
145
+ <span class="tech-font text-xl font-bold gradient-text">soc.io</span>
146
+ </div>
147
+ <div class="hidden md:block">
148
+ <div class="ml-10 flex items-baseline space-x-4">
149
+ <a href="#" class="text-purple-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Dashboard</a>
150
+ <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Templates</a>
151
+ <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Gallery</a>
152
+ <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Analytics</a>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ <div class="hidden md:block">
157
+ <div class="ml-4 flex items-center md:ml-6">
158
+ <button id="generate-btn" class="bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium mr-3">
159
+ <i class="fas fa-bolt mr-1"></i> Generate
160
+ </button>
161
+ <div class="ml-3 relative">
162
+ <div>
163
+ <button class="max-w-xs flex items-center text-sm rounded-full focus:outline-none" id="user-menu">
164
+ <img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
165
+ </button>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <div class="-mr-2 flex md:hidden">
171
+ <button class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none">
172
+ <span class="sr-only">Open main menu</span>
173
+ <i class="fas fa-bars"></i>
174
+ </button>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </nav>
179
+
180
+ <!-- API Key Modal -->
181
+ <div id="api-key-modal" class="api-key-modal">
182
+ <div class="bg-gray-900 rounded-xl p-8 max-w-md w-full neon-border glow-box">
183
+ <div class="flex justify-between items-center mb-6">
184
+ <h3 class="tech-font text-2xl gradient-text">Hugging Face API Key</h3>
185
+ <button id="close-modal" class="text-gray-400 hover:text-white">
186
+ <i class="fas fa-times"></i>
187
+ </button>
188
+ </div>
189
+ <p class="text-gray-300 mb-4">
190
+ To generate images, you need a Hugging Face API key with access to the Stable Diffusion models.
191
+ </p>
192
+ <div class="mb-6">
193
+ <label class="block text-sm font-medium text-gray-300 mb-2">Your API Key</label>
194
+ <input
195
+ type="password"
196
+ id="api-key-input"
197
+ class="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-3 text-white focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
198
+ placeholder="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
199
+ <p class="text-xs text-gray-500 mt-2">
200
+ Don't have an API key? <a href="https://huggingface.co/settings/tokens" target="_blank" class="text-purple-400 hover:underline">Get one here</a>
201
+ </p>
202
+ </div>
203
+ <div class="flex justify-end gap-3">
204
+ <button id="cancel-api-key" class="px-4 py-2 rounded-lg border border-gray-700 text-gray-300 hover:bg-gray-800">
205
+ Cancel
206
+ </button>
207
+ <button id="save-api-key" class="bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white px-6 py-2 rounded-lg">
208
+ Save Key
209
+ </button>
210
+ </div>
211
+ </div>
212
  </div>
213
+
214
+ <!-- Main Content -->
215
+ <main class="pt-20 pb-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
216
+ <!-- Hero Section -->
217
+ <div class="text-center py-12 slide-in">
218
+ <h1 class="tech-font text-4xl md:text-6xl font-bold mb-6">
219
+ <span class="gradient-text">AI-Powered</span> Social Content
220
+ </h1>
221
+ <p class="text-xl text-gray-300 max-w-3xl mx-auto">
222
+ Create stunning visuals for your social media with the power of <span class="text-purple-300 font-medium">ControlNet</span> and <span class="text-green-300 font-medium">SDXL</span>. Just describe what you want or use our templates.
223
+ </p>
224
+
225
+ <div class="mt-10 flex flex-col sm:flex-row justify-center gap-4">
226
+ <button id="start-creating" class="glow-box bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white px-8 py-4 rounded-lg text-lg font-medium flex items-center justify-center">
227
+ <i class="fas fa-magic mr-3"></i> Start Creating
228
+ </button>
229
+ <button class="neon-border bg-gray-900 hover:bg-gray-800 text-white px-8 py-4 rounded-lg text-lg font-medium flex items-center justify-center">
230
+ <i class="fas fa-play-circle mr-3"></i> Watch Demo
231
+ </button>
232
+ </div>
233
+ </div>
234
+
235
+ <!-- Generator Section -->
236
+ <div class="mt-16 neon-border rounded-xl bg-gray-900 bg-opacity-70 p-6 glow-box">
237
+ <div class="flex flex-col lg:flex-row gap-8">
238
+ <!-- Input Panel -->
239
+ <div class="lg:w-1/2">
240
+ <h2 class="tech-font text-2xl font-bold mb-6 gradient-text">Content Generator</h2>
241
+
242
+ <div class="mb-6">
243
+ <label class="block text-sm font-medium text-gray-300 mb-2">Prompt</label>
244
+ <div class="relative">
245
+ <textarea
246
+ id="prompt-input"
247
+ class="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-3 text-white focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
248
+ rows="4"
249
+ placeholder="Describe the image you want to generate..."></textarea>
250
+ <div class="absolute bottom-3 right-3 flex gap-2">
251
+ <button class="text-gray-400 hover:text-purple-400">
252
+ <i class="fas fa-microphone"></i>
253
+ </button>
254
+ <button id="prompt-suggestions" class="text-gray-400 hover:text-purple-400">
255
+ <i class="fas fa-lightbulb"></i>
256
+ </button>
257
+ </div>
258
+ </div>
259
+ </div>
260
+
261
+ <div class="grid grid-cols-2 gap-4 mb-6">
262
+ <div>
263
+ <label class="block text-sm font-medium text-gray-300 mb-2">Style</label>
264
+ <select id="style-select" class="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-white focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent">
265
+ <option value="photorealistic">Photorealistic</option>
266
+ <option value="digital_art">Digital Art</option>
267
+ <option value="3d_render">3D Render</option>
268
+ <option value="anime">Anime</option>
269
+ <option value="watercolor">Watercolor</option>
270
+ <option value="cyberpunk">Cyberpunk</option>
271
+ </select>
272
+ </div>
273
+ <div>
274
+ <label class="block text-sm font-medium text-gray-300 mb-2">Aspect Ratio</label>
275
+ <select id="aspect-ratio-select" class="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-white focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent">
276
+ <option value="1:1">Square (1:1)</option>
277
+ <option value="4:5">Portrait (4:5)</option>
278
+ <option value="16:9">Landscape (16:9)</option>
279
+ <option value="9:16">Story (9:16)</option>
280
+ </select>
281
+ </div>
282
+ </div>
283
+
284
+ <div class="mb-6">
285
+ <label class="block text-sm font-medium text-gray-300 mb-2">Upload Reference (ControlNet)</label>
286
+ <div id="upload-area" class="border-2 border-dashed border-gray-700 rounded-lg p-8 text-center cursor-pointer hover:border-purple-500 transition">
287
+ <i class="fas fa-cloud-upload-alt text-4xl text-gray-500 mb-3"></i>
288
+ <p class="text-gray-400">Drag & drop an image or click to browse</p>
289
+ <p class="text-xs text-gray-500 mt-2">Supports JPG, PNG (Max 10MB)</p>
290
+ <input type="file" id="file-input" class="hidden" accept="image/jpeg,image/png">
291
+ </div>
292
+ <div id="preview-container" class="hidden mt-4">
293
+ <div class="relative">
294
+ <img id="preview-image" src="#" alt="Preview" class="max-h-40 rounded-lg">
295
+ <button id="remove-image" class="absolute top-2 right-2 bg-gray-900 bg-opacity-70 text-white p-1 rounded-full hover:bg-gray-800">
296
+ <i class="fas fa-times"></i>
297
+ </button>
298
+ </div>
299
+ </div>
300
+ </div>
301
+
302
+ <div class="flex justify-between items-center">
303
+ <div class="flex items-center">
304
+ <input id="advanced-toggle" type="checkbox" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-700 rounded">
305
+ <label for="advanced-toggle" class="ml-2 block text-sm text-gray-300">Advanced Controls</label>
306
+ </div>
307
+ <button id="generate-now-btn" class="bg-gradient-to-r from-purple-600 to-indigo-600 hover:from-purple-700 hover:to-indigo-700 text-white px-6 py-3 rounded-lg font-medium flex items-center">
308
+ <i class="fas fa-bolt mr-2"></i> Generate Now
309
+ </button>
310
+ </div>
311
+
312
+ <!-- Advanced Controls (Hidden by default) -->
313
+ <div id="advanced-controls" class="hidden mt-6 space-y-4">
314
+ <div>
315
+ <label class="block text-sm font-medium text-gray-300 mb-2">Guidance Scale</label>
316
+ <input id="guidance-scale" type="range" min="1" max="20" value="7.5" step="0.5" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
317
+ <div class="flex justify-between text-xs text-gray-400">
318
+ <span>More Creative</span>
319
+ <span>More Precise</span>
320
+ </div>
321
+ </div>
322
+ <div>
323
+ <label class="block text-sm font-medium text-gray-300 mb-2">Steps</label>
324
+ <input id="steps-input" type="range" min="10" max="50" value="25" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
325
+ </div>
326
+ <div>
327
+ <label class="block text-sm font-medium text-gray-300 mb-2">Seed</label>
328
+ <input id="seed-input" type="number" class="w-full bg-gray-800 border border-gray-700 rounded-lg px-4 py-2 text-white focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" placeholder="Random">
329
+ </div>
330
+ </div>
331
+ </div>
332
+
333
+ <!-- Output Preview -->
334
+ <div class="lg:w-1/2">
335
+ <div class="flex justify-between items-center mb-6">
336
+ <h2 class="tech-font text-2xl font-bold gradient-text">Preview</h2>
337
+ <div class="flex gap-2">
338
+ <button id="undo-btn" class="bg-gray-800 hover:bg-gray-700 text-gray-300 p-2 rounded-lg">
339
+ <i class="fas fa-undo"></i>
340
+ </button>
341
+ <button id="randomize-btn" class="bg-gray-800 hover:bg-gray-700 text-gray-300 p-2 rounded-lg">
342
+ <i class="fas fa-random"></i>
343
+ </button>
344
+ <button id="download-btn" class="bg-gray-800 hover:bg-gray-700 text-gray-300 p-2 rounded-lg">
345
+ <i class="fas fa-download"></i>
346
+ </button>
347
+ </div>
348
+ </div>
349
+
350
+ <div id="output-container" class="bg-gray-800 rounded-xl p-4 h-full min-h-[400px] flex items-center justify-center">
351
+ <div id="placeholder-content" class="text-center">
352
+ <i class="fas fa-image text-6xl text-gray-600 mb-4"></i>
353
+ <p class="text-gray-400">Your generated content will appear here</p>
354
+ <p id="status-text" class="terminal-text text-xs mt-2">SDXL 1.0 model loaded | ControlNet ready</p>
355
+ </div>
356
+ <div id="loading-indicator" class="hidden flex-col items-center">
357
+ <div class="loading-spinner mb-4"></div>
358
+ <p class="text-purple-300">Generating your image...</p>
359
+ <p id="generation-status" class="terminal-text text-xs mt-2">Initializing model</p>
360
+ </div>
361
+ <img id="generated-image" src="#" alt="Generated image" class="hidden generated-image">
362
+ </div>
363
+
364
+ <div id="variations-container" class="mt-4 grid grid-cols-4 gap-2">
365
+ <div class="bg-gray-800 rounded-lg h-20 flex items-center justify-center cursor-pointer hover:border-2 hover:border-purple-500">
366
+ <i class="fas fa-plus text-gray-500"></i>
367
+ </div>
368
+ </div>
369
+ </div>
370
+ </div>
371
+ </div>
372
+
373
+ <!-- Features Section -->
374
+ <div class="mt-20">
375
+ <h2 class="tech-font text-3xl font-bold text-center mb-12 gradient-text">Powerful Features</h2>
376
+
377
+ <div class="grid md:grid-cols-3 gap-8">
378
+ <div class="neon-border bg-gray-900 rounded-xl p-6 hover:bg-opacity-100 transition">
379
+ <div class="text-purple-500 text-4xl mb-4">
380
+ <i class="fas fa-brain"></i>
381
+ </div>
382
+ <h3 class="tech-font text-xl font-bold mb-3">AI-Powered Generation</h3>
383
+ <p class="text-gray-300">Leverage state-of-the-art SDXL and ControlNet models to create stunning visuals from simple text prompts.</p>
384
+ </div>
385
+
386
+ <div class="neon-border bg-gray-900 rounded-xl p-6 hover:bg-opacity-100 transition">
387
+ <div class="text-green-500 text-4xl mb-4">
388
+ <i class="fas fa-sliders-h"></i>
389
+ </div>
390
+ <h3 class="tech-font text-xl font-bold mb-3">Precise Control</h3>
391
+ <p class="text-gray-300">Use reference images with ControlNet to maintain composition, depth, or edges while changing style.</p>
392
+ </div>
393
+
394
+ <div class="neon-border bg-gray-900 rounded-xl p-6 hover:bg-opacity-100 transition">
395
+ <div class="text-yellow-500 text-4xl mb-4">
396
+ <i class="fas fa-templates"></i>
397
+ </div>
398
+ <h3 class="tech-font text-xl font-bold mb-3">Smart Templates</h3>
399
+ <p class="text-gray-300">Choose from hundreds of professionally designed templates optimized for each social platform.</p>
400
+ </div>
401
+ </div>
402
+ </div>
403
+
404
+ <!-- Recent Creations -->
405
+ <div class="mt-20">
406
+ <div class="flex justify-between items-center mb-8">
407
+ <h2 class="tech-font text-3xl font-bold gradient-text">Recent Creations</h2>
408
+ <button class="text-purple-400 hover:text-white flex items-center">
409
+ View All <i class="fas fa-arrow-right ml-2"></i>
410
+ </button>
411
+ </div>
412
+
413
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
414
+ <div class="relative group overflow-hidden rounded-lg h-48">
415
+ <img src="https://source.unsplash.com/random/300x300/?cyberpunk" alt="" class="w-full h-full object-cover">
416
+ <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-0 group-hover:opacity-100 transition flex items-end p-4">
417
+ <div>
418
+ <p class="text-white font-medium">"Cyberpunk cityscape"</p>
419
+ <p class="text-purple-300 text-sm">SDXL + ControlNet</p>
420
+ </div>
421
+ </div>
422
+ </div>
423
+
424
+ <div class="relative group overflow-hidden rounded-lg h-48">
425
+ <img src="https://source.unsplash.com/random/300x300/?portrait" alt="" class="w-full h-full object-cover">
426
+ <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-0 group-hover:opacity-100 transition flex items-end p-4">
427
+ <div>
428
+ <p class="text-white font-medium">"Professional headshot"</p>
429
+ <p class="text-purple-300 text-sm">SDXL Photoreal</p>
430
+ </div>
431
+ </div>
432
+ </div>
433
+
434
+ <div class="relative group overflow-hidden rounded-lg h-48">
435
+ <img src="https://source.unsplash.com/random/300x300/?product" alt="" class="w-full h-full object-cover">
436
+ <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-0 group-hover:opacity-100 transition flex items-end p-4">
437
+ <div>
438
+ <p class="text-white font-medium">"Minimal product display"</p>
439
+ <p class="text-purple-300 text-sm">ControlNet Edges</p>
440
+ </div>
441
+ </div>
442
+ </div>
443
+
444
+ <div class="relative group overflow-hidden rounded-lg h-48">
445
+ <img src="https://source.unsplash.com/random/300x300/?abstract" alt="" class="w-full h-full object-cover">
446
+ <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-0 group-hover:opacity-100 transition flex items-end p-4">
447
+ <div>
448
+ <p class="text-white font-medium">"Colorful abstract art"</p>
449
+ <p class="text-purple-300 text-sm">SDXL Digital Art</p>
450
+ </div>
451
+ </div>
452
+ </div>
453
+ </div>
454
+ </div>
455
+ </main>
456
+
457
+ <!-- Footer -->
458
+ <footer class="bg-black bg-opacity-80 border-t border-purple-900 mt-20">
459
+ <div class="max-w-7xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
460
+ <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
461
+ <div>
462
+ <h3 class="tech-font text-lg font-bold gradient-text mb-4">soc.io</h3>
463
+ <p class="text-gray-400">AI-powered social media content creation for the modern creator.</p>
464
+ <div class="flex gap-4 mt-4">
465
+ <a href="#" class="text-gray-400 hover:text-purple-400"><i class="fab fa-twitter"></i></a>
466
+ <a href="#" class="text-gray-400 hover:text-purple-400"><i class="fab fa-instagram"></i></a>
467
+ <a href="#" class="text-gray-400 hover:text-purple-400"><i class="fab fa-discord"></i></a>
468
+ </div>
469
+ </div>
470
+
471
+ <div>
472
+ <h3 class="tech-font text-sm font-bold text-gray-300 mb-4">PRODUCT</h3>
473
+ <ul class="space-y-2">
474
+ <li><a href="#" class="text-gray-400 hover:text-white">Features</a></li>
475
+ <li><a href="#" class="text-gray-400 hover:text-white">Pricing</a></li>
476
+ <li><a href="#" class="text-gray-400 hover:text-white">Templates</a></li>
477
+ <li><a href="#" class="text-gray-400 hover:text-white">API</a></li>
478
+ </ul>
479
+ </div>
480
+
481
+ <div>
482
+ <h3 class="tech-font text-sm font-bold text-gray-300 mb-4">RESOURCES</h3>
483
+ <ul class="space-y-2">
484
+ <li><a href="#" class="text-gray-400 hover:text-white">Documentation</a></li>
485
+ <li><a href="#" class="text-gray-400 hover:text-white">Tutorials</a></li>
486
+ <li><a href="#" class="text-gray-400 hover:text-white">Blog</a></li>
487
+ <li><a href="#" class="text-gray-400 hover:text-white">Community</a></li>
488
+ </ul>
489
+ </div>
490
+
491
+ <div>
492
+ <h3 class="tech-font text-sm font-bold text-gray-300 mb-4">NEWSLETTER</h3>
493
+ <p class="text-gray-400 mb-4">Subscribe for updates and AI tips.</p>
494
+ <div class="flex">
495
+ <input type="email" placeholder="Your email" class="bg-gray-800 text-white px-4 py-2 rounded-l-lg focus:outline-none focus:ring-1 focus:ring-purple-500 w-full">
496
+ <button class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-r-lg">
497
+ <i class="fas fa-paper-plane"></i>
498
+ </button>
499
+ </div>
500
+ </div>
501
+ </div>
502
+
503
+ <div class="border-t border-gray-800 mt-12 pt-8 flex flex-col md:flex-row justify-between items-center">
504
+ <p class="text-gray-500 text-sm">© 2023 soc.io. All rights reserved.</p>
505
+ <div class="flex gap-6 mt-4 md:mt-0">
506
+ <a href="#" class="text-gray-500 hover:text-gray-300 text-sm">Privacy</a>
507
+ <a href="#" class="text-gray-500 hover:text-gray-300 text-sm">Terms</a>
508
+ <a href="#" class="text-gray-500 hover:text-gray-300 text-sm">Cookies</a>
509
+ </div>
510
+ </div>
511
+ </div>
512
+ </footer>
513
+
514
+ <script>
515
+ // Store API key in localStorage
516
+ let apiKey = localStorage.getItem('hf_api_key');
517
+ let generatedImages = [];
518
+
519
+ // DOM elements
520
+ const apiKeyModal = document.getElementById('api-key-modal');
521
+ const apiKeyInput = document.getElementById('api-key-input');
522
+ const saveApiKeyBtn = document.getElementById('save-api-key');
523
+ const cancelApiKeyBtn = document.getElementById('cancel-api-key');
524
+ const closeModalBtn = document.getElementById('close-modal');
525
+ const generateNowBtn = document.getElementById('generate-now-btn');
526
+ const startCreatingBtn = document.getElementById('start-creating');
527
+ const generateBtn = document.getElementById('generate-btn');
528
+ const promptInput = document.getElementById('prompt-input');
529
+ const styleSelect = document.getElementById('style-select');
530
+ const aspectRatioSelect = document.getElementById('aspect-ratio-select');
531
+ const outputContainer = document.getElementById('output-container');
532
+ const placeholderContent = document.getElementById('placeholder-content');
533
+ const loadingIndicator = document.getElementById('loading-indicator');
534
+ const generatedImage = document.getElementById('generated-image');
535
+ const statusText = document.getElementById('status-text');
536
+ const generationStatus = document.getElementById('generation-status');
537
+ const uploadArea = document.getElementById('upload-area');
538
+ const fileInput = document.getElementById('file-input');
539
+ const previewContainer = document.getElementById('preview-container');
540
+ const previewImage = document.getElementById('preview-image');
541
+ const removeImageBtn = document.getElementById('remove-image');
542
+ const advancedToggle = document.getElementById('advanced-toggle');
543
+ const advancedControls = document.getElementById('advanced-controls');
544
+ const downloadBtn = document.getElementById('download-btn');
545
+ const undoBtn = document.getElementById('undo-btn');
546
+ const randomizeBtn = document.getElementById('randomize-btn');
547
+ const promptSuggestionsBtn = document.getElementById('prompt-suggestions');
548
+ const variationsContainer = document.getElementById('variations-container');
549
+ const guidanceScale = document.getElementById('guidance-scale');
550
+ const stepsInput = document.getElementById('steps-input');
551
+ const seedInput = document.getElementById('seed-input');
552
+
553
+ // Modal control
554
+ function showApiKeyModal() {
555
+ apiKeyModal.classList.add('active');
556
+ if (apiKey) {
557
+ apiKeyInput.value = apiKey;
558
+ }
559
+ }
560
+
561
+ function hideApiKeyModal() {
562
+ apiKeyModal.classList.remove('active');
563
+ }
564
+
565
+ // Event listeners for modal
566
+ [saveApiKeyBtn, cancelApiKeyBtn, closeModalBtn].forEach(btn => {
567
+ btn.addEventListener('click', (e) => {
568
+ e.preventDefault();
569
+ if (btn === saveApiKeyBtn && apiKeyInput.value) {
570
+ apiKey = apiKeyInput.value;
571
+ localStorage.setItem('hf_api_key', apiKey);
572
+ updateStatus('API key saved successfully');
573
+ }
574
+ hideApiKeyModal();
575
+ });
576
+ });
577
+
578
+ // Check for API key on actions that require it
579
+ function checkApiKey() {
580
+ if (!apiKey) {
581
+ showApiKeyModal();
582
+ return false;
583
+ }
584
+ return true;
585
+ }
586
+
587
+ // Generate image function
588
+ async function generateImage() {
589
+ if (!checkApiKey()) return;
590
+
591
+ const prompt = promptInput.value.trim();
592
+ if (!prompt) {
593
+ updateStatus('Please enter a prompt', 'error');
594
+ return;
595
+ }
596
+
597
+ // Show loading state
598
+ placeholderContent.classList.add('hidden');
599
+ loadingIndicator.classList.remove('hidden');
600
+ generatedImage.classList.add('hidden');
601
+ outputContainer.classList.add('neon-border');
602
+
603
+ // Get generation parameters
604
+ const style = styleSelect.value;
605
+ const aspectRatio = aspectRatioSelect.value;
606
+ const guidance = parseFloat(guidanceScale.value);
607
+ const steps = parseInt(stepsInput.value);
608
+ const seed = seedInput.value ? parseInt(seedInput.value) : Math.floor(Math.random() * 1000000);
609
+
610
+ // Update status messages
611
+ updateGenerationStatus('Validating API key...');
612
+ await delay(1000);
613
+
614
+ updateGenerationStatus('Initializing SDXL model...');
615
+ await delay(1500);
616
+
617
+ updateGenerationStatus('Processing prompt...');
618
+ await delay(2000);
619
+
620
+ updateGenerationStatus('Generating image...');
621
+ await delay(2500);
622
+
623
+ try {
624
+ // In a real app, this would call the Hugging Face API
625
+ // For demo purposes, we'll simulate the API call
626
+ const imageUrl = await mockHuggingFaceAPICall(prompt, style, aspectRatio, guidance, steps, seed);
627
+
628
+ // Store the generated image
629
+ generatedImages.push(imageUrl);
630
+
631
+ // Display the image
632
+ displayGeneratedImage(imageUrl);
633
+ updateStatus('Image generated successfully!');
634
+
635
+ // Generate variations
636
+ generateVariations();
637
+
638
+ } catch (error) {
639
+ console.error('Error generating image:', error);
640
+ updateStatus(`Error: ${error.message}`, 'error');
641
+ placeholderContent.classList.remove('hidden');
642
+ loadingIndicator.classList.add('hidden');
643
+ }
644
+ }
645
+
646
+ // Mock Hugging Face API call
647
+ async function mockHuggingFaceAPICall(prompt, style, aspectRatio, guidance, steps, seed) {
648
+ // This is just a simulation - in a real app, you would call the actual API
649
+ console.log('Mock API call with:', {
650
+ prompt,
651
+ style,
652
+ aspectRatio,
653
+ guidance,
654
+ steps,
655
+ seed
656
+ });
657
+
658
+ // Map styles to different Unsplash categories
659
+ const styleMap = {
660
+ 'photorealistic': 'portrait',
661
+ 'digital_art': 'abstract,art',
662
+ '3d_render': '3d,render',
663
+ 'anime': 'anime',
664
+ 'watercolor': 'watercolor,painting',
665
+ 'cyberpunk': 'cyberpunk'
666
+ };
667
+
668
+ // Get dimensions based on aspect ratio
669
+ const dimensions = getDimensionsFromAspectRatio(aspectRatio);
670
+
671
+ // Return a random image from Unsplash based on the style
672
+ return `https://source.unsplash.com/random/${dimensions.width}x${dimensions.height}/?${styleMap[style] || 'portrait'}&${seed}`;
673
+ }
674
+
675
+ function getDimensionsFromAspectRatio(ratio) {
676
+ switch(ratio) {
677
+ case '1:1': return { width: 768, height: 768 };
678
+ case '4:5': return { width: 640, height: 800 };
679
+ case '16:9': return { width: 1024, height: 576 };
680
+ case '9:16': return { width: 432, height: 768 };
681
+ default: return { width: 768, height: 768 };
682
+ }
683
+ }
684
+
685
+ function displayGeneratedImage(imageUrl) {
686
+ generatedImage.src = imageUrl;
687
+ loadingIndicator.classList.add('hidden');
688
+ generatedImage.classList.remove('hidden');
689
+
690
+ // Enable download button
691
+ downloadBtn.onclick = () => {
692
+ downloadImage(imageUrl);
693
+ };
694
+ }
695
+
696
+ function downloadImage(url) {
697
+ const a = document.createElement('a');
698
+ a.href = url;
699
+ a.download = `soc.io-${Date.now()}.jpg`;
700
+ document.body.appendChild(a);
701
+ a.click();
702
+ document.body.removeChild(a);
703
+ updateStatus('Image downloaded');
704
+ }
705
+
706
+ function generateVariations() {
707
+ // Clear previous variations
708
+ variationsContainer.innerHTML = '';
709
+
710
+ // Add 3 variations
711
+ for (let i = 0; i < 3; i++) {
712
+ const variation = document.createElement('div');
713
+ variation.className = 'bg-gray-800 rounded-lg h-20 overflow-hidden';
714
+ variation.innerHTML = `<img src="https://source.unsplash.com/random/150x150/?${styleSelect.value}&${Date.now() + i}" class="w-full h-full object-cover" alt="Variation ${i+1}">`;
715
+
716
+ variation.addEventListener('click', () => {
717
+ // When a variation is clicked, display it as the main image
718
+ const imgUrl = variation.querySelector('img').src;
719
+ generatedImages.push(imgUrl);
720
+ displayGeneratedImage(imgUrl);
721
+ updateStatus('Variation loaded');
722
+ });
723
+
724
+ variationsContainer.appendChild(variation);
725
+ }
726
+ }
727
+
728
+ function updateStatus(message, type = 'success') {
729
+ statusText.textContent = message;
730
+ statusText.className = 'terminal-text text-xs mt-2';
731
+ if (type === 'error') {
732
+ statusText.classList.add('text-red-400');
733
+ } else {
734
+ statusText.classList.add('text-green-400');
735
+ }
736
+ }
737
+
738
+ function updateGenerationStatus(message) {
739
+ generationStatus.textContent = message;
740
+ }
741
+
742
+ function delay(ms) {
743
+ return new Promise(resolve => setTimeout(resolve, ms));
744
+ }
745
+
746
+ // Image upload handling
747
+ uploadArea.addEventListener('click', () => fileInput.click());
748
+
749
+ fileInput.addEventListener('change', (e) => {
750
+ const file = e.target.files[0];
751
+ if (file) {
752
+ const reader = new FileReader();
753
+ reader.onload = (event) => {
754
+ previewImage.src = event.target.result;
755
+ previewContainer.classList.remove('hidden');
756
+ uploadArea.classList.add('hidden');
757
+ };
758
+ reader.readAsDataURL(file);
759
+ }
760
+ });
761
+
762
+ removeImageBtn.addEventListener('click', (e) => {
763
+ e.stopPropagation();
764
+ fileInput.value = '';
765
+ previewContainer.classList.add('hidden');
766
+ uploadArea.classList.remove('hidden');
767
+ });
768
+
769
+ // Drag and drop for image upload
770
+ uploadArea.addEventListener('dragover', (e) => {
771
+ e.preventDefault();
772
+ uploadArea.classList.add('border-purple-500', 'bg-gray-800');
773
+ });
774
+
775
+ uploadArea.addEventListener('dragleave', () => {
776
+ uploadArea.classList.remove('border-purple-500', 'bg-gray-800');
777
+ });
778
+
779
+ uploadArea.addEventListener('drop', (e) => {
780
+ e.preventDefault();
781
+ uploadArea.classList.remove('border-purple-500', 'bg-gray-800');
782
+
783
+ const file = e.dataTransfer.files[0];
784
+ if (file && (file.type === 'image/jpeg' || file.type === 'image/png')) {
785
+ fileInput.files = e.dataTransfer.files;
786
+ const event = new Event('change');
787
+ fileInput.dispatchEvent(event);
788
+ }
789
+ });
790
+
791
+ // Advanced controls toggle
792
+ advancedToggle.addEventListener('change', () => {
793
+ if (advancedToggle.checked) {
794
+ advancedControls.classList.remove('hidden');
795
+ } else {
796
+ advancedControls.classList.add('hidden');
797
+ }
798
+ });
799
+
800
+ // Generate buttons
801
+ [generateNowBtn, startCreatingBtn, generateBtn].forEach(btn => {
802
+ btn.addEventListener('click', (e) => {
803
+ e.preventDefault();
804
+ if (btn === generateNowBtn) {
805
+ generateImage();
806
+ } else {
807
+ // Scroll to generator section
808
+ document.querySelector('.neon-border.rounded-xl').scrollIntoView({
809
+ behavior: 'smooth'
810
+ });
811
+ }
812
+ });
813
+ });
814
+
815
+ // Randomize button - generates random prompt
816
+ randomizeBtn.addEventListener('click', () => {
817
+ const randomPrompts = [
818
+ "A futuristic cityscape at night with neon lights and flying cars",
819
+ "A majestic lion in the savanna at golden hour",
820
+ "An astronaut floating in space with Earth in the background",
821
+ "A cyberpunk hacker in a dark room with multiple monitors",
822
+ "A magical forest with glowing plants and fairies",
823
+ "A steampunk airship flying over Victorian London",
824
+ "A cute anime character with pink hair and big eyes",
825
+ "A watercolor painting of a sunset over mountains"
826
+ ];
827
+
828
+ promptInput.value = randomPrompts[Math.floor(Math.random() * randomPrompts.length)];
829
+ updateStatus('Random prompt generated');
830
+ });
831
+
832
+ // Prompt suggestions button
833
+ promptSuggestionsBtn.addEventListener('click', () => {
834
+ const suggestions = [
835
+ "Try adding more details like lighting, style, or composition",
836
+ "Example: 'A photorealistic portrait of a woman with freckles, soft lighting'",
837
+ "Example: 'Cyberpunk city at night, neon lights, rain on streets'",
838
+ "Example: 'Cute anime girl with blue hair, wearing school uniform'"
839
+ ];
840
+
841
+ alert("Prompt Tips:\n\n" + suggestions.join("\n\n"));
842
+ });
843
+
844
+ // Undo button - goes back to previous generated image
845
+ undoBtn.addEventListener('click', () => {
846
+ if (generatedImages.length > 1) {
847
+ generatedImages.pop(); // Remove current image
848
+ const prevImage = generatedImages[generatedImages.length - 1];
849
+ displayGeneratedImage(prevImage);
850
+ updateStatus('Reverted to previous image');
851
+ } else if (generatedImages.length === 1) {
852
+ generatedImages = [];
853
+ generatedImage.classList.add('hidden');
854
+ placeholderContent.classList.remove('hidden');
855
+ updateStatus('Generation cleared');
856
+ } else {
857
+ updateStatus('Nothing to undo', 'error');
858
+ }
859
+ });
860
+
861
+ // Initialize typing effect for status text
862
+ document.addEventListener('DOMContentLoaded', function() {
863
+ const elements = document.querySelectorAll('.slide-in');
864
+
865
+ const observer = new IntersectionObserver((entries) => {
866
+ entries.forEach(entry => {
867
+ if (entry.isIntersecting) {
868
+ entry.target.style.opacity = 1;
869
+ entry.target.style.transform = 'translateY(0)';
870
+ }
871
+ });
872
+ }, { threshold: 0.1 });
873
+
874
+ elements.forEach(el => {
875
+ el.style.opacity = 0;
876
+ el.style.transform = 'translateY(20px)';
877
+ el.style.transition = 'all 0.5s ease-out';
878
+ observer.observe(el);
879
+ });
880
+
881
+ // Terminal-like effect for status text
882
+ const originalText = statusText.textContent;
883
+ statusText.textContent = '';
884
+
885
+ let i = 0;
886
+ const typingEffect = setInterval(() => {
887
+ if (i < originalText.length) {
888
+ statusText.textContent += originalText.charAt(i);
889
+ i++;
890
+ } else {
891
+ clearInterval(typingEffect);
892
+ }
893
+ }, 50);
894
+
895
+ // Initialize seed value
896
+ seedInput.value = Math.floor(Math.random() * 1000000);
897
+ });
898
+ </script>
899
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=pauloyatowo/soc-io" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p>
900
+ <section class="image-generation-section">
901
+ <textarea id="promptInput" placeholder="Enter your ad prompt here...">A minimal, stylish Instagram ad for Brilla.ng, a professional cleaning service targeting Lagos homeowners and businesses. The visual features a spotless, modern Lagos living room or office with clean lines and natural light. A bold yet elegant text overlay says: “We don’t cut corners, we clean them.” The Brilla.ng logo is subtly placed in the corner. Use soft whites, warm neutrals, and a hint of the brand’s color for accen...
902
+ <button onclick="generateImage()">Generate Ad</button>
903
+ <div id="imageContainer"></div>
904
+ </section>
905
+
906
+ <script>
907
+ async function generateImage() {
908
+ const prompt = document.getElementById('promptInput').value;
909
+ const response = await fetch('/generate', {
910
+ method: 'POST',
911
+ headers: {
912
+ 'Content-Type': 'application/json'
913
+ },
914
+ body: JSON.stringify({ prompt })
915
+ });
916
+ if (!response.ok) {
917
+ alert("Failed to generate image.");
918
+ return;
919
+ }
920
+ const blob = await response.blob();
921
+ const imageUrl = URL.createObjectURL(blob);
922
+ document.getElementById('imageContainer').innerHTML = `<img src="${imageUrl}" alt="Generated Ad" style="max-width:100%;margin-top:1em;" />`;
923
+ }
924
+ </script>
925
+ </body>
926
+
927
+ </html>
style.css CHANGED
@@ -1,41 +1,28 @@
1
-
2
  body {
3
- padding: 2rem;
4
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
5
- background-color: #f9f9f9;
6
  }
7
 
8
  h1 {
9
- font-size: 20px;
10
- margin-top: 0;
11
  }
12
 
13
  p {
14
- color: rgb(107, 114, 128);
15
- font-size: 15px;
16
- margin-bottom: 10px;
17
- margin-top: 5px;
18
  }
19
 
20
  .card {
21
- max-width: 620px;
22
- margin: 0 auto;
23
- padding: 16px;
24
- border: 1px solid lightgray;
25
- border-radius: 16px;
26
- background-color: #fff;
27
  }
28
 
29
  .card p:last-child {
30
- margin-bottom: 0;
31
- }
32
-
33
- button {
34
- padding: 10px 20px;
35
- margin-top: 10px;
36
- background-color: #4f46e5;
37
- color: white;
38
- border: none;
39
- border-radius: 8px;
40
- cursor: pointer;
41
  }
 
 
1
  body {
2
+ padding: 2rem;
3
+ font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
4
  }
5
 
6
  h1 {
7
+ font-size: 16px;
8
+ margin-top: 0;
9
  }
10
 
11
  p {
12
+ color: rgb(107, 114, 128);
13
+ font-size: 15px;
14
+ margin-bottom: 10px;
15
+ margin-top: 5px;
16
  }
17
 
18
  .card {
19
+ max-width: 620px;
20
+ margin: 0 auto;
21
+ padding: 16px;
22
+ border: 1px solid lightgray;
23
+ border-radius: 16px;
 
24
  }
25
 
26
  .card p:last-child {
27
+ margin-bottom: 0;
 
 
 
 
 
 
 
 
 
 
28
  }