diff --git a/public/app.js b/public/app.js
index 8dbe2a0..185cbf5 100644
--- a/public/app.js
+++ b/public/app.js
@@ -6998,7 +6998,51 @@ document.addEventListener('DOMContentLoaded', () => {
cartazPrintableArea.style.backgroundColor = bg;
cartazPrintableArea.style.color = text;
cartazPrintableArea.style.fontFamily = font;
- cartazPrintableArea.style.maxWidth = orientacao === 'paisagem' ? '800px' : '500px';
+
+ if (orientacao === 'paisagem') {
+ cartazPrintableArea.style.maxWidth = '800px';
+ cartazPrintableArea.style.aspectRatio = '1.414 / 1';
+ cartazPrintableArea.style.height = 'auto';
+ cartazPreviewContent.style.flexDirection = 'row';
+ cartazPreviewContent.style.flexWrap = 'wrap';
+ cartazPreviewContent.style.justifyContent = 'center';
+ cartazPreviewContent.style.alignContent = 'flex-start';
+ cartazPreviewContent.style.gap = '12px';
+
+ setTimeout(() => {
+ Array.from(cartazPreviewContent.children).forEach(child => {
+ child.style.flex = '1 1 calc(50% - 12px)';
+ child.style.boxSizing = 'border-box';
+ child.style.margin = '0';
+ child.style.background = 'rgba(255,255,255,0.25)';
+ child.style.padding = '12px';
+ child.style.borderRadius = '8px';
+ child.style.border = '1px solid rgba(0,0,0,0.05)';
+ });
+ }, 0);
+ } else {
+ cartazPrintableArea.style.maxWidth = '500px';
+ cartazPrintableArea.style.aspectRatio = '1 / 1.414';
+ cartazPrintableArea.style.height = 'auto';
+ cartazPreviewContent.style.flexDirection = 'column';
+ cartazPreviewContent.style.flexWrap = 'nowrap';
+ cartazPreviewContent.style.justifyContent = 'flex-start';
+ cartazPreviewContent.style.gap = '12px';
+
+ setTimeout(() => {
+ Array.from(cartazPreviewContent.children).forEach(child => {
+ child.style.flex = '0 0 auto';
+ child.style.width = '100%';
+ child.style.boxSizing = 'border-box';
+ child.style.margin = '0';
+ child.style.background = 'rgba(255,255,255,0.25)';
+ child.style.padding = '12px';
+ child.style.borderRadius = '8px';
+ child.style.border = '1px solid rgba(0,0,0,0.05)';
+ });
+ }, 0);
+ }
+
cartazPreviewTitle.textContent = title;
cartazPreviewTitle.style.borderColor = text;
@@ -7124,7 +7168,7 @@ document.addEventListener('DOMContentLoaded', () => {
const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block'
- ? `

`
+ ? `
`
: '';
const printWindow = window.open('', '_blank');
@@ -7157,9 +7201,12 @@ document.addEventListener('DOMContentLoaded', () => {
border-radius: 16px;
width: 100%;
max-width: ${orientacao === 'paisagem' ? '1200px' : '800px'};
+ aspect-ratio: ${orientacao === 'paisagem' ? '1.414 / 1' : '1 / 1.414'};
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
box-sizing: border-box;
border: ${border === 'none' ? 'none' : `${border} ${text}`};
+ display: flex;
+ flex-direction: column;
}
h1 {
text-align: center;
@@ -7173,17 +7220,21 @@ document.addEventListener('DOMContentLoaded', () => {
font-size: 1.5rem;
line-height: 1.6;
display: flex;
+ flex-direction: ${orientacao === 'paisagem' ? 'row' : 'column'};
flex-wrap: wrap;
gap: 20px;
justify-content: center;
}
/* Suporte para cards na content-area */
.content-area > div, .content-area > p, .content-area > ul {
+ box-sizing: border-box;
background: rgba(255, 255, 255, 0.3);
padding: 20px;
border-radius: 12px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
- width: 100%;
+ width: ${orientacao === 'paisagem' ? 'calc(50% - 20px)' : '100%'};
+ flex: ${orientacao === 'paisagem' ? '1 1 calc(50% - 20px)' : '0 0 auto'};
+ margin: 0;
}
ul {
margin-left: 20px;
diff --git a/public/index.html b/public/index.html
index 4545571..86910ab 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1868,12 +1868,12 @@
Título do Cartaz
-
-
![]()
+
+
-
+
Clique em "Criar Cartaz Pedagógico" para que a assistente monte e estruture o cartaz ideal para você.
diff --git a/server.js b/server.js
index 3f8f304..8d5e815 100644
--- a/server.js
+++ b/server.js
@@ -1400,8 +1400,13 @@ Detalhes do Cartaz:
- Orientação: "${orientacao === 'paisagem' ? 'Paisagem/Horizontal' : 'Retrato/Vertical'}"
Por favor, gere o CONTEÚDO textual e estrutural do cartaz em HTML.
-REGRAS FUNDAMENTAIS E ESTÉTICAS:
-- O cartaz deve caber ESTRITAMENTE em UMA ÚNICA PÁGINA (Tamanho ${tamanho || 'A4'}, orientação ${orientacao === 'paisagem' ? 'Horizontal' : 'Vertical'}). Não crie textos longos ou listas que fariam a folha "vazar" na impressão.
+
+REGRAS DE IDIOMA E LOCALIZAÇÃO:
+- O conteúdo gerado deve ser IMPRETERIVELMENTE em português do Brasil (pt-BR). Não use termos em outros idiomas de forma desnecessária.
+
+REGRAS FUNDAMENTAIS E ESTÉTICAS DE DIAGRAMAÇÃO:
+- O cartaz deve caber ESTRITAMENTE em UMA ÚNICA PÁGINA FÍSICA (Tamanho ${tamanho || 'A4'}, orientação ${orientacao === 'paisagem' ? 'Horizontal/Paisagem' : 'Vertical/Retrato'}). Não extrapole este espaço de forma alguma.
+- Limite a quantidade de conteúdo: gere no máximo 2 ou 3 cards (divs de conteúdo) no total. Cada card deve ter pouquíssimo texto (no máximo 3 ou 4 itens curtos por card).
- Distribua a informação em CARDS (pequenos cartões ou blocos curtos) bem espaçados, parecidos com pôsteres infantis modernos, onde o texto NÃO ocupa uma folha corrida.
- Os textos devem ser extremamente curtos, diretos, visuais e fáceis de ler.
- Use emojis apropriados para crianças.
@@ -1409,7 +1414,7 @@ REGRAS FUNDAMENTAIS E ESTÉTICAS:
- Se for "informativo", destaque avisos gerais e orientações (ex: horários, cardápio, provas) em caixas curtas e legíveis.
- Se for "conscientizacao", use frases curtas de impacto sobre campanhas (ex: prevenção, saúde, coleta seletiva), acompanhadas de dicas em pequenos blocos.
- Se for "cultural", promova a atividade de lazer, esporte ou feira destacando o evento de forma animada e pontual.
-- Considere a orientação ${orientacao === 'paisagem' ? 'Paisagem (horizontal)' : 'Retrato (vertical)'} ao organizar o fluxo: para paisagem, use \`display: flex; flex-wrap: wrap; gap: 20px;\` para os cards ficarem lado a lado; para retrato, de cima para baixo.
+- Considere a orientação ${orientacao === 'paisagem' ? 'Paisagem (horizontal)' : 'Retrato (vertical)'} ao organizar o fluxo: para paisagem, os cards devem ficar lado a lado (2 colunas horizontais); para retrato, eles se empilham verticalmente.
- Retorne apenas o formato HTML (use
,
,
, - , , ). Não adicione ou , retorne apenas o conteúdo interno. Não inclua o título
pois ele já é colocado no topo pela interface.`;
let conteudoHtml = '';
@@ -1464,7 +1469,29 @@ REGRAS FUNDAMENTAIS E ESTÉTICAS:
let generatedImageUrl = null;
if (promptImagem && promptImagem.trim().length > 3) {
try {
- console.log('[Cartazes] Gerando ilustração para o cartaz...');
+ console.log('[Cartazes] Refinando prompt de imagem para inglês (sem texto)...');
+ let refinedPrompt = promptImagem;
+ try {
+ const refineRes = await callMinimax({
+ messages: [{
+ role: 'user',
+ content: `Translate the following Portuguese description into a clean English description suitable for an image generation prompt.
+Make sure the prompt specifies a beautiful, colorful, kid-friendly vector/illustration style.
+CRITICAL REQUIREMENT: Explicitly specify in the prompt that there should be absolutely no text, no words, no signs, no letters, no labels, no speech bubbles, and no writing of any kind.
+Portuguese description: "${promptImagem}"
+Return ONLY the English prompt, no extra chat.`
+ }],
+ temperature: 0.3,
+ max_tokens: 250
+ });
+ if (refineRes && refineRes.text) {
+ refinedPrompt = refineRes.text;
+ }
+ } catch (refineErr) {
+ console.error('[Cartazes] Erro ao refinar prompt:', refineErr);
+ }
+
+ console.log('[Cartazes] Gerando ilustração com prompt final:', refinedPrompt);
const minmBase = (process.env.MINIMAX_API_BASE || 'https://api.minimax.io/v1').replace(/\/v1\/?$/, '');
const genResp = await fetch(`${minmBase}/v1/image_generation`, {
method: 'POST',
@@ -1474,7 +1501,7 @@ REGRAS FUNDAMENTAIS E ESTÉTICAS:
},
body: JSON.stringify({
model: 'image-01',
- prompt: `${promptImagem}. Estilo ilustração de livro infantil de alta qualidade, 3D Pixar, cores suaves, traço limpo, sem texto.`,
+ prompt: `${refinedPrompt}. Complete figures shown from top to bottom without cutoffs, kid-friendly illustration style, 3D Pixar, soft pastel colors, no text, no words, no letters, no writing, no labels.`,
n: 1
})
});