Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- 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 |
<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 |
-
--
|
|
|
|
| 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:
|
|
|
|
| 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(
|
| 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
}
|
| 69 |
|
| 70 |
.anycoder-link {
|
| 71 |
font-size: 0.875rem;
|
| 72 |
color: var(--text-muted);
|
| 73 |
text-decoration: none;
|
| 74 |
-
transition:
|
| 75 |
border: 1px solid var(--border);
|
| 76 |
-
padding: 0.
|
| 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:
|
| 94 |
-
gap:
|
|
|
|
| 95 |
}
|
| 96 |
|
| 97 |
/* Sidebar / Inputs */
|
| 98 |
aside {
|
| 99 |
background-color: var(--bg-card);
|
| 100 |
border-radius: var(--radius);
|
| 101 |
-
padding: 1.
|
| 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.
|
| 138 |
color: var(--text-main);
|
| 139 |
font-family: inherit;
|
| 140 |
font-size: 0.95rem;
|
| 141 |
-
transition:
|
| 142 |
}
|
| 143 |
|
| 144 |
textarea {
|
| 145 |
resize: vertical;
|
| 146 |
-
min-height:
|
| 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.
|
|
|
|
| 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:
|
| 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:
|
| 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:
|
| 186 |
}
|
| 187 |
|
| 188 |
/* Output Section */
|
|
@@ -202,11 +218,19 @@
|
|
| 202 |
}
|
| 203 |
|
| 204 |
.status-badge {
|
| 205 |
-
font-size: 0.
|
| 206 |
-
padding: 0.
|
| 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:
|
| 226 |
position: relative;
|
| 227 |
overflow: hidden;
|
| 228 |
-
animation: fadeIn 0.5s ease-out;
|
| 229 |
}
|
| 230 |
|
| 231 |
.card:hover {
|
| 232 |
-
transform: translateY(-
|
| 233 |
box-shadow: var(--shadow);
|
| 234 |
-
border-color: var(--
|
|
|
|
| 235 |
}
|
| 236 |
|
| 237 |
.card-header {
|
|
@@ -244,7 +269,7 @@
|
|
| 244 |
}
|
| 245 |
|
| 246 |
.card-title {
|
| 247 |
-
font-size: 0.
|
| 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.
|
| 259 |
-
padding: 2px
|
| 260 |
border-radius: 4px;
|
| 261 |
-
background:
|
| 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
|
| 292 |
border-radius: 6px;
|
| 293 |
font-size: 0.8rem;
|
| 294 |
cursor: pointer;
|
| 295 |
-
transition:
|
| 296 |
display: flex;
|
| 297 |
align-items: center;
|
| 298 |
-
gap: 0.
|
|
|
|
| 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.
|
| 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:
|
|
|
|
|
|
|
|
|
|
| 337 |
}
|
| 338 |
|
| 339 |
.toast.show {
|
| 340 |
transform: translateY(0);
|
| 341 |
}
|
| 342 |
|
| 343 |
-
/*
|
| 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 |
-
|
| 365 |
}
|
| 366 |
}
|
| 367 |
|
|
@@ -377,11 +409,20 @@
|
|
| 377 |
main {
|
| 378 |
padding: 1rem;
|
| 379 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
}
|
| 381 |
|
| 382 |
-
/* Scrollbar
|
| 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.
|
| 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">
|
|
|
|
|
|
|
|
|
|
| 469 |
|
| 470 |
<script>
|
| 471 |
-
/
|
|
|
|
|
|
|
|
|
|
| 472 |
const TEMPLATES = [
|
| 473 |
{
|
| 474 |
id: "detail_1",
|
|
@@ -526,7 +573,10 @@
|
|
| 526 |
}
|
| 527 |
];
|
| 528 |
|
| 529 |
-
/
|
|
|
|
|
|
|
|
|
|
| 530 |
function extractData(productNameInput, colorsInput) {
|
| 531 |
let rawName = productNameInput.trim();
|
| 532 |
|
|
@@ -630,7 +680,10 @@
|
|
| 630 |
};
|
| 631 |
}
|
| 632 |
|
| 633 |
-
/
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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 |
-
'&': '&',
|
| 791 |
-
'<': '<',
|
| 792 |
-
'>': '>',
|
| 793 |
-
'"': '"',
|
| 794 |
-
"'": '''
|
| 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|