eubottura commited on
Commit
bdecae0
·
verified ·
1 Parent(s): 317e179

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +37 -98
index.html CHANGED
@@ -201,14 +201,13 @@
201
  box-shadow: var(--shadow-md);
202
  }
203
 
204
- /* Distribution Preview (New Feature) */
205
  .dist-preview {
206
  background: #f8fafc;
207
  border-radius: 8px;
208
  padding: 1rem;
209
  border: 1px solid var(--border-color);
210
  display: none;
211
- /* Hidden by default */
212
  animation: slideDown 0.3s ease;
213
  }
214
 
@@ -366,7 +365,6 @@
366
  gap: 0.3rem;
367
  }
368
 
369
- /* Specific style for single color badge to make it pop */
370
  .assigned-color.single-color-highlight {
371
  background-color: #ecfdf5;
372
  color: var(--success-color);
@@ -374,7 +372,7 @@
374
  border-radius: 4px;
375
  border: 1px solid #a7f3d0;
376
  }
377
-
378
  .assigned-color.single-color-highlight::before {
379
  content: '';
380
  display: block;
@@ -459,32 +457,18 @@
459
 
460
  /* Animations */
461
  @keyframes slideDown {
462
- from {
463
- opacity: 0;
464
- transform: translateY(-10px);
465
- }
466
-
467
- to {
468
- opacity: 1;
469
- transform: translateY(0);
470
- }
471
  }
472
 
473
  @keyframes fadeIn {
474
- from {
475
- opacity: 0;
476
- }
477
-
478
- to {
479
- opacity: 1;
480
- }
481
  }
482
 
483
  /* Responsive */
484
  @media (max-width: 1024px) {
485
- main {
486
- grid-template-columns: 1fr;
487
- }
488
  }
489
  </style>
490
  </head>
@@ -512,16 +496,14 @@
512
  <form id="generatorForm">
513
  <div class="form-group">
514
  <label for="productName">Product Name</label>
515
- <input type="text" id="productName" placeholder="e.g. Bermuda Linho Feminina" required autocomplete="off">
516
- <div class="helper-text"><i class="fa-solid fa-tag"></i> Include material, gender, and type.</div>
517
  </div>
518
 
519
  <div class="form-group">
520
  <label for="colors">Color Variants (Comma or Slash separated)</label>
521
- <!-- Updated placeholder to show slash support -->
522
  <input type="text" id="colors" placeholder="e.g. Black, Grey / Dark Blue, Army Green" required autocomplete="off">
523
- <div class="helper-text"><i class="fa-solid fa-palette"></i> List all available colors. Use commas or slashes (e.g., Red/Blue).
524
- </div>
525
  </div>
526
 
527
  <button type="submit" class="btn-generate">
@@ -570,12 +552,13 @@
570
  * SHOOT COORDINATOR LOGIC
571
  * Role: Asset Coordinator
572
  * Goal: Distribute colors strictly across two categories.
573
- * FIX: Improved parsing to handle comma OR slash separation.
 
574
  */
575
 
576
  const TEMPLATES = {
577
  // --- CATEGORY A: MULTI-COLOR SHOTS ---
578
- // Constraint: Must depict ALL colors.
579
  AVALIACAO_ESPELHO: {
580
  title: "Review Mirror",
581
  type: "multi",
@@ -598,11 +581,11 @@
598
  },
599
 
600
  // --- CATEGORY B: SINGLE-COLOR SHOTS ---
601
- // Constraint: Pick ONE color per shot. Cycle if needed.
602
  DETALHE_1: {
603
  title: "Detail Shot 1 (Hand)",
604
  type: "single",
605
- text: `DETALHE DO PRODUTO STRICT VISUAL MATCH TAKEN WITH IPHONE. 1:1 Square format. The subject is the EXACT "{{PRODUCT_NAME}}" in color {{ACTIVE_COLOR}}. A hand is gently pinching the fabric to display the texture and authentic stitching details. Extreme close-up focus on the material weave and construction. Natural sunlight, casual atmosphere, amateur raw photo style. DO NOT ALTER THE SILHOUETTE. --ar 1:1 --style raw --v 6.0`
606
  },
607
  DETALHE_2: {
608
  title: "Detail Shot 2 (Macro)",
@@ -623,7 +606,7 @@
623
  // Utility
624
  TEXTO_FOTO_PRINCIPAL: {
625
  title: "Main Photo Text Overlay",
626
- type: "multi", // Usually applies to the main photo which has all colors
627
  text: `TEXTO FOTO PRINCIPAL Ensure the promotional text "Pague 3, Leve 5". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus. Simple composition, use of symmetry, shallow depth of field. Add bold, sharp graphic text overlays seamlessly integrated.`
628
  }
629
  };
@@ -665,8 +648,7 @@
665
  variables.TARGET_AUDIENCE = "Male";
666
  }
667
 
668
- // Color Analysis - FIXED LOGIC
669
- // Now splits by comma OR forward slash to handle inputs like "Red/Blue"
670
  const colorsArray = colorsStr.split(/[,\/]/).map(c => c.trim()).filter(c => c.length > 0);
671
  variables.COLORS_ARRAY = colorsArray;
672
  variables.COLOR_LIST = colorsArray.join(', ');
@@ -685,17 +667,23 @@
685
 
686
  // --- STRING SUBSTITUTION ---
687
 
688
- function applySubstitutions(templateStr, variables, activeColor) {
689
  let result = templateStr;
690
 
691
  // Core Data
692
  result = result.replace(/{{PRODUCT_NAME}}/g, variables.PRODUCT_NAME);
693
  result = result.replace(/{{MATERIAL}}/g, variables.MATERIAL);
694
- result = result.replace(/{{QUANTITY}}/g, variables.TOTAL_QUANTITY);
 
 
 
 
 
 
 
695
 
696
  // Color Logic
697
  result = result.replace(/{{ALL_COLORS}}/g, variables.COLOR_LIST);
698
- // IMPORTANT: This replaces the placeholder with ONLY the specific single color assigned
699
  result = result.replace(/{{ACTIVE_COLOR}}/g, activeColor);
700
 
701
  // Legacy Cleanup
@@ -745,10 +733,9 @@
745
  // Assign Single Colors (Cycle Logic)
746
  let colorPointer = 0;
747
  const singleColorKeys = ['DETALHE_1', 'DETALHE_2', 'PESSOA_USANDO_1', 'PESSOA_USANDO_2'];
748
- const singleColorAssignments = {}; // Map key -> color string
749
 
750
  singleColorKeys.forEach(key => {
751
- // Use modulo to cycle through colors if there are fewer colors than shots
752
  const assignedColor = vars.COLORS_ARRAY[colorPointer % vars.COLORS_ARRAY.length];
753
  singleColorAssignments[key] = assignedColor;
754
  distributionPlan.single.push({ key, color: assignedColor });
@@ -768,12 +755,14 @@
768
  <span class="dist-label">Multi-Variant Shots</span>
769
  <div class="color-chips">
770
  <span class="chip multi">${vars.COLORS_ARRAY.length} Colors</span>
 
771
  </div>
772
  </div>
773
  <div class="dist-row">
774
  <span class="dist-label">Single-Variant Shots</span>
775
  <div class="color-chips">
776
- ${distributionPlan.single.map(s => `<span class="chip">${s.color}</span>`).join('')}
 
777
  </div>
778
  </div>
779
  `;
@@ -791,11 +780,14 @@
791
  const badgeText = type === 'multi' ? 'Full Spectrum' : 'Single Variant';
792
 
793
  let colorDisplay;
 
 
794
  if (type === 'multi') {
795
  colorDisplay = `<span class="assigned-color" style="color:var(--accent-color)"><i class="fa-solid fa-palette"></i> ${vars.COLORS_ARRAY.length} Variants</span>`;
 
796
  } else {
797
- // Highlight the single color specifically
798
  colorDisplay = `<span class="assigned-color single-color-highlight">${colorLabel}</span>`;
 
799
  }
800
 
801
  card.innerHTML = `
@@ -804,6 +796,7 @@
804
  <span class="variant-badge ${badgeClass}">${badgeText}</span>
805
  <span class="card-title">${title}</span>
806
  ${colorDisplay}
 
807
  </div>
808
  <button class="btn-copy-single" onclick="copyToClipboard(this)" data-text="${encodeURIComponent(text)}">
809
  <i class="fa-regular fa-copy"></i> Copy
@@ -814,65 +807,11 @@
814
  return card;
815
  };
816
 
817
- // Group 1: Multi-Variant
818
  const group1 = document.createElement('div');
819
  group1.className = 'section-group';
820
  group1.innerHTML = `<div class="section-header"><i class="fa-solid fa-layer-group"></i> Phase 1: Full Spectrum Shots</div>`;
821
 
822
  multiColorKeys.forEach(key => {
823
  if(TEMPLATES[key]) {
824
- // For multi, activeColor placeholder is irrelevant, but we pass the list just in case
825
- const processed = applySubstitutions(TEMPLATES[key].text, vars, vars.COLOR_LIST);
826
- group1.appendChild(createCard(key, TEMPLATES[key].title, processed, 'multi', vars.COLOR_LIST));
827
- allGeneratedText.push(processed);
828
- }
829
- });
830
- resultsContainer.appendChild(group1);
831
-
832
- // Group 2: Single-Variant
833
- const group2 = document.createElement('div');
834
- group2.className = 'section-group';
835
- group2.innerHTML = `<div class="section-header"><i class="fa-solid fa-user-tag"></i> Phase 2: Individual Variant Focus</div>`;
836
-
837
- singleColorKeys.forEach(key => {
838
- if(TEMPLATES[key]) {
839
- // CRITICAL FIX: Pass the specific single color assigned to this key
840
- const activeColor = singleColorAssignments[key];
841
- const processed = applySubstitutions(TEMPLATES[key].text, vars, activeColor);
842
- group2.appendChild(createCard(key, TEMPLATES[key].title, processed, 'single', activeColor));
843
- allGeneratedText.push(processed);
844
- }
845
- });
846
- resultsContainer.appendChild(group2);
847
-
848
- // Setup Copy All
849
- copyAllBtn.style.display = 'flex';
850
- copyAllBtn.onclick = () => {
851
- const allText = allGeneratedText.join('\n\n---\n\n');
852
- navigator.clipboard.writeText(allText).then(() => showToast('All prompts copied!'));
853
- };
854
- });
855
-
856
- // Utils
857
- window.copyToClipboard = function(btn) {
858
- const text = decodeURIComponent(btn.getAttribute('data-text'));
859
- navigator.clipboard.writeText(text).then(() => {
860
- const originalHTML = btn.innerHTML;
861
- btn.innerHTML = `<i class="fa-solid fa-check"></i> Copied`;
862
- setTimeout(() => {
863
- btn.innerHTML = originalHTML;
864
- }, 2000);
865
- });
866
- };
867
-
868
- function showToast(msg) {
869
- const toastMsg = document.getElementById('toastMessage');
870
- toastMsg.textContent = msg;
871
- const toast = document.getElementById('toast');
872
- toast.classList.add('show');
873
- setTimeout(() => toast.classList.remove('show'), 3000);
874
- }
875
- </script>
876
- </body>
877
-
878
- </html>
 
201
  box-shadow: var(--shadow-md);
202
  }
203
 
204
+ /* Distribution Preview */
205
  .dist-preview {
206
  background: #f8fafc;
207
  border-radius: 8px;
208
  padding: 1rem;
209
  border: 1px solid var(--border-color);
210
  display: none;
 
211
  animation: slideDown 0.3s ease;
212
  }
213
 
 
365
  gap: 0.3rem;
366
  }
367
 
 
368
  .assigned-color.single-color-highlight {
369
  background-color: #ecfdf5;
370
  color: var(--success-color);
 
372
  border-radius: 4px;
373
  border: 1px solid #a7f3d0;
374
  }
375
+
376
  .assigned-color.single-color-highlight::before {
377
  content: '';
378
  display: block;
 
457
 
458
  /* Animations */
459
  @keyframes slideDown {
460
+ from { opacity: 0; transform: translateY(-10px); }
461
+ to { opacity: 1; transform: translateY(0); }
 
 
 
 
 
 
 
462
  }
463
 
464
  @keyframes fadeIn {
465
+ from { opacity: 0; }
466
+ to { opacity: 1; }
 
 
 
 
 
467
  }
468
 
469
  /* Responsive */
470
  @media (max-width: 1024px) {
471
+ main { grid-template-columns: 1fr; }
 
 
472
  }
473
  </style>
474
  </head>
 
496
  <form id="generatorForm">
497
  <div class="form-group">
498
  <label for="productName">Product Name</label>
499
+ <input type="text" id="productName" placeholder="e.g. Bermuda Linho Feminina (Leve 3)" required autocomplete="off">
500
+ <div class="helper-text"><i class="fa-solid fa-tag"></i> Include material, gender, and bundle info.</div>
501
  </div>
502
 
503
  <div class="form-group">
504
  <label for="colors">Color Variants (Comma or Slash separated)</label>
 
505
  <input type="text" id="colors" placeholder="e.g. Black, Grey / Dark Blue, Army Green" required autocomplete="off">
506
+ <div class="helper-text"><i class="fa-solid fa-palette"></i> List all available colors. Use commas or slashes.</div>
 
507
  </div>
508
 
509
  <button type="submit" class="btn-generate">
 
552
  * SHOOT COORDINATOR LOGIC
553
  * Role: Asset Coordinator
554
  * Goal: Distribute colors strictly across two categories.
555
+ * FIX 1: Improved parsing to handle comma OR slash separation.
556
+ * FIX 2: Force quantity to 1 for Single Variant shots (Phase 2), regardless of bundle size.
557
  */
558
 
559
  const TEMPLATES = {
560
  // --- CATEGORY A: MULTI-COLOR SHOTS ---
561
+ // Constraint: Must depict ALL colors. Uses TOTAL_QUANTITY.
562
  AVALIACAO_ESPELHO: {
563
  title: "Review Mirror",
564
  type: "multi",
 
581
  },
582
 
583
  // --- CATEGORY B: SINGLE-COLOR SHOTS ---
584
+ // Constraint: Pick ONE color per shot. QUANTITY FORCED TO 1.
585
  DETALHE_1: {
586
  title: "Detail Shot 1 (Hand)",
587
  type: "single",
588
+ text: `DETALHE DO PRODUTO STRICT VISUAL MATCH TAKEN WITH IPHONE. 1:1 Square format. The subject is the EXACT "{{PRODUCT_NAME}}" in color {{ACTIVE_COLOR}} (Qty: 1). A hand is gently pinching the fabric to display the texture and authentic stitching details. Extreme close-up focus on the material weave and construction. Natural sunlight, casual atmosphere, amateur raw photo style. DO NOT ALTER THE SILHOUETTE. --ar 1:1 --style raw --v 6.0`
589
  },
590
  DETALHE_2: {
591
  title: "Detail Shot 2 (Macro)",
 
606
  // Utility
607
  TEXTO_FOTO_PRINCIPAL: {
608
  title: "Main Photo Text Overlay",
609
+ type: "multi",
610
  text: `TEXTO FOTO PRINCIPAL Ensure the promotional text "Pague 3, Leve 5". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus. Simple composition, use of symmetry, shallow depth of field. Add bold, sharp graphic text overlays seamlessly integrated.`
611
  }
612
  };
 
648
  variables.TARGET_AUDIENCE = "Male";
649
  }
650
 
651
+ // Color Analysis - Split by comma OR slash
 
652
  const colorsArray = colorsStr.split(/[,\/]/).map(c => c.trim()).filter(c => c.length > 0);
653
  variables.COLORS_ARRAY = colorsArray;
654
  variables.COLOR_LIST = colorsArray.join(', ');
 
667
 
668
  // --- STRING SUBSTITUTION ---
669
 
670
+ function applySubstitutions(templateStr, variables, activeColor, type) {
671
  let result = templateStr;
672
 
673
  // Core Data
674
  result = result.replace(/{{PRODUCT_NAME}}/g, variables.PRODUCT_NAME);
675
  result = result.replace(/{{MATERIAL}}/g, variables.MATERIAL);
676
+
677
+ // Quantity Logic Override
678
+ // CRITICAL: If type is 'single', we force quantity to 1 to avoid showing piles/bundles in detail shots
679
+ let quantityToUse = variables.TOTAL_QUANTITY;
680
+ if (type === 'single') {
681
+ quantityToUse = 1;
682
+ }
683
+ result = result.replace(/{{QUANTITY}}/g, quantityToUse);
684
 
685
  // Color Logic
686
  result = result.replace(/{{ALL_COLORS}}/g, variables.COLOR_LIST);
 
687
  result = result.replace(/{{ACTIVE_COLOR}}/g, activeColor);
688
 
689
  // Legacy Cleanup
 
733
  // Assign Single Colors (Cycle Logic)
734
  let colorPointer = 0;
735
  const singleColorKeys = ['DETALHE_1', 'DETALHE_2', 'PESSOA_USANDO_1', 'PESSOA_USANDO_2'];
736
+ const singleColorAssignments = {};
737
 
738
  singleColorKeys.forEach(key => {
 
739
  const assignedColor = vars.COLORS_ARRAY[colorPointer % vars.COLORS_ARRAY.length];
740
  singleColorAssignments[key] = assignedColor;
741
  distributionPlan.single.push({ key, color: assignedColor });
 
755
  <span class="dist-label">Multi-Variant Shots</span>
756
  <div class="color-chips">
757
  <span class="chip multi">${vars.COLORS_ARRAY.length} Colors</span>
758
+ <span class="chip" style="border:none; background:transparent;">(${vars.TOTAL_QUANTITY} units/shot)</span>
759
  </div>
760
  </div>
761
  <div class="dist-row">
762
  <span class="dist-label">Single-Variant Shots</span>
763
  <div class="color-chips">
764
+ <span class="chip single-color-highlight" style="border-color:var(--success-color); color:var(--success-color);">1 Unit/Shot</span>
765
+ <span class="chip" style="border:none; background:transparent;">(Forced Qty)</span>
766
  </div>
767
  </div>
768
  `;
 
780
  const badgeText = type === 'multi' ? 'Full Spectrum' : 'Single Variant';
781
 
782
  let colorDisplay;
783
+ let qtyInfo = "";
784
+
785
  if (type === 'multi') {
786
  colorDisplay = `<span class="assigned-color" style="color:var(--accent-color)"><i class="fa-solid fa-palette"></i> ${vars.COLORS_ARRAY.length} Variants</span>`;
787
+ qtyInfo = `<span style="font-size:0.7rem; color:var(--text-secondary); margin-left:8px;">(${vars.TOTAL_QUANTITY} units)</span>`;
788
  } else {
 
789
  colorDisplay = `<span class="assigned-color single-color-highlight">${colorLabel}</span>`;
790
+ qtyInfo = `<span style="font-size:0.7rem; color:var(--success-color); margin-left:8px; font-weight:600;">(Qty: 1)</span>`;
791
  }
792
 
793
  card.innerHTML = `
 
796
  <span class="variant-badge ${badgeClass}">${badgeText}</span>
797
  <span class="card-title">${title}</span>
798
  ${colorDisplay}
799
+ ${qtyInfo}
800
  </div>
801
  <button class="btn-copy-single" onclick="copyToClipboard(this)" data-text="${encodeURIComponent(text)}">
802
  <i class="fa-regular fa-copy"></i> Copy
 
807
  return card;
808
  };
809
 
810
+ // Group 1: Multi-Variant (Pass 'multi' type)
811
  const group1 = document.createElement('div');
812
  group1.className = 'section-group';
813
  group1.innerHTML = `<div class="section-header"><i class="fa-solid fa-layer-group"></i> Phase 1: Full Spectrum Shots</div>`;
814
 
815
  multiColorKeys.forEach(key => {
816
  if(TEMPLATES[key]) {
817
+ // Pass 'multi' as