jkorstad commited on
Commit
5d49db1
·
verified ·
1 Parent(s): f963809

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +1131 -0
app.py ADDED
@@ -0,0 +1,1131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === index.html ===
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>ComfyUI Workflow Studio - AI-Powered Workflow Generator</title>
8
+ <meta name="description" content="Generate and customize ComfyUI workflows with AI assistance. Templates for 3D, audio, image generation and more.">
9
+ <meta name="keywords" content="ComfyUI, AI, Workflow, Stable Diffusion, 3D, Audio, Image Generation">
10
+ <link rel="stylesheet" href="assets/css/styles.css">
11
+ <link rel="preconnect" href="https://fonts.googleapis.com">
12
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
13
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
14
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
15
+ </head>
16
+ <body>
17
+ <!-- Header -->
18
+ <header class="header">
19
+ <div class="container">
20
+ <div class="header-content">
21
+ <div class="logo">
22
+ <i class="fas fa-cube"></i>
23
+ <span>ComfyUI Studio</span>
24
+ </div>
25
+ <nav class="nav">
26
+ <a href="#templates" class="nav-link">Templates</a>
27
+ <a href="#generator" class="nav-link">AI Generator</a>
28
+ <a href="#workflows" class="nav-link">My Workflows</a>
29
+ <a href="#docs" class="nav-link">Docs</a>
30
+ </nav>
31
+ <div class="header-actions">
32
+ <button class="btn btn-secondary" onclick="toggleTheme()">
33
+ <i class="fas fa-moon"></i>
34
+ </button>
35
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">
36
+ Built with anycoder
37
+ </a>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </header>
42
+
43
+ <!-- Hero Section -->
44
+ <section class="hero">
45
+ <div class="container">
46
+ <div class="hero-content">
47
+ <h1 class="hero-title">AI-Powered ComfyUI Workflow Generator</h1>
48
+ <p class="hero-subtitle">Create stunning AI workflows with natural language. Start with templates for 3D, audio, image generation, and more.</p>
49
+ <div class="hero-buttons">
50
+ <button class="btn btn-primary btn-large" onclick="scrollToSection('generator')">
51
+ <i class="fas fa-magic"></i>
52
+ Start Creating
53
+ </button>
54
+ <button class="btn btn-outline btn-large" onclick="scrollToSection('templates')">
55
+ <i class="fas fa-th-large"></i>
56
+ Browse Templates
57
+ </button>
58
+ </div>
59
+ <div class="stats">
60
+ <div class="stat">
61
+ <span class="stat-number">50+</span>
62
+ <span class="stat-label">Templates</span>
63
+ </div>
64
+ <div class="stat">
65
+ <span class="stat-number">Zero</span>
66
+ <span class="stat-label">GPU Cost</span>
67
+ </div>
68
+ <div class="stat">
69
+ <span class="stat-number">∞</span>
70
+ <span class="stat-label">Possibilities</span>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </section>
76
+
77
+ <!-- Template Gallery -->
78
+ <section id="templates" class="section">
79
+ <div class="container">
80
+ <div class="section-header">
81
+ <h2 class="section-title">Workflow Templates</h2>
82
+ <p class="section-subtitle">Start with pre-built templates for various AI tasks</p>
83
+ </div>
84
+ <div class="template-categories">
85
+ <button class="category-btn active" data-category="all">All</button>
86
+ <button class="category-btn" data-category="image">Image</button>
87
+ <button class="category-btn" data-category="3d">3D</button>
88
+ <button class="category-btn" data-category="audio">Audio</button>
89
+ <button class="category-btn" data-category="video">Video</button>
90
+ <button class="category-btn" data-category="text">Text</button>
91
+ </div>
92
+ <div class="template-grid" id="templateGrid">
93
+ <!-- Templates will be dynamically inserted here -->
94
+ </div>
95
+ </div>
96
+ </section>
97
+
98
+ <!-- AI Workflow Generator -->
99
+ <section id="generator" class="section section-alt">
100
+ <div class="container">
101
+ <div class="section-header">
102
+ <h2 class="section-title">AI Workflow Generator</h2>
103
+ <p class="section-subtitle">Describe your workflow in natural language and let AI create it for you</p>
104
+ </div>
105
+ <div class="generator-container">
106
+ <div class="generator-input">
107
+ <div class="input-group">
108
+ <label for="workflowPrompt">Describe your workflow</label>
109
+ <textarea id="workflowPrompt" placeholder="E.g., Generate 20 different ants with various elemental traits (fire, ice, electric) and different sizes for a game. Create image to textured 3D workflow..."></textarea>
110
+ </div>
111
+ <div class="input-group">
112
+ <label for="batchInput">Batch Generation (Optional)</label>
113
+ <textarea id="batchInput" placeholder="Enter multiple prompts (one per line) or let AI generate variations automatically..."></textarea>
114
+ </div>
115
+ <div class="input-options">
116
+ <div class="option-group">
117
+ <label>
118
+ <input type="checkbox" id="useTemplate" checked>
119
+ Start from template
120
+ </label>
121
+ </div>
122
+ <div class="option-group">
123
+ <label>
124
+ <input type="checkbox" id="autoVariations" checked>
125
+ Auto-generate variations
126
+ </label>
127
+ </div>
128
+ <div class="option-group">
129
+ <label>
130
+ <input type="checkbox" id="optimize" checked>
131
+ Optimize for Zero GPU
132
+ </label>
133
+ </div>
134
+ </div>
135
+ <div class="input-group">
136
+ <label for="outputFormat">Output Format</label>
137
+ <select id="outputFormat" class="form-select">
138
+ <option value="image">2D Images</option>
139
+ <option value="3d">3D Models</option>
140
+ <option value="textured3d">Textured 3D</option>
141
+ <option value="audio">Audio</option>
142
+ <option value="video">Video</option>
143
+ </select>
144
+ </div>
145
+ <button class="btn btn-primary btn-large" onclick="generateWorkflow()">
146
+ <i class="fas fa-sparkles"></i>
147
+ Generate Workflow
148
+ </button>
149
+ </div>
150
+ <div class="generator-preview" id="generatorPreview">
151
+ <div class="preview-placeholder">
152
+ <i class="fas fa-code-branch"></i>
153
+ <p>Your generated workflow will appear here</p>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ </div>
158
+ </section>
159
+
160
+ <!-- Workflow Editor -->
161
+ <section id="workflows" class="section">
162
+ <div class="container">
163
+ <div class="section-header">
164
+ <h2 class="section-title">Workflow Editor</h2>
165
+ <p class="section-subtitle">Visual workflow editor with drag-and-drop nodes and Zero GPU optimization</p>
166
+ </div>
167
+ <div class="editor-container">
168
+ <div class="editor-toolbar">
169
+ <div class="toolbar-group">
170
+ <button class="tool-btn" onclick="addNode('input')">
171
+ <i class="fas fa-sign-in-alt"></i> Input
172
+ </button>
173
+ <button class="tool-btn" onclick="addNode('batch')">
174
+ <i class="fas fa-layer-group"></i> Batch
175
+ </button>
176
+ <button class="tool-btn" onclick="addNode('model')">
177
+ <i class="fas fa-brain"></i> Model
178
+ </button>
179
+ <button class="tool-btn" onclick="addNode('process')">
180
+ <i class="fas fa-cogs"></i> Process
181
+ </button>
182
+ <button class="tool-btn" onclick="addNode('3d')">
183
+ <i class="fas fa-cube"></i> 3D
184
+ </button>
185
+ <button class="tool-btn" onclick="addNode('output')">
186
+ <i class="fas fa-sign-out-alt"></i> Output
187
+ </button>
188
+ </div>
189
+ <div class="toolbar-group">
190
+ <button class="tool-btn" onclick="queueBatch()">
191
+ <i class="fas fa-list-ol"></i> Queue Batch
192
+ </button>
193
+ <button class="tool-btn" onclick="runWorkflow()">
194
+ <i class="fas fa-play"></i> Run
195
+ </button>
196
+ <button class="tool-btn" onclick="saveWorkflow()">
197
+ <i class="fas fa-save"></i> Save
198
+ </button>
199
+ <button class="tool-btn" onclick="exportWorkflow()">
200
+ <i class="fas fa-download"></i> Export
201
+ </button>
202
+ </div>
203
+ </div>
204
+ <div class="editor-canvas" id="editorCanvas">
205
+ <div class="canvas-placeholder">
206
+ <i class="fas fa-project-diagram"></i>
207
+ <p>Drag nodes here to build your workflow</p>
208
+ </div>
209
+ </div>
210
+ </div>
211
+ </div>
212
+ </section>
213
+
214
+ <!-- Results Section -->
215
+ <section id="results" class="section section-alt">
216
+ <div class="container">
217
+ <div class="section-header">
218
+ <h2 class="section-title">Results</h2>
219
+ <p class="section-subtitle">View and download your generated content</p>
220
+ </div>
221
+ <div class="results-grid" id="resultsGrid">
222
+ <div class="result-placeholder">
223
+ <i class="fas fa-images"></i>
224
+ <p>Your generated results will appear here</p>
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </section>
229
+
230
+ <!-- Footer -->
231
+ <footer class="footer">
232
+ <div class="container">
233
+ <div class="footer-content">
234
+ <div class="footer-section">
235
+ <div class="footer-logo">
236
+ <i class="fas fa-cube"></i>
237
+ <span>ComfyUI Studio</span>
238
+ </div>
239
+ <p>AI-powered workflow generation for ComfyUI</p>
240
+ </div>
241
+ <div class="footer-section">
242
+ <h4>Resources</h4>
243
+ <a href="#docs">Documentation</a>
244
+ <a href="#templates">Templates</a>
245
+ <a href="#api">API Reference</a>
246
+ </div>
247
+ <div class="footer-section">
248
+ <h4>Community</h4>
249
+ <a href="#">Discord</a>
250
+ <a href="#">GitHub</a>
251
+ <a href="#">Forum</a>
252
+ </div>
253
+ <div class="footer-section">
254
+ <h4>Powered by</h4>
255
+ <p>Zero GPU Backend</p>
256
+ <p>Hugging Face Spaces</p>
257
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
258
+ </div>
259
+ </div>
260
+ <div class="footer-bottom">
261
+ <p>&copy; 2024 ComfyUI Studio. All rights reserved.</p>
262
+ </div>
263
+ </div>
264
+ </footer>
265
+
266
+ <script src="assets/js/app.js"></script>
267
+ </body>
268
+ </html>
269
+
270
+ === assets/css/styles.css ===
271
+ :root {
272
+ --primary-color: #6366f1;
273
+ --primary-dark: #4f46e5;
274
+ --primary-light: #818cf8;
275
+ --secondary-color: #22d3ee;
276
+ --background: #ffffff;
277
+ --surface: #f8fafc;
278
+ --surface-alt: #f1f5f9;
279
+ --text-primary: #1e293b;
280
+ --text-secondary: #64748b;
281
+ --border: #e2e8f0;
282
+ --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
283
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
284
+ --radius: 0.5rem;
285
+ --transition: all 0.3s ease;
286
+ }
287
+
288
+ [data-theme="dark"] {
289
+ --background: #0f172a;
290
+ --surface: #1e293b;
291
+ --surface-alt: #334155;
292
+ --text-primary: #f1f5f9;
293
+ --text-secondary: #94a3b8;
294
+ --border: #475569;
295
+ }
296
+
297
+ * {
298
+ margin: 0;
299
+ padding: 0;
300
+ box-sizing: border-box;
301
+ }
302
+
303
+ body {
304
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
305
+ background: var(--background);
306
+ color: var(--text-primary);
307
+ line-height: 1.6;
308
+ transition: var(--transition);
309
+ }
310
+
311
+ .container {
312
+ max-width: 1200px;
313
+ margin: 0 auto;
314
+ padding: 0 1rem;
315
+ }
316
+
317
+ /* Header */
318
+ .header {
319
+ background: var(--surface);
320
+ border-bottom: 1px solid var(--border);
321
+ position: sticky;
322
+ top: 0;
323
+ z-index: 100;
324
+ backdrop-filter: blur(10px);
325
+ background: rgba(var(--surface), 0.9);
326
+ }
327
+
328
+ .header-content {
329
+ display: flex;
330
+ align-items: center;
331
+ justify-content: space-between;
332
+ padding: 1rem 0;
333
+ }
334
+
335
+ .logo {
336
+ display: flex;
337
+ align-items: center;
338
+ gap: 0.5rem;
339
+ font-size: 1.25rem;
340
+ font-weight: 700;
341
+ color: var(--primary-color);
342
+ }
343
+
344
+ .logo i {
345
+ font-size: 1.5rem;
346
+ }
347
+
348
+ .nav {
349
+ display: flex;
350
+ gap: 2rem;
351
+ }
352
+
353
+ .nav-link {
354
+ color: var(--text-secondary);
355
+ text-decoration: none;
356
+ font-weight: 500;
357
+ transition: var(--transition);
358
+ }
359
+
360
+ .nav-link:hover {
361
+ color: var(--primary-color);
362
+ }
363
+
364
+ .header-actions {
365
+ display: flex;
366
+ align-items: center;
367
+ gap: 1rem;
368
+ }
369
+
370
+ .built-with {
371
+ color: var(--primary-color);
372
+ text-decoration: none;
373
+ font-weight: 500;
374
+ transition: var(--transition);
375
+ }
376
+
377
+ .built-with:hover {
378
+ color: var(--primary-dark);
379
+ }
380
+
381
+ /* Buttons */
382
+ .btn {
383
+ display: inline-flex;
384
+ align-items: center;
385
+ gap: 0.5rem;
386
+ padding: 0.5rem 1rem;
387
+ border: none;
388
+ border-radius: var(--radius);
389
+ font-weight: 500;
390
+ cursor: pointer;
391
+ transition: var(--transition);
392
+ text-decoration: none;
393
+ font-size: 0.875rem;
394
+ }
395
+
396
+ .btn-primary {
397
+ background: var(--primary-color);
398
+ color: white;
399
+ }
400
+
401
+ .btn-primary:hover {
402
+ background: var(--primary-dark);
403
+ transform: translateY(-1px);
404
+ box-shadow: var(--shadow-lg);
405
+ }
406
+
407
+ .btn-secondary {
408
+ background: var(--surface-alt);
409
+ color: var(--text-primary);
410
+ }
411
+
412
+ .btn-secondary:hover {
413
+ background: var(--border);
414
+ }
415
+
416
+ .btn-outline {
417
+ background: transparent;
418
+ color: var(--primary-color);
419
+ border: 2px solid var(--primary-color);
420
+ }
421
+
422
+ .btn-outline:hover {
423
+ background: var(--primary-color);
424
+ color: white;
425
+ }
426
+
427
+ .btn-large {
428
+ padding: 0.75rem 1.5rem;
429
+ font-size: 1rem;
430
+ }
431
+
432
+ /* Hero Section */
433
+ .hero {
434
+ padding: 4rem 0;
435
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
436
+ color: white;
437
+ overflow: hidden;
438
+ }
439
+
440
+ .hero::before {
441
+ content: '';
442
+ position: absolute;
443
+ top: 0;
444
+ left: 0;
445
+ right: 0;
446
+ bottom: 0;
447
+ background: url('data:image/svg+xml,<svg width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><g fill="%23ffffff" fill-opacity="0.05"><path d="M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z"/></g></g></svg>') repeat;
448
+ opacity: 0.3;
449
+ }
450
+
451
+ .hero-content {
452
+ position: relative;
453
+ text-align: center;
454
+ max-width: 800px;
455
+ margin: 0 auto;
456
+ }
457
+
458
+ .hero-title {
459
+ font-size: 3rem;
460
+ font-weight: 700;
461
+ margin-bottom: 1rem;
462
+ background: linear-gradient(135deg, #ffffff 0%, #e0e7ff 100%);
463
+ -webkit-background-clip: text;
464
+ -webkit-text-fill-color: transparent;
465
+ background-clip: text;
466
+ }
467
+
468
+ .hero-subtitle {
469
+ font-size: 1.25rem;
470
+ margin-bottom: 2rem;
471
+ opacity: 0.9;
472
+ }
473
+
474
+ .hero-buttons {
475
+ display: flex;
476
+ gap: 1rem;
477
+ justify-content: center;
478
+ margin-bottom: 3rem;
479
+ }
480
+
481
+ .stats {
482
+ display: flex;
483
+ justify-content: center;
484
+ gap: 4rem;
485
+ }
486
+
487
+ .stat {
488
+ text-align: center;
489
+ }
490
+
491
+ .stat-number {
492
+ display: block;
493
+ font-size: 2rem;
494
+ font-weight: 700;
495
+ }
496
+
497
+ .stat-label {
498
+ font-size: 0.875rem;
499
+ opacity: 0.8;
500
+ }
501
+
502
+ /* Sections */
503
+ .section {
504
+ padding: 4rem 0;
505
+ }
506
+
507
+ .section-alt {
508
+ background: var(--surface);
509
+ }
510
+
511
+ .section-header {
512
+ text-align: center;
513
+ margin-bottom: 3rem;
514
+ }
515
+
516
+ .section-title {
517
+ font-size: 2.5rem;
518
+ font-weight: 700;
519
+ margin-bottom: 0.5rem;
520
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
521
+ -webkit-background-clip: text;
522
+ -webkit-text-fill-color: transparent;
523
+ background-clip: text;
524
+ }
525
+
526
+ .section-subtitle {
527
+ color: var(--text-secondary);
528
+ font-size: 1.125rem;
529
+ }
530
+
531
+ /* Template Gallery */
532
+ .template-categories {
533
+ display: flex;
534
+ gap: 1rem;
535
+ justify-content: center;
536
+ margin-bottom: 2rem;
537
+ flex-wrap: wrap;
538
+ }
539
+
540
+ .category-btn {
541
+ padding: 0.5rem 1rem;
542
+ border: 2px solid var(--border);
543
+ background: var(--background);
544
+ color: var(--text-secondary);
545
+ border-radius: 2rem;
546
+ cursor: pointer;
547
+ transition: var(--transition);
548
+ }
549
+
550
+ .category-btn.active,
551
+ .category-btn:hover {
552
+ border-color: var(--primary-color);
553
+ color: var(--primary-color);
554
+ background: var(--primary-color);
555
+ background: linear-gradient(135deg, var(--primary-color), var(--primary-light));
556
+ color: white;
557
+ }
558
+
559
+ .template-grid {
560
+ display: grid;
561
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
562
+ gap: 1.5rem;
563
+ }
564
+
565
+ .template-card {
566
+ background: var(--surface);
567
+ border: 1px solid var(--border);
568
+ border-radius: var(--radius);
569
+ padding: 1.5rem;
570
+ transition: var(--transition);
571
+ cursor: pointer;
572
+ }
573
+
574
+ .template-card:hover {
575
+ transform: translateY(-4px);
576
+ box-shadow: var(--shadow-lg);
577
+ border-color: var(--primary-color);
578
+ }
579
+
580
+ .template-icon {
581
+ width: 48px;
582
+ height: 48px;
583
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
584
+ border-radius: var(--radius);
585
+ display: flex;
586
+ align-items: center;
587
+ justify-content: center;
588
+ color: white;
589
+ font-size: 1.5rem;
590
+ margin-bottom: 1rem;
591
+ }
592
+
593
+ .template-title {
594
+ font-size: 1.125rem;
595
+ font-weight: 600;
596
+ margin-bottom: 0.5rem;
597
+ }
598
+
599
+ .template-description {
600
+ color: var(--text-secondary);
601
+ font-size: 0.875rem;
602
+ margin-bottom: 1rem;
603
+ }
604
+
605
+ .template-tags {
606
+ display: flex;
607
+ gap: 0.5rem;
608
+ flex-wrap: wrap;
609
+ }
610
+
611
+ .template-tag {
612
+ padding: 0.25rem 0.5rem;
613
+ background: var(--surface-alt);
614
+ color: var(--text-secondary);
615
+ border-radius: 0.25rem;
616
+ font-size: 0.75rem;
617
+ }
618
+
619
+ /* Generator */
620
+ .generator-container {
621
+ display: grid;
622
+ grid-template-columns: 1fr 1fr;
623
+ gap: 2rem;
624
+ max-width: 1000px;
625
+ margin: 0 auto;
626
+ }
627
+
628
+ .generator-input {
629
+ background: var(--background);
630
+ padding: 2rem;
631
+ border-radius: var(--radius);
632
+ border: 1px solid var(--border);
633
+ }
634
+
635
+ .input-group {
636
+ margin-bottom: 1.5rem;
637
+ }
638
+
639
+ .input-group label {
640
+ display: block;
641
+ margin-bottom: 0.5rem;
642
+ font-weight: 500;
643
+ }
644
+
645
+ .input-group textarea {
646
+ width: 100%;
647
+ min-height: 120px;
648
+ padding: 0.75rem;
649
+ border: 1px solid var(--border);
650
+ border-radius: var(--radius);
651
+ background: var(--surface);
652
+ color: var(--text-primary);
653
+ font-family: inherit;
654
+ resize: vertical;
655
+ }
656
+
657
+ .form-select {
658
+ width: 100%;
659
+ padding: 0.75rem;
660
+ border: 1px solid var(--border);
661
+ border-radius: var(--radius);
662
+ background: var(--surface);
663
+ color: var(--text-primary);
664
+ font-family: inherit;
665
+ cursor: pointer;
666
+ }
667
+
668
+ .input-options {
669
+ display: flex;
670
+ flex-wrap: wrap;
671
+ gap: 1rem;
672
+ margin-bottom: 1.5rem;
673
+ }
674
+
675
+ .option-group label {
676
+ display: flex;
677
+ align-items: center;
678
+ gap: 0.5rem;
679
+ cursor: pointer;
680
+ }
681
+
682
+ .batch-preview {
683
+ background: var(--surface);
684
+ border: 1px solid var(--border);
685
+ border-radius: var(--radius);
686
+ padding: 1rem;
687
+ margin-top: 1rem;
688
+ max-height: 200px;
689
+ overflow-y: auto;
690
+ }
691
+
692
+ .batch-item {
693
+ padding: 0.5rem;
694
+ border-bottom: 1px solid var(--border);
695
+ font-size: 0.875rem;
696
+ }
697
+
698
+ .batch-item:last-child {
699
+ border-bottom: none;
700
+ }
701
+
702
+ .generator-preview {
703
+ background: var(--background);
704
+ border: 1px solid var(--border);
705
+ border-radius: var(--radius);
706
+ padding: 2rem;
707
+ min-height: 300px;
708
+ }
709
+
710
+ .preview-placeholder {
711
+ display: flex;
712
+ flex-direction: column;
713
+ align-items: center;
714
+ justify-content: center;
715
+ height: 100%;
716
+ color: var(--text-secondary);
717
+ }
718
+
719
+ .preview-placeholder i {
720
+ font-size: 3rem;
721
+ margin-bottom: 1rem;
722
+ opacity: 0.5;
723
+ }
724
+
725
+ /* Editor */
726
+ .editor-container {
727
+ background: var(--background);
728
+ border: 1px solid var(--border);
729
+ border-radius: var(--radius);
730
+ overflow: hidden;
731
+ }
732
+
733
+ .editor-toolbar {
734
+ background: var(--surface);
735
+ padding: 1rem;
736
+ border-bottom: 1px solid var(--border);
737
+ display: flex;
738
+ justify-content: space-between;
739
+ flex-wrap: wrap;
740
+ gap: 1rem;
741
+ }
742
+
743
+ .toolbar-group {
744
+ display: flex;
745
+ gap: 0.5rem;
746
+ }
747
+
748
+ .tool-btn {
749
+ padding: 0.5rem 1rem;
750
+ background: var(--background);
751
+ border: 1px solid var(--border);
752
+ border-radius: var(--radius);
753
+ cursor: pointer;
754
+ transition: var(--transition);
755
+ display: flex;
756
+ align-items: center;
757
+ gap: 0.5rem;
758
+ color: var(--text-primary);
759
+ }
760
+
761
+ .tool-btn:hover {
762
+ background: var(--primary-color);
763
+ color: white;
764
+ border-color: var(--primary-color);
765
+ }
766
+
767
+ .editor-canvas {
768
+ min-height: 400px;
769
+ padding: 2rem;
770
+ background: var(--surface);
771
+ position: relative;
772
+ }
773
+
774
+ .canvas-placeholder {
775
+ display: flex;
776
+ flex-direction: column;
777
+ align-items: center;
778
+ justify-content: center;
779
+ height: 100%;
780
+ color: var(--text-secondary);
781
+ }
782
+
783
+ .canvas-placeholder i {
784
+ font-size: 3rem;
785
+ margin-bottom: 1rem;
786
+ opacity: 0.5;
787
+ }
788
+
789
+ /* Results */
790
+ .results-grid {
791
+ display: grid;
792
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
793
+ gap: 1.5rem;
794
+ }
795
+
796
+ .result-card {
797
+ background: var(--surface);
798
+ border: 1px solid var(--border);
799
+ border-radius: var(--radius);
800
+ overflow: hidden;
801
+ transition: var(--transition);
802
+ }
803
+
804
+ .result-card:hover {
805
+ transform: translateY(-2px);
806
+ box-shadow: var(--shadow-lg);
807
+ }
808
+
809
+ .result-image {
810
+ width: 100%;
811
+ height: 200px;
812
+ background: var(--surface-alt);
813
+ display: flex;
814
+ align-items: center;
815
+ justify-content: center;
816
+ color: var(--text-secondary);
817
+ }
818
+
819
+ .result-info {
820
+ padding: 1rem;
821
+ }
822
+
823
+ .result-title {
824
+ font-weight: 600;
825
+ margin-bottom: 0.5rem;
826
+ }
827
+
828
+ .result-meta {
829
+ color: var(--text-secondary);
830
+ font-size: 0.875rem;
831
+ }
832
+
833
+ .result-placeholder {
834
+ grid-column: 1 / -1;
835
+ text-align: center;
836
+ padding: 4rem 2rem;
837
+ color: var(--text-secondary);
838
+ }
839
+
840
+ .result-placeholder i {
841
+ font-size: 3rem;
842
+ margin-bottom: 1rem;
843
+ opacity: 0.5;
844
+ }
845
+
846
+ /* Footer */
847
+ .footer {
848
+ background: var(--surface);
849
+ border-top: 1px solid var(--border);
850
+ padding: 3rem 0 1rem;
851
+ }
852
+
853
+ .footer-content {
854
+ display: grid;
855
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
856
+ gap: 2rem;
857
+ margin-bottom: 2rem;
858
+ }
859
+
860
+ .footer-section h4 {
861
+ margin-bottom: 1rem;
862
+ color: var(--text-primary);
863
+ }
864
+
865
+ .footer-section a {
866
+ display: block;
867
+ color: var(--text-secondary);
868
+ text-decoration: none;
869
+ margin-bottom: 0.5rem;
870
+ transition: var(--transition);
871
+ }
872
+
873
+ .footer-section a:hover {
874
+ color: var(--primary-color);
875
+ }
876
+
877
+ .footer-logo {
878
+ display: flex;
879
+ align-items: center;
880
+ gap: 0.5rem;
881
+ font-size: 1.25rem;
882
+ font-weight: 700;
883
+ color: var(--primary-color);
884
+ margin-bottom: 0.5rem;
885
+ }
886
+
887
+ .footer-bottom {
888
+ padding-top: 2rem;
889
+ border-top: 1px solid var(--border);
890
+ text-align: center;
891
+ color: var(--text-secondary);
892
+ }
893
+
894
+ /* Responsive */
895
+ @media (max-width: 768px) {
896
+ .nav {
897
+ display: none;
898
+ }
899
+
900
+ .hero-title {
901
+ font-size: 2rem;
902
+ }
903
+
904
+ .hero-subtitle {
905
+ font-size: 1rem;
906
+ }
907
+
908
+ .hero-buttons {
909
+ flex-direction: column;
910
+ align-items: center;
911
+ }
912
+
913
+ .stats {
914
+ gap: 2rem;
915
+ }
916
+
917
+ .generator-container {
918
+ grid-template-columns: 1fr;
919
+ }
920
+
921
+ .editor-toolbar {
922
+ flex-direction: column;
923
+ }
924
+
925
+ .template-grid {
926
+ grid-template-columns: 1fr;
927
+ }
928
+ }
929
+
930
+ /* Loading Animation */
931
+ .loading {
932
+ display: inline-block;
933
+ width: 20px;
934
+ height: 20px;
935
+ border: 3px solid var(--border);
936
+ border-radius: 50%;
937
+ border-top-color: var(--primary-color);
938
+ animation: spin 1s ease-in-out infinite;
939
+ }
940
+
941
+ @keyframes spin {
942
+ to { transform: rotate(360deg); }
943
+ }
944
+
945
+ /* Toast Notification */
946
+ .toast {
947
+ position: fixed;
948
+ bottom: 2rem;
949
+ right: 2rem;
950
+ background: var(--surface);
951
+ border: 1px solid var(--border);
952
+ border-radius: var(--radius);
953
+ padding: 1rem 1.5rem;
954
+ box-shadow: var(--shadow-lg);
955
+ display: flex;
956
+ align-items: center;
957
+ gap: 1rem;
958
+ transform: translateX(400px);
959
+ transition: transform 0.3s ease;
960
+ z-index: 1000;
961
+ }
962
+
963
+ .toast.show {
964
+ transform: translateX(0);
965
+ }
966
+
967
+ .toast.success {
968
+ border-color: #10b981;
969
+ color: #10b981;
970
+ }
971
+
972
+ .toast.error {
973
+ border-color: #ef4444;
974
+ color: #ef4444;
975
+ }
976
+
977
+ /* Node Styles */
978
+ .node {
979
+ position: absolute;
980
+ background: var(--background);
981
+ border: 2px solid var(--border);
982
+ border-radius: var(--radius);
983
+ padding: 1rem;
984
+ min-width: 150px;
985
+ cursor: move;
986
+ transition: var(--transition);
987
+ }
988
+
989
+ .node:hover {
990
+ border-color: var(--primary-color);
991
+ box-shadow: var(--shadow-lg);
992
+ }
993
+
994
+ .node.selected {
995
+ border-color: var(--primary-color);
996
+ }
997
+
998
+ .node.batch {
999
+ border-color: var(--secondary-color);
1000
+ }
1001
+
1002
+ .node.batch .node-header {
1003
+ color: var(--secondary-color);
1004
+ }
1005
+
1006
+ .node.3d {
1007
+ border-color: #10b981;
1008
+ }
1009
+
1010
+ .node.3d .node-header {
1011
+ color: #10b981;
1012
+ }
1013
+
1014
+ .node-header {
1015
+ font-weight: 600;
1016
+ margin-bottom: 0.5rem;
1017
+ display: flex;
1018
+ align-items: center;
1019
+ gap: 0.5rem;
1020
+ }
1021
+
1022
+ .node-ports {
1023
+ display: flex;
1024
+ justify-content: space-between;
1025
+ margin-top: 0.5rem;
1026
+ }
1027
+
1028
+ .port {
1029
+ width: 12px;
1030
+ height: 12px;
1031
+ background: var(--primary-color);
1032
+ border-radius: 50%;
1033
+ cursor: pointer;
1034
+ }
1035
+
1036
+ .port.input {
1037
+ margin-left: -6px;
1038
+ }
1039
+
1040
+ .port.output {
1041
+ margin-right: -6px;
1042
+ }
1043
+
1044
+ .batch-indicator {
1045
+ position: absolute;
1046
+ top: -8px;
1047
+ right: -8px;
1048
+ background: var(--secondary-color);
1049
+ color: white;
1050
+ border-radius: 50%;
1051
+ width: 24px;
1052
+ height: 24px;
1053
+ display: flex;
1054
+ align-items: center;
1055
+ justify-content: center;
1056
+ font-size: 0.75rem;
1057
+ font-weight: 600;
1058
+ }
1059
+
1060
+ .queue-status {
1061
+ position: fixed;
1062
+ bottom: 2rem;
1063
+ left: 2rem;
1064
+ background: var(--surface);
1065
+ border: 1px solid var(--border);
1066
+ border-radius: var(--radius);
1067
+ padding: 1rem;
1068
+ box-shadow: var(--shadow-lg);
1069
+ display: none;
1070
+ }
1071
+
1072
+ .queue-status.active {
1073
+ display: block;
1074
+ }
1075
+
1076
+ .queue-progress {
1077
+ margin-top: 0.5rem;
1078
+ background: var(--surface-alt);
1079
+ border-radius: var(--radius);
1080
+ height: 8px;
1081
+ overflow: hidden;
1082
+ }
1083
+
1084
+ .queue-progress-bar {
1085
+ height: 100%;
1086
+ background: var(--primary-color);
1087
+ transition: width 0.3s ease;
1088
+ }
1089
+
1090
+ /* Connection Line */
1091
+ .connection {
1092
+ stroke: var(--primary-color);
1093
+ stroke-width: 2;
1094
+ fill: none;
1095
+ pointer-events: none;
1096
+ }
1097
+
1098
+ /* Animations */
1099
+ @keyframes fadeIn {
1100
+ from {
1101
+ opacity: 0;
1102
+ transform: translateY(20px);
1103
+ }
1104
+ to {
1105
+ opacity: 1;
1106
+ transform: translateY(0);
1107
+ }
1108
+ }
1109
+
1110
+ .fade-in {
1111
+ animation: fadeIn 0.5s ease;
1112
+ }
1113
+
1114
+ /* Scrollbar */
1115
+ ::-webkit-scrollbar {
1116
+ width: 8px;
1117
+ height: 8px;
1118
+ }
1119
+
1120
+ ::-webkit-scrollbar-track {
1121
+ background: var(--surface);
1122
+ }
1123
+
1124
+ ::-webkit-scrollbar-thumb {
1125
+ background: var(--border);
1126
+ border-radius: 4px;
1127
+ }
1128
+
1129
+ ::-webkit-scrollbar-thumb:hover {
1130
+ background: var(--text-secondary);
1131
+ }