- El numero debe verse claramente gracias a la formacion y colocacion de los nombres, no por una linea exterior ni por un fondo coloreado. - Usa la silueta del numero solo como guia invisible de colocacion. - Dentro de esa silueta invisible, coloca los nombres completos en lineas ordenadas, preferiblemente horizontales. - No cortar ningun nombre: cada nombre debe leerse entero de principio a fin. - Si un nombre no cabe completo en una zona estrecha de la silueta, moverlo a otra posicion donde quepa completo. - No recortar letras ni dejar nombres partidos en los bordes del numero. - La suma visual de las lineas de nombres debe crear la forma completa del numero desde lejos. - Desde lejos debe reconocerse claramente el numero ${value('number', 'indicado')}. - Desde cerca deben distinguirse los nombres como microtexto uniforme. - Mantener el ancho final del numero en ${resolvedNumberWidth}. - Los nombres deben repetirse tantas veces como sea necesario para completar el numero. - La repeticion debe hacerse siguiendo el orden exacto de la lista dada. - Nunca debe aparecer el mismo nombre repetido de forma consecutiva. - Alternar los nombres de forma equilibrada para que el numero de apariciones de cada nombre distinto sea lo mas ecuanime posible. - Repartir los nombres de la lista de manera proporcional, evitando que un nombre aparezca muchas mas veces que otro salvo que sea inevitable por espacio. - No usar palabras aleatorias, simbolos ni nombres inventados. BANDERAS Y EXTRAS: - Lleva bandera: ${value('flagEnabled')} - Tipo de bandera: ${value('flagType', 'no lleva')} - Posicion de la bandera: ${value('flagPosition')} - Tecnica de la bandera: ${value('flagTechnique')} - Tamano aproximado de la bandera en produccion real: ${flagWidth} - Otros extras: ${value('extras', 'ninguno')} INSTRUCCIONES VISUALES PARA BANDERAS Y EXTRAS: - Si lleva bandera, debe verse discreta pero visible. - La bandera debe ir correctamente ubicada en la manga indicada. - Si no lleva bandera, no anadir ninguna. - No anadir extras no indicados. FORMATO DE IMAGEN ESPERADO: - Una unica imagen comercial limpia. - Fondo blanco o gris muy claro. - Sin ambiente, sin modelos humanos, sin perchas visibles. - Iluminacion de estudio suave. - Si el formato es horizontal ecommerce, colocar frontal y espalda en la misma imagen, con la espalda ligeramente protagonista cuando el diseno principal este detras. - Si el formato es cuadrado para redes, mantener composicion centrada y facil de leer. - Si el formato es vertical presentacion cliente, colocar las vistas en orden claro, priorizando la lectura del diseno. NO HACER: - No poner la sudadera sobre una persona. - No anadir manos, perchas, maniquies ni fondos decorativos. - No cambiar el modelo de prenda. - No inventar etiquetas, marcas, escudos, nombres ni numeros. - No repetir texto fuera de las zonas indicadas. - No tapar disenos con la capucha. - No deformar logos. - No convertir la imagen en ilustracion o dibujo. ANTES DE GENERAR, COMPROBAR MENTALMENTE: - Modelo correcto. - Color correcto. - Tecnica correcta. - Logo frontal en la zona indicada. - Logo trasero centrado si existe. - Logo manga izquierda solo en manga izquierda si existe. - Logo manga derecha solo en manga derecha si existe. - Distancias desde cuello, hombro o costura respetadas. - Numero formado por nombres, no numero solido normal. - Medida real del numero respetada. - Textos exactos. - No hay elementos inventados. IMPORTANTE: - Esto es una previsualizacion comercial de venta, no un diseno tecnico de produccion. - Debe verse muy convincente, muy limpio y muy realista. - La prioridad es que la sudadera resulte atractiva para el cliente y transmita claramente como quedara el diseno final. - Respetar fielmente los datos del pedido.`; document.getElementById('promptOutput').textContent = prompt; document.getElementById('promptReady').classList.remove('hidden'); if (showStatus) setStatus('Prompt generado correctamente.'); return prompt; } async function copyPrompt() { const prompt = generatePrompt(); try { await navigator.clipboard.writeText(prompt); setStatus('Prompt copiado al portapapeles.'); } catch (error) { setStatus('No se pudo copiar automaticamente. Selecciona el prompt y copialo manualmente.'); } } function downloadPrompt() { const prompt = generatePrompt(); const blob = new Blob([prompt], { type: 'text/plain;charset=utf-8' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'prompt_mockup_sudadera.txt'; a.click(); URL.revokeObjectURL(url); setStatus('Archivo .txt descargado.'); } async function sendPrompt() { const prompt = generatePrompt(); const endpoint = value('endpoint', '/api/generate-mockup'); const formData = new FormData(); const logoData = logoConfigs.map(getLogoData); formData.append('prompt', prompt); formData.append('model', value('model')); formData.append('hoodieColor', hoodieColorSelect.value); formData.append('printColor', printColorSelect.value); formData.append('technique', value('technique')); formData.append('logos', JSON.stringify(logoData)); logoConfigs.forEach(config => { const file = getFile(`${config.key}File`); if (file) formData.append(config.formDataName, file); }); setStatus('Enviando prompt, datos y logos al backend...'); try { const response = await fetch(endpoint, { method: 'POST', body: formData }); if (!response.ok) throw new Error(`Error HTTP ${response.status}`); const data = await response.json(); setStatus('Backend respondio correctamente. Revisa la consola para ver la respuesta.'); console.log('Respuesta backend:', data); } catch (error) { setStatus(`No se pudo enviar. Necesitas un backend activo en ${endpoint}. Detalle: ${error.message}`); } } function resetForm() { document.querySelectorAll('input, textarea').forEach(el => { if (el.id === 'endpoint') el.value = '/api/generate-mockup'; else el.value = ''; }); document.querySelectorAll('select').forEach(el => el.selectedIndex = 0); logoConfigs.forEach(config => { const preview = document.getElementById(`${config.key}Preview`); if (preview) preview.classList.add('hidden'); }); populateColors(); populateReferencePreset(); generatePrompt(false); setStatus('Formulario limpiado.'); } function setStatus(message) { document.getElementById('status').textContent = message; } init(); Untitled Page