eubottura commited on
Commit
5b307fb
·
verified ·
1 Parent(s): e9b8425

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +100 -180
index.html CHANGED
@@ -4,16 +4,16 @@
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>AI Prompt Gen | E-Commerce Asset System v4.8</title>
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link
11
- href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
12
- rel="stylesheet">
13
  <style>
14
  :root {
 
15
  --bg-body: #0f172a;
16
  --bg-card: #1e293b;
 
17
  --bg-input: #334155;
18
  --text-main: #f8fafc;
19
  --text-muted: #94a3b8;
@@ -22,10 +22,13 @@
22
  --accent: #10b981;
23
  --danger: #ef4444;
24
  --border: #334155;
25
- --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
 
26
  --radius: 12px;
 
27
  }
28
 
 
29
  * {
30
  box-sizing: border-box;
31
  margin: 0;
@@ -40,11 +43,13 @@
40
  min-height: 100vh;
41
  display: flex;
42
  flex-direction: column;
 
43
  }
44
 
45
  /* Header */
46
  header {
47
- background-color: var(--bg-card);
 
48
  border-bottom: 1px solid var(--border);
49
  padding: 1rem 2rem;
50
  display: flex;
@@ -58,28 +63,34 @@
58
  .brand {
59
  font-size: 1.25rem;
60
  font-weight: 700;
61
- background: linear-gradient(to right, var(--primary), var(--accent));
62
  -webkit-background-clip: text;
63
  -webkit-text-fill-color: transparent;
64
  letter-spacing: -0.025em;
65
  display: flex;
66
  align-items: center;
67
- gap: 0.5rem;
 
 
 
 
68
  }
69
 
70
  .anycoder-link {
71
  font-size: 0.875rem;
72
  color: var(--text-muted);
73
  text-decoration: none;
74
- transition: color 0.2s;
75
  border: 1px solid var(--border);
76
- padding: 0.25rem 0.75rem;
77
  border-radius: 99px;
 
78
  }
79
 
80
  .anycoder-link:hover {
81
  color: var(--primary);
82
  border-color: var(--primary);
 
83
  }
84
 
85
  /* Main Layout */
@@ -90,17 +101,17 @@
90
  width: 100%;
91
  padding: 2rem;
92
  display: grid;
93
- grid-template-columns: 380px 1fr;
94
- gap: 2rem;
 
95
  }
96
 
97
  /* Sidebar / Inputs */
98
  aside {
99
  background-color: var(--bg-card);
100
  border-radius: var(--radius);
101
- padding: 1.5rem;
102
  border: 1px solid var(--border);
103
- height: fit-content;
104
  position: sticky;
105
  top: 6rem;
106
  box-shadow: var(--shadow);
@@ -134,23 +145,24 @@
134
  background-color: var(--bg-input);
135
  border: 1px solid var(--border);
136
  border-radius: 8px;
137
- padding: 0.75rem 1rem;
138
  color: var(--text-main);
139
  font-family: inherit;
140
  font-size: 0.95rem;
141
- transition: all 0.2s ease;
142
  }
143
 
144
  textarea {
145
  resize: vertical;
146
- min-height: 100px;
147
  }
148
 
149
  input:focus,
150
  textarea:focus {
151
  outline: none;
152
  border-color: var(--primary);
153
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
 
154
  }
155
 
156
  .helper-text {
@@ -158,11 +170,12 @@
158
  color: var(--text-muted);
159
  margin-top: 0.5rem;
160
  font-style: italic;
 
161
  }
162
 
163
  button.btn-primary {
164
  width: 100%;
165
- padding: 0.875rem;
166
  background-color: var(--primary);
167
  color: white;
168
  border: none;
@@ -170,19 +183,22 @@
170
  font-weight: 600;
171
  font-size: 1rem;
172
  cursor: pointer;
173
- transition: background-color 0.2s, transform 0.1s;
174
  display: flex;
175
  justify-content: center;
176
  align-items: center;
177
  gap: 0.5rem;
 
178
  }
179
 
180
  button.btn-primary:hover {
181
  background-color: var(--primary-hover);
 
 
182
  }
183
 
184
  button.btn-primary:active {
185
- transform: scale(0.98);
186
  }
187
 
188
  /* Output Section */
@@ -202,11 +218,19 @@
202
  }
203
 
204
  .status-badge {
205
- font-size: 0.875rem;
206
- padding: 0.25rem 0.75rem;
207
  border-radius: 99px;
208
  background-color: var(--bg-input);
209
  color: var(--text-muted);
 
 
 
 
 
 
 
 
210
  }
211
 
212
  .grid {
@@ -222,16 +246,17 @@
222
  padding: 0;
223
  display: flex;
224
  flex-direction: column;
225
- transition: transform 0.2s, box-shadow 0.2s;
226
  position: relative;
227
  overflow: hidden;
228
- animation: fadeIn 0.5s ease-out;
229
  }
230
 
231
  .card:hover {
232
- transform: translateY(-2px);
233
  box-shadow: var(--shadow);
234
- border-color: var(--primary);
 
235
  }
236
 
237
  .card-header {
@@ -244,7 +269,7 @@
244
  }
245
 
246
  .card-title {
247
- font-size: 0.85rem;
248
  font-weight: 700;
249
  color: var(--primary);
250
  text-transform: uppercase;
@@ -255,12 +280,13 @@
255
  }
256
 
257
  .card-type {
258
- font-size: 0.7rem;
259
- padding: 2px 6px;
260
  border-radius: 4px;
261
- background: var(--bg-input);
262
  color: var(--text-muted);
263
  text-transform: uppercase;
 
264
  }
265
 
266
  .card-content {
@@ -274,6 +300,7 @@
274
  overflow-y: auto;
275
  background-color: rgba(0, 0, 0, 0.2);
276
  flex: 1;
 
277
  }
278
 
279
  .card-actions {
@@ -288,14 +315,15 @@
288
  background-color: transparent;
289
  border: 1px solid var(--border);
290
  color: var(--text-muted);
291
- padding: 0.4rem 0.8rem;
292
  border-radius: 6px;
293
  font-size: 0.8rem;
294
  cursor: pointer;
295
- transition: all 0.2s;
296
  display: flex;
297
  align-items: center;
298
- gap: 0.4rem;
 
299
  }
300
 
301
  .btn-copy:hover {
@@ -312,6 +340,7 @@
312
  border: 2px dashed var(--border);
313
  border-radius: var(--radius);
314
  grid-column: 1 / -1;
 
315
  }
316
 
317
  .empty-icon {
@@ -329,18 +358,21 @@
329
  color: #fff;
330
  padding: 0.75rem 1.5rem;
331
  border-radius: 8px;
332
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
333
  transform: translateY(150%);
334
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
335
  z-index: 1000;
336
- font-weight: 500;
 
 
 
337
  }
338
 
339
  .toast.show {
340
  transform: translateY(0);
341
  }
342
 
343
- /* Animation */
344
  @keyframes fadeIn {
345
  from {
346
  opacity: 0;
@@ -353,7 +385,7 @@
353
  }
354
  }
355
 
356
- /* Responsive */
357
  @media (max-width: 1024px) {
358
  main {
359
  grid-template-columns: 1fr;
@@ -361,7 +393,7 @@
361
 
362
  aside {
363
  position: static;
364
- margin-bottom: 2rem;
365
  }
366
  }
367
 
@@ -377,11 +409,20 @@
377
  main {
378
  padding: 1rem;
379
  }
 
 
 
 
 
 
 
 
380
  }
381
 
382
- /* Scrollbar styling */
383
  ::-webkit-scrollbar {
384
  width: 8px;
 
385
  }
386
 
387
  ::-webkit-scrollbar-track {
@@ -412,7 +453,7 @@
412
  <path d="M12 12l-2-2"></path>
413
  <path d="M12 16l-2-2"></path>
414
  </svg>
415
- PromptGen AI v4.8
416
  </div>
417
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
418
  anycoder</a>
@@ -465,10 +506,16 @@
465
  </section>
466
  </main>
467
 
468
- <div id="toast" class="toast">Copied to clipboard!</div>
 
 
 
469
 
470
  <script>
471
- // --- TEMPLATES (BLOCKS 1-9) ---
 
 
 
472
  const TEMPLATES = [
473
  {
474
  id: "detail_1",
@@ -526,7 +573,10 @@
526
  }
527
  ];
528
 
529
- // --- STEP 1: VARIABLE EXTRACTION & PARSING ---
 
 
 
530
  function extractData(productNameInput, colorsInput) {
531
  let rawName = productNameInput.trim();
532
 
@@ -630,7 +680,10 @@
630
  };
631
  }
632
 
633
- // --- STEP 2, 3, & 4: LOGIC, DISTRIBUTION & INJECTION ---
 
 
 
634
  function processTemplates(data) {
635
  let singleColorIndex = 0;
636
 
@@ -651,18 +704,13 @@
651
 
652
  // Rule A: Feature Adaptation (Deletion)
653
  if (!data.hasHighWaisted) {
654
- // Remove "high-waisted", "high waist", "alta cintura"
655
- // Using regex to handle word boundaries and spacing roughly
656
  text = text.replace(/\bhigh-waisted\b/gi, '');
657
  text = text.replace(/\bhigh waist\b/gi, 'waist');
658
  text = text.replace(/\balta cintura\b/gi, '');
659
-
660
- // Cleanup double spaces resulting from removal
661
  text = text.replace(/\s+/g, ' ').trim();
662
  }
663
 
664
  if (!data.hasRibs) {
665
- // Remove "vertical front seams", "nervuras", "ribs"
666
  text = text.replace(/vertical front seams/gi, '');
667
  text = text.replace(/nervuras/gi, '');
668
  text = text.replace(/ribs/gi, '');
@@ -683,7 +731,6 @@
683
  if (data.promoOffer) {
684
  text = `Ensure the promotional text "${data.promoOffer}". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`;
685
  } else {
686
- // If no promo, display Product Name
687
  text = `Ensure the product name "${data.productName}" is clearly visible. Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`;
688
  }
689
  }
@@ -696,9 +743,7 @@
696
  text = text.replace(/Bermuda Viena/g, data.productName);
697
 
698
  // 2. Material
699
- // Replace "Linen and Cotton" first
700
  text = text.replace(/Linen and Cotton/gi, data.material);
701
- // Handle individual fallbacks if material is singular
702
  if (data.material === 'Linen') text = text.replace(/\bCotton\b/gi, 'Linen');
703
  if (data.material === 'Cotton') text = text.replace(/\bLinen\b/gi, 'Cotton');
704
 
@@ -708,18 +753,10 @@
708
  text = text.replace(/exactly 5 identical/g, `exactly ${data.totalQuantity} identical`);
709
  text = text.replace(/5 identical pairs/g, `${data.totalQuantity} identical pairs`);
710
 
711
- // 4. Colors (The complex replacement)
712
- // We replace the hardcoded list in the templates with the actual list
713
- // Hardcoded patterns found in templates: "Green, Khaki, White, Black, and Beige" or "Green (Verde), Khaki (Cáki)..."
714
-
715
- // Simple replacement for the list format "Green, Khaki, White, Black, and Beige"
716
  text = text.replace(/Green, Khaki, White, Black, and Beige/g, data.colorListString);
717
-
718
- // Replacement for descriptive format "Green (Verde), Khaki (Cáki), White (Branco), Black (Preto), and Beige"
719
- // This requires mapping back, but for simplicity we replace the whole segment with the generated list
720
  text = text.replace(/Green \(Verde\), Khaki \(Cáki\), White \(Branco\), Black \(Preto\), and Beige/gi, data.colorListString);
721
 
722
- // Generic single color replacement (Beige, beige color)
723
  if (template.type === "SINGLE") {
724
  text = text.replace(/\bbeige color\b/gi, `${assignedColor} color`);
725
  text = text.replace(/\bnatural beige\b/gi, `natural ${assignedColor}`);
@@ -728,121 +765,4 @@
728
 
729
  return {
730
  id: template.id,
731
- title: template.title,
732
- type: template.type,
733
- content: text
734
- };
735
- });
736
- }
737
-
738
- // --- UI RENDERING & INTERACTION ---
739
-
740
- function renderResults(results) {
741
- const grid = document.getElementById('resultsGrid');
742
- const statusBadge = document.getElementById('statusBadge');
743
-
744
- grid.innerHTML = ''; // Clear previous results
745
-
746
- if (!results || results.length === 0) {
747
- grid.innerHTML = `
748
- <div class="empty-state">
749
- <div class="empty-icon">⚡</div>
750
- <h3>No Results</h3>
751
- <p>Could not generate prompts. Check your input.</p>
752
- </div>
753
- `;
754
- statusBadge.textContent = "Error";
755
- statusBadge.style.color = "var(--danger)";
756
- return;
757
- }
758
-
759
- statusBadge.textContent = `Generated ${results.length} prompts`;
760
- statusBadge.style.color = "var(--accent)";
761
-
762
- results.forEach((res, index) => {
763
- const card = document.createElement('div');
764
- card.className = 'card';
765
- card.style.animationDelay = `${index * 50}ms`; // Staggered animation
766
-
767
- card.innerHTML = `
768
- <div class="card-header">
769
- <div class="card-title">
770
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
771
- ${res.title}
772
- </div>
773
- <span class="card-type">${res.type}</span>
774
- </div>
775
- <div class="card-content">${escapeHtml(res.content)}</div>
776
- <div class="card-actions">
777
- <button class="btn-copy" onclick="copyText('${res.id}')">
778
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
779
- Copy
780
- </button>
781
- </div>
782
- `;
783
- grid.appendChild(card);
784
- });
785
- }
786
-
787
- // Helper to prevent XSS when displaying text
788
- function escapeHtml(text) {
789
- const map = {
790
- '&': '&amp;',
791
- '<': '&lt;',
792
- '>': '&gt;',
793
- '"': '&quot;',
794
- "'": '&#039;'
795
- };
796
- return text.replace(/[&<>"']/g, function(m) { return map[m]; });
797
- }
798
-
799
- // Global store for copy function
800
- let generatedResults = [];
801
-
802
- function copyText(id) {
803
- const item = generatedResults.find(r => r.id === id);
804
- if (item) {
805
- navigator.clipboard.writeText(item.content).then(() => {
806
- showToast();
807
- }).catch(err => {
808
- console.error('Failed to copy: ', err);
809
- });
810
- }
811
- }
812
-
813
- function showToast() {
814
- const toast = document.getElementById('toast');
815
- toast.classList.add('show');
816
- setTimeout(() => {
817
- toast.classList.remove('show');
818
- }, 3000);
819
- }
820
-
821
- // --- EVENT LISTENERS ---
822
- document.addEventListener('DOMContentLoaded', () => {
823
- const generateBtn = document.getElementById('generateBtn');
824
- const productNameInput = document.getElementById('productName');
825
- const colorListInput = document.getElementById('colorList');
826
-
827
- generateBtn.addEventListener('click', () => {
828
- const pName = productNameInput.value;
829
- const cList = colorListInput.value;
830
-
831
- if (!pName.trim()) {
832
- alert("Please enter a product name.");
833
- return;
834
- }
835
-
836
- // Execute Logic
837
- const data = extractData(pName, cList);
838
- generatedResults = processTemplates(data); // Store for copy function
839
-
840
- // Render
841
- renderResults(generatedResults);
842
- });
843
- });
844
-
845
- </script>
846
- </body>
847
-
848
- </html>
 
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>AI Prompt Gen | E-Commerce Asset System v4.9</title>
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
 
 
11
  <style>
12
  :root {
13
+ /* Color Palette - Modern Dark Theme */
14
  --bg-body: #0f172a;
15
  --bg-card: #1e293b;
16
+ --bg-card-hover: #263345;
17
  --bg-input: #334155;
18
  --text-main: #f8fafc;
19
  --text-muted: #94a3b8;
 
22
  --accent: #10b981;
23
  --danger: #ef4444;
24
  --border: #334155;
25
+ --border-hover: #475569;
26
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.15);
27
  --radius: 12px;
28
+ --transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
29
  }
30
 
31
+ /* Reset & Base */
32
  * {
33
  box-sizing: border-box;
34
  margin: 0;
 
43
  min-height: 100vh;
44
  display: flex;
45
  flex-direction: column;
46
+ background-image: radial-gradient(circle at top right, #1e293b 0%, transparent 40%);
47
  }
48
 
49
  /* Header */
50
  header {
51
+ background-color: rgba(30, 41, 59, 0.8);
52
+ backdrop-filter: blur(12px);
53
  border-bottom: 1px solid var(--border);
54
  padding: 1rem 2rem;
55
  display: flex;
 
63
  .brand {
64
  font-size: 1.25rem;
65
  font-weight: 700;
66
+ background: linear-gradient(135deg, var(--primary), var(--accent));
67
  -webkit-background-clip: text;
68
  -webkit-text-fill-color: transparent;
69
  letter-spacing: -0.025em;
70
  display: flex;
71
  align-items: center;
72
+ gap: 0.75rem;
73
+ }
74
+
75
+ .brand svg {
76
+ color: var(--primary);
77
  }
78
 
79
  .anycoder-link {
80
  font-size: 0.875rem;
81
  color: var(--text-muted);
82
  text-decoration: none;
83
+ transition: var(--transition);
84
  border: 1px solid var(--border);
85
+ padding: 0.35rem 1rem;
86
  border-radius: 99px;
87
+ font-weight: 500;
88
  }
89
 
90
  .anycoder-link:hover {
91
  color: var(--primary);
92
  border-color: var(--primary);
93
+ background-color: rgba(59, 130, 246, 0.1);
94
  }
95
 
96
  /* Main Layout */
 
101
  width: 100%;
102
  padding: 2rem;
103
  display: grid;
104
+ grid-template-columns: 400px 1fr; /* Slightly wider sidebar for usability */
105
+ gap: 2.5rem;
106
+ align-items: start;
107
  }
108
 
109
  /* Sidebar / Inputs */
110
  aside {
111
  background-color: var(--bg-card);
112
  border-radius: var(--radius);
113
+ padding: 1.75rem;
114
  border: 1px solid var(--border);
 
115
  position: sticky;
116
  top: 6rem;
117
  box-shadow: var(--shadow);
 
145
  background-color: var(--bg-input);
146
  border: 1px solid var(--border);
147
  border-radius: 8px;
148
+ padding: 0.875rem 1rem;
149
  color: var(--text-main);
150
  font-family: inherit;
151
  font-size: 0.95rem;
152
+ transition: var(--transition);
153
  }
154
 
155
  textarea {
156
  resize: vertical;
157
+ min-height: 120px;
158
  }
159
 
160
  input:focus,
161
  textarea:focus {
162
  outline: none;
163
  border-color: var(--primary);
164
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
165
+ background-color: #384659;
166
  }
167
 
168
  .helper-text {
 
170
  color: var(--text-muted);
171
  margin-top: 0.5rem;
172
  font-style: italic;
173
+ opacity: 0.8;
174
  }
175
 
176
  button.btn-primary {
177
  width: 100%;
178
+ padding: 1rem;
179
  background-color: var(--primary);
180
  color: white;
181
  border: none;
 
183
  font-weight: 600;
184
  font-size: 1rem;
185
  cursor: pointer;
186
+ transition: var(--transition);
187
  display: flex;
188
  justify-content: center;
189
  align-items: center;
190
  gap: 0.5rem;
191
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
192
  }
193
 
194
  button.btn-primary:hover {
195
  background-color: var(--primary-hover);
196
+ transform: translateY(-1px);
197
+ box-shadow: 0 6px 16px rgba(59, 130, 246, 0.3);
198
  }
199
 
200
  button.btn-primary:active {
201
+ transform: translateY(1px);
202
  }
203
 
204
  /* Output Section */
 
218
  }
219
 
220
  .status-badge {
221
+ font-size: 0.8rem;
222
+ padding: 0.3rem 0.8rem;
223
  border-radius: 99px;
224
  background-color: var(--bg-input);
225
  color: var(--text-muted);
226
+ font-weight: 500;
227
+ border: 1px solid var(--border);
228
+ }
229
+
230
+ .status-badge.success {
231
+ color: var(--accent);
232
+ border-color: rgba(16, 185, 129, 0.3);
233
+ background-color: rgba(16, 185, 129, 0.1);
234
  }
235
 
236
  .grid {
 
246
  padding: 0;
247
  display: flex;
248
  flex-direction: column;
249
+ transition: var(--transition);
250
  position: relative;
251
  overflow: hidden;
252
+ animation: fadeIn 0.5s ease-out forwards;
253
  }
254
 
255
  .card:hover {
256
+ transform: translateY(-4px);
257
  box-shadow: var(--shadow);
258
+ border-color: var(--border-hover);
259
+ background-color: var(--bg-card-hover);
260
  }
261
 
262
  .card-header {
 
269
  }
270
 
271
  .card-title {
272
+ font-size: 0.8rem;
273
  font-weight: 700;
274
  color: var(--primary);
275
  text-transform: uppercase;
 
280
  }
281
 
282
  .card-type {
283
+ font-size: 0.65rem;
284
+ padding: 2px 8px;
285
  border-radius: 4px;
286
+ background: rgba(255, 255, 255, 0.05);
287
  color: var(--text-muted);
288
  text-transform: uppercase;
289
+ border: 1px solid var(--border);
290
  }
291
 
292
  .card-content {
 
300
  overflow-y: auto;
301
  background-color: rgba(0, 0, 0, 0.2);
302
  flex: 1;
303
+ line-height: 1.5;
304
  }
305
 
306
  .card-actions {
 
315
  background-color: transparent;
316
  border: 1px solid var(--border);
317
  color: var(--text-muted);
318
+ padding: 0.4rem 1rem;
319
  border-radius: 6px;
320
  font-size: 0.8rem;
321
  cursor: pointer;
322
+ transition: var(--transition);
323
  display: flex;
324
  align-items: center;
325
+ gap: 0.5rem;
326
+ font-weight: 500;
327
  }
328
 
329
  .btn-copy:hover {
 
340
  border: 2px dashed var(--border);
341
  border-radius: var(--radius);
342
  grid-column: 1 / -1;
343
+ background-color: rgba(255, 255, 255, 0.01);
344
  }
345
 
346
  .empty-icon {
 
358
  color: #fff;
359
  padding: 0.75rem 1.5rem;
360
  border-radius: 8px;
361
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
362
  transform: translateY(150%);
363
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
364
  z-index: 1000;
365
+ font-weight: 600;
366
+ display: flex;
367
+ align-items: center;
368
+ gap: 0.5rem;
369
  }
370
 
371
  .toast.show {
372
  transform: translateY(0);
373
  }
374
 
375
+ /* Animations */
376
  @keyframes fadeIn {
377
  from {
378
  opacity: 0;
 
385
  }
386
  }
387
 
388
+ /* Responsive Design */
389
  @media (max-width: 1024px) {
390
  main {
391
  grid-template-columns: 1fr;
 
393
 
394
  aside {
395
  position: static;
396
+ width: 100%;
397
  }
398
  }
399
 
 
409
  main {
410
  padding: 1rem;
411
  }
412
+
413
+ .brand span {
414
+ display: none; /* Hide text on very small screens, keep logo */
415
+ }
416
+
417
+ .brand span:first-child {
418
+ display: block; /* Keep the svg visible */
419
+ }
420
  }
421
 
422
+ /* Custom Scrollbar */
423
  ::-webkit-scrollbar {
424
  width: 8px;
425
+ height: 8px;
426
  }
427
 
428
  ::-webkit-scrollbar-track {
 
453
  <path d="M12 12l-2-2"></path>
454
  <path d="M12 16l-2-2"></path>
455
  </svg>
456
+ <span>PromptGen AI v4.9</span>
457
  </div>
458
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
459
  anycoder</a>
 
506
  </section>
507
  </main>
508
 
509
+ <div id="toast" class="toast">
510
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>
511
+ Copied to clipboard!
512
+ </div>
513
 
514
  <script>
515
+ /**
516
+ * TEMPLATES (BLOCKS 1-9)
517
+ * Core definitions for the prompt generation logic.
518
+ */
519
  const TEMPLATES = [
520
  {
521
  id: "detail_1",
 
573
  }
574
  ];
575
 
576
+ /**
577
+ * STEP 1: VARIABLE EXTRACTION & PARSING
578
+ * Analyzes raw input strings to extract structured data.
579
+ */
580
  function extractData(productNameInput, colorsInput) {
581
  let rawName = productNameInput.trim();
582
 
 
680
  };
681
  }
682
 
683
+ /**
684
+ * STEP 2, 3, & 4: LOGIC, DISTRIBUTION & INJECTION
685
+ * Processes templates based on extracted data.
686
+ */
687
  function processTemplates(data) {
688
  let singleColorIndex = 0;
689
 
 
704
 
705
  // Rule A: Feature Adaptation (Deletion)
706
  if (!data.hasHighWaisted) {
 
 
707
  text = text.replace(/\bhigh-waisted\b/gi, '');
708
  text = text.replace(/\bhigh waist\b/gi, 'waist');
709
  text = text.replace(/\balta cintura\b/gi, '');
 
 
710
  text = text.replace(/\s+/g, ' ').trim();
711
  }
712
 
713
  if (!data.hasRibs) {
 
714
  text = text.replace(/vertical front seams/gi, '');
715
  text = text.replace(/nervuras/gi, '');
716
  text = text.replace(/ribs/gi, '');
 
731
  if (data.promoOffer) {
732
  text = `Ensure the promotional text "${data.promoOffer}". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`;
733
  } else {
 
734
  text = `Ensure the product name "${data.productName}" is clearly visible. Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`;
735
  }
736
  }
 
743
  text = text.replace(/Bermuda Viena/g, data.productName);
744
 
745
  // 2. Material
 
746
  text = text.replace(/Linen and Cotton/gi, data.material);
 
747
  if (data.material === 'Linen') text = text.replace(/\bCotton\b/gi, 'Linen');
748
  if (data.material === 'Cotton') text = text.replace(/\bLinen\b/gi, 'Cotton');
749
 
 
753
  text = text.replace(/exactly 5 identical/g, `exactly ${data.totalQuantity} identical`);
754
  text = text.replace(/5 identical pairs/g, `${data.totalQuantity} identical pairs`);
755
 
756
+ // 4. Colors
 
 
 
 
757
  text = text.replace(/Green, Khaki, White, Black, and Beige/g, data.colorListString);
 
 
 
758
  text = text.replace(/Green \(Verde\), Khaki \(Cáki\), White \(Branco\), Black \(Preto\), and Beige/gi, data.colorListString);
759
 
 
760
  if (template.type === "SINGLE") {
761
  text = text.replace(/\bbeige color\b/gi, `${assignedColor} color`);
762
  text = text.replace(/\bnatural beige\b/gi, `natural ${assignedColor}`);
 
765
 
766
  return {
767
  id: template.id,
768
+ title: template.title