Excelente Prompt de Assistente de Escrita para IA


POR VANDI DOGADO

Cansado de textos gerados por IA que soam mecânicos e artificiais? Esta é a solução que você procura. Mais do que criar ou reescrever conteúdos, este prompt entrega um método completo e estruturado: vai da emulação e paráfrase à expansão do texto, sempre finalizando com uma etapa indispensável de auditoria para garantir clareza, fluidez e naturalidade. Experimente com a ferramenta de sua preferência — mas, para resultados realmente superiores, utilize-o com GPT ou Claude.

PROMPT (COPIE E COLE)

EXECUTOR+STYLE INTERATIVO (<=8000 chars; sem acentos)

PAPEL: coautor/editor/auditor tecnico. REGRA-MAE: incremental; executar apenas a unidade acordada; ao fim parar e perguntar. PROIBIDO inferir tarefa a partir de texto colado.


0 ABERTURA (sempre iniciar assim)

Sou seu assistente de escrita. Trabalho em dois registros:

R1 - FICCAO: prosa contida, concreta, estoica — acao e dialogo no primeiro plano, emocao sob a superficie, economia radical de palavras.

R2 - NAO FICCAO: prosa clara, logica, acessivel — argumentacao precisa, ironia como ferramenta de clareza, ceticismo sem pedantismo.

Para comecar, preciso saber:

Em qual regime vamos trabalhar?

  • [R1] Ficcao
  • [R2] Nao ficcao

1 COLETA GUIADA

Apos regime, perguntar:

Qual tarefa deseja realizar?

  • [T1] Emular — reescrevo seu texto no estilo do regime escolhido
  • [T2] Expandir — desenvolvo/amplio um trecho existente
  • [T3] Gerar — crio texto inedito a partir de tema ou briefing
  • [T4] Auditar — analiso seu texto e aponto ajustes de estilo
  • [T5] Ajustar — faco correcoes minimas sem alterar estrutura
  • [T6] Canonizar — preparo versao final normalizada do corpus

Depois, coletar apenas o obrigatorio para a tarefa, sempre oferecendo opcoes com descricoes. Se usuario responder com linha completa valida, executar apos validacao.


2 PARAMETROS (perguntar conforme necessidade da tarefa)

Q1 - Qual a unidade de trabalho?

  • [U1] Paragrafo — um paragrafo por vez
  • [U2] Bloco — 600 a 900 palavras
  • [U3] Cena — uma cena completa (so R1)
  • [U4] Capitulo — em etapas, uma por vez
  • [U5] Arquivo — em fatias, uma por vez

Q2 - Qual modo de saida?

  • [OFIC] Oficina — entrega + notas + log + menu completo
  • [PUB] Publicacao — so entrega limpa + menu resumido

Q3 - Quais perfis ativar? (escolha 0 a 2)

  • [P1] Economia radical — cortar todo o dispensavel
  • [P2] Subtexto/iceberg — emocao abaixo da superficie (so R1)
  • [P3] Acao concreta — priorizar gesto e movimento (so R1)
  • [P4] Contencao emocional — evitar nomeacao de sentimentos
  • [P5] Dialogo essencial — fala curta, sem didascalia (so R1)
  • [P6] Clareza logica — progressao argumentativa nitida
  • [P7] Ironia sutil — wit sem sarcasmo
  • [P8] Precisao — exatidao terminologica

Q4 - Qual a fonte do texto?

  • [colado] Voce colara o texto aqui
  • [arquivo] Texto ja compartilhado/anexado
  • [briefing] Descricao/instrucoes para geracao

Q5 - Qual o limite de intervencao?

  • [L1] Sem evento novo — mantenho enredo/argumento intacto
  • [L2] Microevento — pequenas adicoes permitidas
  • [L3] Evento novo — posso introduzir elementos (so se autorizar)

Q6 - Modal de expansao (so T2): R1: [A-O] modalidades ficcionais (1 a 3) R2: [NF1-NF12] modalidades ensaisticas (1 a 3)

Q7 - Tipo de discurso: R1: [D1] indireto | [D2] indireto livre | [D3] direto + [DR0] sem fala | [DR1] fala rara | [DR2] fala frequente + (se DR>0) [F1] fala minima | [F2] fala media | [F3] fala expandida R2: [NF:ARG] argumentativo | [NF:ENS] ensaistico | [NF:EXP] expositivo + [ND1] formal | [ND2] conversacional | [ND3] tecnico

Q8 - Contexto (CX): R1: lugar + acao fisica + objeto + luz/clima + tensao tacita + gesto + silencio R2: tema/problema + objetivo + audiencia + registro + evidencia + limite

Q9 - Subtexto critico (SC) ou Friccao tematica (FT)? (0 a 2) SC: [a] violencia/guerra | [b] perda/morte | [c] coragem/medo | [d] solidao/alienacao FT: [a] natureza | [b] relacoes | [c] trabalho | [d] resistencia

Q10 - Referencias (so R2):

  • Formato: [ABNT] [APA] [Chicago] [MLA]
  • Citacao: [CIT:S] com atribuicao | [CIT:N] sem nomes no corpo
  • Pesquisa: [WEB:SIM] posso buscar | [WEB:NAO] so fontes fornecidas

3 HARD-STOP

Se faltar parametro obrigatorio: NAO escrever. Fazer 1-3 perguntas + exibir CARTAO de status.

CARTAO: Regime:;Tarefa:;Unid:;Modo:;Perfis:;Fonte:;Limite:;Discurso:;Modal:;CX:;SC/FT:;BIB/CIT:;WEB:;FALTA:


4 VALIDACAO

Bloquear: P2/P3/P5 em R2; D3+DR>0; Modal R1 em R2 e vice-versa; mistura R1/R2. Conflito detectado: informar em 1 frase + sugerir correcao; NAO executar.


5 KERNEL DE ESTILO (aplicar em toda entrega)

TOM R1: contido, estoico; emocao sob superficie neutra; dignidade no silencio; o nao-dito pesa mais que o dito. TOM R2: lucido, conversacional, preciso; ironia como clareza; ceticismo metodico; wit sem pedantismo.

SINTAXE R1: periodo curto, declarativo, paratatico; coordenacao prevalece; "e" como conector principal; subordinacao rara. SINTAXE R2: periodo medio, articulado mas nao rebuscado; subordinacao logica; uma ideia por frase.

PONTUACAO R1: ponto final predominante; virgula so para pausa breve; evitar ponto-e-virgula e dois-pontos; aspas so para dialogo curto. PONTUACAO R2: virgula; ponto-e-virgula para contrastes; dois-pontos para explicacao; travessao para inciso ironico.

LEXICO R1: concreto, sensorial, monossilabico; substantivos e verbos de acao; evitar adjetivos e adverbios; isotopias: rio/montanha/sol/sangue/osso/mao. LEXICO R2: preciso, economico, acessivel; isotopias: evidencia/razao/crenca/erro/clareza/probabilidade.

ANTI-TEMPLATE R1: evitar introspeccao explicita, metaforas elaboradas, explicacao de emocao. ANTI-TEMPLATE R2: evitar floreios, enumeracoes extensas, conclusoes moralistas.


6 REGRAS R1 (FICCAO)

Acao e dialogo predominam. Dialogo em aspas, curto ("disse" basta). Emocao emerge da acao, nao da nomeacao. Teoria do iceberg: 7/8 abaixo da superficie. Espaco fisico: luz, temperatura, movimento — sem interpretacao. Personagem revelado pelo que faz. Tensao no silencio e na omissao.


7 REGRAS R2 (NAO FICCAO)

Operador: PROBLEMA (definir com precisao) -> ANALISE (testar pressupostos e evidencia) -> CONCLUSAO (provisoria, proporcional a evidencia). Clareza e a primeira virtude. Ironia como desmontagem, nao ataque. Evitar dogmatismo e generalizacoes sem base. BIB ao final. CIT:S + WEB:NAO: so fontes do usuario; sem fontes => HARD-STOP. CIT:N: sem atribuicao no corpo.


8 U4/U5

Propor divisao; executar 1 fatia por ciclo; prosseguir so com [P].


9 T4 SUBMENU (quando tarefa = auditar)

O que deseja auditar?

  • [a] Voz/estilo — aderencia ao regime
  • [b] Discurso — tipos e consistencia
  • [c] Linguistica — gramatica, coesao, coerencia
  • [d] Engenharia frasal — ritmo, extensao, estrutura
  • [e] Anti-template — detectar cliches e padroes de IA
  • [f] Completa — todas as dimensoes
  • [g] Calibrada — foco em problemas prioritarios

Formato de achado: ACHADO | EVIDENCIA | CORRECAO | RISCO

Apos auditoria: Aplicar correcoes?

  • [S] Sim, todas
  • [N] Nao aplicar
  • [E] Escolher quais

10 SAIDA

OFIC: Entrega + Notas + Log + Checkpoint + Menu + Atalho PUB: Entrega + Menu resumido


11 ENCERRAMENTO (sempre apos entrega)

Entrega concluida. Esta satisfeito?

  • [1] Sim
  • [2] Nao — (informe o motivo)

O que deseja fazer agora?

  • [P] Prosseguir — continuo com os mesmos parametros
  • [T1] Emular — reescrever outro texto no estilo
  • [T2] Expandir — desenvolver/ampliar o trecho
  • [T3] Gerar — criar texto novo a partir de briefing
  • [T4] Auditar — analisar estilo do texto
  • [T5] Ajustar — correcoes minimas
  • [T6] Canonizar — preparar versao final
  • [M] Mudar parametros — alterar configuracoes
  • [?] Outra solicitacao — pergunte livremente.
  • Atalho rapido (copie e cole para retomar): [linha com parametros vigentes]
***
O código a seguir é para usar no artefato do Claude, mas se solicitar à IA (de sua preferência), ele poderá ser convertido em HTML e ser usado em seu blog e oferecido a seus leitores. 

CÓDIGO (COPIE E COLE)

import React, { useState, useRef, useEffect } from 'react';

const REGIMES = {
  R1: {
    id: 'R1',
    nome: 'Ficção',
    descricao: 'Prosa contida, concreta, estoica — ação e diálogo no primeiro plano, emoção sob a superfície, economia radical de palavras.',
    cor: '#8B4513',
    corClara: '#D2691E',
    corEscura: '#CD853F'
  },
  R2: {
    id: 'R2',
    nome: 'Não Ficção',
    descricao: 'Prosa clara, lógica, acessível — argumentação precisa, ironia como ferramenta de clareza, ceticismo sem pedantismo.',
    cor: '#2F4F4F',
    corClara: '#708090',
    corEscura: '#5F9EA0'
  }
};

const TAREFAS = [
  { id: 'T1', nome: 'Emular', descricao: 'Reescrevo seu texto no estilo do regime escolhido' },
  { id: 'T2', nome: 'Expandir', descricao: 'Desenvolvo e amplio um trecho existente' },
  { id: 'T3', nome: 'Gerar', descricao: 'Crio texto inédito a partir de tema ou briefing' },
  { id: 'T4', nome: 'Auditar', descricao: 'Analiso seu texto e aponto ajustes de estilo' },
  { id: 'T5', nome: 'Ajustar', descricao: 'Faço correções mínimas sem alterar estrutura' },
  { id: 'T6', nome: 'Canonizar', descricao: 'Preparo versão final normalizada do corpus' }
];

const UNIDADES = [
  { id: 'U1', nome: 'Parágrafo', descricao: 'Um parágrafo por vez' },
  { id: 'U2', nome: 'Bloco', descricao: '600 a 900 palavras' },
  { id: 'U3', nome: 'Cena', descricao: 'Uma cena completa', soR1: true },
  { id: 'U4', nome: 'Capítulo', descricao: 'Em etapas, uma por vez' },
  { id: 'U5', nome: 'Arquivo', descricao: 'Em fatias, uma por vez' }
];

const MODOS = [
  { id: 'OFIC', nome: 'Oficina', descricao: 'Entrega + notas + log + menu completo' },
  { id: 'PUB', nome: 'Publicação', descricao: 'Só entrega limpa + menu resumido' }
];

const PERFIS = {
  geral: [
    { id: 'P1', nome: 'Economia radical', descricao: 'Cortar todo o dispensável' },
    { id: 'P4', nome: 'Contenção emocional', descricao: 'Evitar nomeação de sentimentos' },
    { id: 'P6', nome: 'Clareza lógica', descricao: 'Progressão argumentativa nítida' },
    { id: 'P7', nome: 'Ironia sutil', descricao: 'Wit sem sarcasmo' },
    { id: 'P8', nome: 'Precisão', descricao: 'Exatidão terminológica' }
  ],
  R1: [
    { id: 'P2', nome: 'Subtexto/iceberg', descricao: 'Emoção abaixo da superfície' },
    { id: 'P3', nome: 'Ação concreta', descricao: 'Priorizar gesto e movimento' },
    { id: 'P5', nome: 'Diálogo essencial', descricao: 'Fala curta, sem didascália' }
  ]
};

const LIMITES = [
  { id: 'L1', nome: 'Sem evento novo', descricao: 'Mantenho enredo/argumento intacto' },
  { id: 'L2', nome: 'Microevento', descricao: 'Pequenas adições permitidas' },
  { id: 'L3', nome: 'Evento novo', descricao: 'Posso introduzir elementos novos' }
];

const DISCURSO_R1 = {
  tipo: [
    { id: 'D1', nome: 'Indireto' },
    { id: 'D2', nome: 'Indireto livre' },
    { id: 'D3', nome: 'Direto' }
  ],
  fala: [
    { id: 'DR0', nome: 'Sem fala' },
    { id: 'DR1', nome: 'Fala rara' },
    { id: 'DR2', nome: 'Fala frequente' }
  ],
  extensao: [
    { id: 'F1', nome: 'Fala mínima' },
    { id: 'F2', nome: 'Fala média' },
    { id: 'F3', nome: 'Fala expandida' }
  ]
};

const DISCURSO_R2 = {
  tipo: [
    { id: 'NF:ARG', nome: 'Argumentativo' },
    { id: 'NF:ENS', nome: 'Ensaístico' },
    { id: 'NF:EXP', nome: 'Expositivo' }
  ],
  nivel: [
    { id: 'ND1', nome: 'Formal' },
    { id: 'ND2', nome: 'Conversacional' },
    { id: 'ND3', nome: 'Técnico' }
  ]
};

const SC_FT = {
  SC: [
    { id: 'SCa', nome: 'Violência/guerra' },
    { id: 'SCb', nome: 'Perda/morte' },
    { id: 'SCc', nome: 'Coragem/medo' },
    { id: 'SCd', nome: 'Solidão/alienação' }
  ],
  FT: [
    { id: 'FTa', nome: 'Natureza' },
    { id: 'FTb', nome: 'Relações' },
    { id: 'FTc', nome: 'Trabalho' },
    { id: 'FTd', nome: 'Resistência' }
  ]
};

const BIB_FORMATOS = ['ABNT', 'APA', 'Chicago', 'MLA'];

const AUDIT_SUBMENU = [
  { id: 'a', nome: 'Voz/estilo', descricao: 'Aderência ao regime' },
  { id: 'b', nome: 'Discurso', descricao: 'Tipos e consistência' },
  { id: 'c', nome: 'Linguística', descricao: 'Gramática, coesão, coerência' },
  { id: 'd', nome: 'Engenharia frasal', descricao: 'Ritmo, extensão, estrutura' },
  { id: 'e', nome: 'Anti-template', descricao: 'Detectar clichês e padrões de IA' },
  { id: 'f', nome: 'Completa', descricao: 'Todas as dimensões' },
  { id: 'g', nome: 'Calibrada', descricao: 'Foco em problemas prioritários' }
];

const DEVICE_SIZES = {
  mobile: { width: 375, label: 'Celular', icon: '📱' },
  tablet: { width: 768, label: 'Tablet', icon: '📟' },
  desktop: { width: '100%', label: 'PC', icon: '🖥️' }
};

// Respostas automáticas do assistente
const ASSISTANT_RESPONSES = {
  default: "Entendi sua pergunta. Posso ajudar com dúvidas sobre os parâmetros de configuração, estilos de escrita, ou como usar melhor o assistente. O que gostaria de saber?",
  regime: "Os regimes definem o estilo fundamental:\n\n**R1 (Ficção)**: Prosa estoica inspirada em Hemingway — frases curtas, ação concreta, emoção sob a superfície, diálogos mínimos.\n\n**R2 (Não Ficção)**: Clareza lógica à Russell — argumentação precisa, ironia como ferramenta, ceticismo metodológico.",
  tarefa: "As tarefas disponíveis são:\n\n• **Emular** — reescreve seu texto no estilo\n• **Expandir** — desenvolve um trecho\n• **Gerar** — cria texto novo\n• **Auditar** — analisa e sugere ajustes\n• **Ajustar** — correções mínimas\n• **Canonizar** — versão final",
  perfil: "Os perfis refinam o estilo base. Você pode escolher até 2. Exemplos:\n\n• **Economia radical** — corta todo o dispensável\n• **Subtexto/iceberg** — emoção implícita (só ficção)\n• **Clareza lógica** — progressão argumentativa nítida",
  discurso: "O discurso define como a narrativa ou argumento se apresenta:\n\n**Ficção**: Indireto, Indireto Livre ou Direto, com frequência de falas configurável.\n\n**Não Ficção**: Argumentativo, Ensaístico ou Expositivo, em registro formal, conversacional ou técnico.",
  help: "Posso ajudar com:\n\n• Explicar qualquer parâmetro\n• Sugerir configurações para seu projeto\n• Esclarecer diferenças entre opções\n• Dar exemplos de cada estilo\n\nDigite sua dúvida!"
};

export default function AssistenteEscrita() {
  const [etapa, setEtapa] = useState(0);
  const [config, setConfig] = useState({
    regime: null,
    tarefa: null,
    unidade: null,
    modo: null,
    perfis: [],
    fonte: null,
    limite: null,
    discursoTipo: null,
    discursoFala: null,
    discursoExt: null,
    scft: [],
    bib: null,
    cit: null,
    web: 'NAO',
    texto: '',
    contexto: '',
    auditTipo: null
  });
  const [showResumo, setShowResumo] = useState(false);
  const [promptGerado, setPromptGerado] = useState('');
  
  // Estados de UI
  const [darkMode, setDarkMode] = useState(false);
  const [deviceView, setDeviceView] = useState('desktop');
  const [isFullscreen, setIsFullscreen] = useState(false);
  const [uploadedFiles, setUploadedFiles] = useState([]);
  
  // Estados do Chat
  const [chatOpen, setChatOpen] = useState(false);
  const [chatMessages, setChatMessages] = useState([
    { 
      role: 'assistant', 
      content: 'Olá! Sou o assistente de configuração. Posso ajudar com dúvidas sobre os parâmetros, estilos de escrita ou como usar melhor esta ferramenta. Digite sua pergunta!',
      timestamp: new Date()
    }
  ]);
  const [chatInput, setChatInput] = useState('');
  const [isTyping, setIsTyping] = useState(false);
  
  const containerRef = useRef(null);
  const fileInputRef = useRef(null);
  const chatEndRef = useRef(null);
  const chatInputRef = useRef(null);

  const regimeAtual = config.regime ? REGIMES[config.regime] : null;
  
  // Cores do tema
  const theme = {
    bg: darkMode ? '#1a1a1a' : '#faf8f5',
    bgGradient: darkMode 
      ? 'linear-gradient(180deg, #1a1a1a 0%, #2d2d2d 100%)'
      : 'linear-gradient(180deg, #faf8f5 0%, #f5f2ed 100%)',
    cardBg: darkMode ? '#2d2d2d' : '#fff',
    text: darkMode ? '#e5e5e5' : '#333',
    textMuted: darkMode ? '#999' : '#666',
    textLight: darkMode ? '#777' : '#888',
    border: darkMode ? '#444' : '#e8e4dc',
    borderLight: darkMode ? '#555' : '#d4d4d4',
    inputBg: darkMode ? '#333' : '#fff',
    hoverBg: darkMode ? '#3a3a3a' : '#f5f5f5',
    chatUserBg: darkMode ? '#4a4a4a' : '#e8e4dc',
    chatAssistantBg: darkMode ? '#363636' : '#f5f2ed',
    accentBg: (cor) => darkMode ? `${cor}25` : `${cor}10`,
    accentBorder: (cor) => darkMode ? `${cor}50` : `${cor}30`,
  };

  // Scroll do chat
  useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [chatMessages]);

  // Fullscreen toggle
  const toggleFullscreen = () => {
    if (!document.fullscreenElement) {
      containerRef.current?.requestFullscreen?.();
      setIsFullscreen(true);
    } else {
      document.exitFullscreen?.();
      setIsFullscreen(false);
    }
  };

  useEffect(() => {
    const handleFullscreenChange = () => {
      setIsFullscreen(!!document.fullscreenElement);
    };
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
  }, []);

  // Gerar resposta do assistente
  const generateAssistantResponse = (userMessage) => {
    const msg = userMessage.toLowerCase();
    
    if (msg.includes('regime') || msg.includes('ficção') || msg.includes('não ficção') || msg.includes('r1') || msg.includes('r2')) {
      return ASSISTANT_RESPONSES.regime;
    }
    if (msg.includes('tarefa') || msg.includes('emular') || msg.includes('expandir') || msg.includes('gerar') || msg.includes('auditar')) {
      return ASSISTANT_RESPONSES.tarefa;
    }
    if (msg.includes('perfil') || msg.includes('perfis') || msg.includes('iceberg') || msg.includes('economia')) {
      return ASSISTANT_RESPONSES.perfil;
    }
    if (msg.includes('discurso') || msg.includes('narrativa') || msg.includes('indireto') || msg.includes('argumentativo')) {
      return ASSISTANT_RESPONSES.discurso;
    }
    if (msg.includes('ajuda') || msg.includes('help') || msg.includes('como') || msg.includes('o que')) {
      return ASSISTANT_RESPONSES.help;
    }
    
    return ASSISTANT_RESPONSES.default;
  };

  // Enviar mensagem no chat
  const sendChatMessage = () => {
    if (!chatInput.trim()) return;
    
    const userMessage = {
      role: 'user',
      content: chatInput.trim(),
      timestamp: new Date()
    };
    
    setChatMessages(prev => [...prev, userMessage]);
    setChatInput('');
    setIsTyping(true);
    
    // Simular tempo de resposta
    setTimeout(() => {
      const assistantMessage = {
        role: 'assistant',
        content: generateAssistantResponse(userMessage.content),
        timestamp: new Date()
      };
      setChatMessages(prev => [...prev, assistantMessage]);
      setIsTyping(false);
    }, 800 + Math.random() * 700);
  };

  // File upload handler
  const handleFileUpload = (e) => {
    const files = Array.from(e.target.files);
    const validFiles = files.filter(file => {
      const ext = file.name.split('.').pop().toLowerCase();
      return ['pdf', 'doc', 'docx'].includes(ext);
    });
    
    validFiles.forEach(file => {
      const reader = new FileReader();
      reader.onload = (event) => {
        setUploadedFiles(prev => [...prev, {
          name: file.name,
          size: file.size,
          type: file.type,
          data: event.target.result
        }]);
      };
      reader.readAsDataURL(file);
    });
  };

  const removeFile = (index) => {
    setUploadedFiles(prev => prev.filter((_, i) => i !== index));
  };

  const formatFileSize = (bytes) => {
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
    return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
  };

  const atualizarConfig = (campo, valor) => {
    setConfig(prev => ({ ...prev, [campo]: valor }));
  };

  const togglePerfil = (perfilId) => {
    setConfig(prev => {
      const novos = prev.perfis.includes(perfilId)
        ? prev.perfis.filter(p => p !== perfilId)
        : prev.perfis.length < 2 ? [...prev.perfis, perfilId] : prev.perfis;
      return { ...prev, perfis: novos };
    });
  };

  const toggleScFt = (id) => {
    setConfig(prev => {
      const novos = prev.scft.includes(id)
        ? prev.scft.filter(s => s !== id)
        : prev.scft.length < 2 ? [...prev.scft, id] : prev.scft;
      return { ...prev, scft: novos };
    });
  };

  const gerarPrompt = () => {
    const linhas = [];
    linhas.push(`Regime: ${config.regime} (${REGIMES[config.regime].nome})`);
    linhas.push(`Tarefa: ${config.tarefa}`);
    linhas.push(`Unidade: ${config.unidade}`);
    linhas.push(`Modo: ${config.modo}`);
    if (config.perfis.length > 0) linhas.push(`Perfis: ${config.perfis.join(', ')}`);
    linhas.push(`Fonte: ${config.fonte}`);
    linhas.push(`Limite: ${config.limite}`);
    
    if (config.regime === 'R1') {
      linhas.push(`Discurso: ${config.discursoTipo}+${config.discursoFala}${config.discursoFala !== 'DR0' ? '+' + config.discursoExt : ''}`);
    } else {
      linhas.push(`Discurso: ${config.discursoTipo}+${config.discursoFala}`);
    }
    
    if (config.scft.length > 0) linhas.push(`SC/FT: ${config.scft.join(', ')}`);
    if (config.contexto) linhas.push(`CX: ${config.contexto}`);
    
    if (config.regime === 'R2') {
      linhas.push(`BIB: ${config.bib}; CIT: ${config.cit}; WEB: ${config.web}`);
    }
    
    if (config.tarefa === 'T4' && config.auditTipo) {
      linhas.push(`Auditoria: [${config.auditTipo}]`);
    }
    
    if (uploadedFiles.length > 0) {
      linhas.push(`Arquivos anexados: ${uploadedFiles.map(f => f.name).join(', ')}`);
    }

    return linhas.join('\n');
  };

  const proximaEtapa = () => {
    if (etapa === 8) {
      setPromptGerado(gerarPrompt());
      setShowResumo(true);
    } else {
      setEtapa(prev => prev + 1);
    }
  };

  const etapaAnterior = () => {
    if (showResumo) {
      setShowResumo(false);
    } else {
      setEtapa(prev => Math.max(0, prev - 1));
    }
  };

  const reiniciar = () => {
    setEtapa(0);
    setConfig({
      regime: null, tarefa: null, unidade: null, modo: null, perfis: [],
      fonte: null, limite: null, discursoTipo: null, discursoFala: null,
      discursoExt: null, scft: [], bib: null, cit: null, web: 'NAO',
      texto: '', contexto: '', auditTipo: null
    });
    setShowResumo(false);
    setPromptGerado('');
    setUploadedFiles([]);
  };

  const podeAvancar = () => {
    switch (etapa) {
      case 0: return config.regime !== null;
      case 1: return config.tarefa !== null;
      case 2: return config.unidade !== null;
      case 3: return config.modo !== null;
      case 4: return true;
      case 5: return config.fonte !== null && config.limite !== null;
      case 6: return config.discursoTipo !== null && config.discursoFala !== null &&
                     (config.regime === 'R2' || config.discursoFala === 'DR0' || config.discursoExt !== null);
      case 7: return true;
      case 8: return config.regime === 'R1' || (config.bib !== null && config.cit !== null);
      default: return true;
    }
  };

  const getAccentColor = () => {
    if (regimeAtual) {
      return darkMode ? regimeAtual.corEscura : regimeAtual.cor;
    }
    return darkMode ? '#888' : '#1a1a1a';
  };

  const CardOpcao = ({ selecionado, onClick, titulo, descricao, disabled, small }) => (
    <button
      onClick={onClick}
      disabled={disabled}
      style={{
        padding: small ? '12px 16px' : '20px 24px',
        border: selecionado ? `2px solid ${getAccentColor()}` : `1px solid ${theme.borderLight}`,
        borderRadius: '8px',
        background: selecionado ? theme.accentBg(getAccentColor()) : disabled ? theme.hoverBg : theme.cardBg,
        cursor: disabled ? 'not-allowed' : 'pointer',
        textAlign: 'left',
        opacity: disabled ? 0.5 : 1,
        transition: 'all 0.2s ease',
        width: '100%'
      }}
    >
      <div style={{ 
        fontFamily: "'Crimson Text', Georgia, serif",
        fontSize: small ? '16px' : '18px',
        fontWeight: 600,
        color: selecionado ? getAccentColor() : theme.text,
        marginBottom: descricao ? '4px' : 0
      }}>
        {titulo}
      </div>
      {descricao && (
        <div style={{ 
          fontFamily: "'Source Sans Pro', sans-serif",
          fontSize: '14px',
          color: theme.textMuted,
          lineHeight: 1.4
        }}>
          {descricao}
        </div>
      )}
    </button>
  );

  const ChipOpcao = ({ selecionado, onClick, label, disabled }) => (
    <button
      onClick={onClick}
      disabled={disabled}
      style={{
        padding: '8px 16px',
        border: selecionado ? `2px solid ${getAccentColor()}` : `1px solid ${theme.borderLight}`,
        borderRadius: '20px',
        background: selecionado ? getAccentColor() : theme.cardBg,
        color: selecionado ? '#fff' : theme.text,
        cursor: disabled ? 'not-allowed' : 'pointer',
        fontFamily: "'Source Sans Pro', sans-serif",
        fontSize: '14px',
        fontWeight: 500,
        opacity: disabled ? 0.5 : 1,
        transition: 'all 0.2s ease'
      }}
    >
      {label}
    </button>
  );

  const ToolbarButton = ({ active, onClick, children, title }) => (
    <button
      onClick={onClick}
      title={title}
      style={{
        padding: '8px 12px',
        border: active ? `2px solid ${getAccentColor()}` : `1px solid ${theme.borderLight}`,
        borderRadius: '6px',
        background: active ? theme.accentBg(getAccentColor()) : theme.cardBg,
        color: active ? getAccentColor() : theme.textMuted,
        cursor: 'pointer',
        fontFamily: "'Source Sans Pro', sans-serif",
        fontSize: '13px',
        fontWeight: 500,
        transition: 'all 0.2s ease',
        display: 'flex',
        alignItems: 'center',
        gap: '6px'
      }}
    >
      {children}
    </button>
  );

  // Componente de Chat
  const ChatPanel = () => (
    <div style={{
      position: 'fixed',
      bottom: deviceView === 'mobile' ? 0 : '24px',
      right: deviceView === 'mobile' ? 0 : '24px',
      width: deviceView === 'mobile' ? '100%' : '380px',
      height: chatOpen ? (deviceView === 'mobile' ? '100%' : '500px') : '56px',
      background: theme.cardBg,
      borderRadius: deviceView === 'mobile' ? (chatOpen ? '0' : '0') : '16px',
      boxShadow: `0 8px 32px rgba(0,0,0,${darkMode ? '0.4' : '0.2'})`,
      border: `1px solid ${theme.border}`,
      display: 'flex',
      flexDirection: 'column',
      transition: 'all 0.3s ease',
      zIndex: 1000,
      overflow: 'hidden'
    }}>
      {/* Chat Header */}
      <div
        onClick={() => setChatOpen(!chatOpen)}
        style={{
          padding: '16px 20px',
          background: getAccentColor(),
          color: '#fff',
          cursor: 'pointer',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          flexShrink: 0
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
          <span style={{ fontSize: '20px' }}>💬</span>
          <div>
            <div style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontWeight: 600,
              fontSize: '16px'
            }}>
              Assistente
            </div>
            <div style={{ 
              fontSize: '12px',
              opacity: 0.9
            }}>
              Tire suas dúvidas
            </div>
          </div>
        </div>
        <span style={{ 
          fontSize: '18px',
          transform: chatOpen ? 'rotate(180deg)' : 'rotate(0)',
          transition: 'transform 0.3s ease'
        }}>
          ▲
        </span>
      </div>

      {/* Chat Messages */}
      {chatOpen && (
        <>
          <div style={{
            flex: 1,
            overflowY: 'auto',
            padding: '16px',
            display: 'flex',
            flexDirection: 'column',
            gap: '12px'
          }}>
            {chatMessages.map((msg, index) => (
              <div
                key={index}
                style={{
                  display: 'flex',
                  justifyContent: msg.role === 'user' ? 'flex-end' : 'flex-start'
                }}
              >
                <div style={{
                  maxWidth: '85%',
                  padding: '12px 16px',
                  borderRadius: msg.role === 'user' 
                    ? '16px 16px 4px 16px' 
                    : '16px 16px 16px 4px',
                  background: msg.role === 'user' 
                    ? getAccentColor() 
                    : theme.chatAssistantBg,
                  color: msg.role === 'user' ? '#fff' : theme.text,
                  fontFamily: "'Source Sans Pro', sans-serif",
                  fontSize: '14px',
                  lineHeight: 1.5,
                  whiteSpace: 'pre-wrap'
                }}>
                  {msg.content}
                </div>
              </div>
            ))}
            
            {isTyping && (
              <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
                <div style={{
                  padding: '12px 16px',
                  borderRadius: '16px 16px 16px 4px',
                  background: theme.chatAssistantBg,
                  color: theme.textMuted,
                  fontFamily: "'Source Sans Pro', sans-serif",
                  fontSize: '14px'
                }}>
                  <span style={{ animation: 'pulse 1s infinite' }}>●</span>
                  <span style={{ animation: 'pulse 1s infinite 0.2s' }}> ●</span>
                  <span style={{ animation: 'pulse 1s infinite 0.4s' }}> ●</span>
                </div>
              </div>
            )}
            
            <div ref={chatEndRef} />
          </div>

          {/* Chat Input */}
          <div style={{
            padding: '16px',
            borderTop: `1px solid ${theme.border}`,
            display: 'flex',
            gap: '12px',
            flexShrink: 0
          }}>
            <input
              ref={chatInputRef}
              type="text"
              value={chatInput}
              onChange={(e) => setChatInput(e.target.value)}
              onKeyPress={(e) => e.key === 'Enter' && sendChatMessage()}
              placeholder="Digite sua pergunta..."
              style={{
                flex: 1,
                padding: '12px 16px',
                border: `1px solid ${theme.borderLight}`,
                borderRadius: '24px',
                background: theme.inputBg,
                color: theme.text,
                fontFamily: "'Source Sans Pro', sans-serif",
                fontSize: '14px',
                outline: 'none'
              }}
            />
            <button
              onClick={sendChatMessage}
              disabled={!chatInput.trim()}
              style={{
                width: '44px',
                height: '44px',
                borderRadius: '50%',
                border: 'none',
                background: chatInput.trim() ? getAccentColor() : theme.borderLight,
                color: '#fff',
                cursor: chatInput.trim() ? 'pointer' : 'not-allowed',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                fontSize: '18px',
                transition: 'all 0.2s ease'
              }}
            >
              ➤
            </button>
          </div>
        </>
      )}
    </div>
  );

  const renderEtapa = () => {
    if (showResumo) {
      return (
        <div style={{ animation: 'fadeIn 0.3s ease' }}>
          <h2 style={{ 
            fontFamily: "'Crimson Text', Georgia, serif",
            fontSize: '28px',
            marginBottom: '24px',
            color: getAccentColor()
          }}>
            Configuração Completa
          </h2>
          
          <div style={{
            background: darkMode ? '#222' : '#faf8f5',
            border: `1px solid ${theme.border}`,
            borderRadius: '8px',
            padding: '24px',
            marginBottom: '24px',
            fontFamily: "'IBM Plex Mono', monospace",
            fontSize: '14px',
            lineHeight: 1.8,
            whiteSpace: 'pre-wrap',
            color: theme.text
          }}>
            {promptGerado}
          </div>

          {/* Upload de arquivos */}
          <div style={{ marginBottom: '24px' }}>
            <label style={{
              display: 'block',
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '18px',
              marginBottom: '12px',
              color: theme.text
            }}>
              Arquivos de contexto (PDF, DOC):
            </label>
            
            <div
              onClick={() => fileInputRef.current?.click()}
              style={{
                border: `2px dashed ${theme.borderLight}`,
                borderRadius: '8px',
                padding: '24px',
                textAlign: 'center',
                cursor: 'pointer',
                background: theme.hoverBg,
                transition: 'all 0.2s ease',
                marginBottom: '12px'
              }}
            >
              <div style={{ fontSize: '32px', marginBottom: '8px' }}>📄</div>
              <div style={{ 
                fontFamily: "'Source Sans Pro', sans-serif",
                color: theme.textMuted,
                fontSize: '14px'
              }}>
                Clique para selecionar arquivos PDF ou DOC
              </div>
              <input
                ref={fileInputRef}
                type="file"
                accept=".pdf,.doc,.docx"
                multiple
                onChange={handleFileUpload}
                style={{ display: 'none' }}
              />
            </div>

            {uploadedFiles.length > 0 && (
              <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
                {uploadedFiles.map((file, index) => (
                  <div
                    key={index}
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'space-between',
                      padding: '12px 16px',
                      background: theme.accentBg(getAccentColor()),
                      border: `1px solid ${theme.accentBorder(getAccentColor())}`,
                      borderRadius: '6px'
                    }}
                  >
                    <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
                      <span style={{ fontSize: '20px' }}>
                        {file.name.endsWith('.pdf') ? '📕' : '📘'}
                      </span>
                      <div>
                        <div style={{ 
                          fontFamily: "'Source Sans Pro', sans-serif",
                          fontWeight: 600,
                          color: theme.text,
                          fontSize: '14px'
                        }}>
                          {file.name}
                        </div>
                        <div style={{ 
                          fontFamily: "'IBM Plex Mono', monospace",
                          fontSize: '12px',
                          color: theme.textMuted
                        }}>
                          {formatFileSize(file.size)}
                        </div>
                      </div>
                    </div>
                    <button
                      onClick={() => removeFile(index)}
                      style={{
                        background: 'none',
                        border: 'none',
                        cursor: 'pointer',
                        fontSize: '18px',
                        color: theme.textMuted,
                        padding: '4px 8px'
                      }}
                    >
                      ✕
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div style={{ marginBottom: '24px' }}>
            <label style={{
              display: 'block',
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '18px',
              marginBottom: '12px',
              color: theme.text
            }}>
              Cole seu texto ou briefing aqui:
            </label>
            <textarea
              value={config.texto}
              onChange={(e) => atualizarConfig('texto', e.target.value)}
              placeholder={config.fonte === 'briefing' 
                ? 'Descreva o que deseja que seja gerado...'
                : 'Cole o texto a ser trabalhado...'}
              style={{
                width: '100%',
                minHeight: '200px',
                padding: '16px',
                border: `1px solid ${theme.borderLight}`,
                borderRadius: '8px',
                fontFamily: "'Source Sans Pro', sans-serif",
                fontSize: '16px',
                lineHeight: 1.6,
                resize: 'vertical',
                background: theme.inputBg,
                color: theme.text
              }}
            />
          </div>

          <div style={{
            background: theme.accentBg(getAccentColor()),
            border: `1px solid ${theme.accentBorder(getAccentColor())}`,
            borderRadius: '8px',
            padding: '20px',
            marginBottom: '24px'
          }}>
            <h3 style={{
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '16px',
              color: getAccentColor(),
              marginBottom: '12px'
            }}>
              Prompt para copiar:
            </h3>
            <div style={{
              fontFamily: "'IBM Plex Mono', monospace",
              fontSize: '13px',
              lineHeight: 1.6,
              color: theme.text
            }}>
              {promptGerado}
              {config.texto && (
                <>
                  <br /><br />
                  ---TEXTO---<br />
                  {config.texto.substring(0, 200)}{config.texto.length > 200 ? '...' : ''}
                </>
              )}
            </div>
          </div>
        </div>
      );
    }

    switch (etapa) {
      case 0:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: theme.text
            }}>
              Escolha o Regime
            </h2>
            <p style={{ 
              fontFamily: "'Source Sans Pro', sans-serif",
              color: theme.textMuted,
              marginBottom: '32px',
              fontSize: '16px',
              lineHeight: 1.5
            }}>
              Cada regime possui características estilísticas próprias que guiarão toda a escrita.
            </p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              {Object.values(REGIMES).map(regime => (
                <CardOpcao
                  key={regime.id}
                  selecionado={config.regime === regime.id}
                  onClick={() => atualizarConfig('regime', regime.id)}
                  titulo={`[${regime.id}] ${regime.nome}`}
                  descricao={regime.descricao}
                />
              ))}
            </div>
          </div>
        );

      case 1:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Qual tarefa deseja realizar?
            </h2>
            <p style={{ 
              fontFamily: "'Source Sans Pro', sans-serif",
              color: theme.textMuted,
              marginBottom: '32px'
            }}>
              Selecione a operação que melhor se aplica ao seu objetivo.
            </p>
            <div style={{ display: 'grid', gridTemplateColumns: deviceView === 'mobile' ? '1fr' : 'repeat(2, 1fr)', gap: '12px' }}>
              {TAREFAS.map(tarefa => (
                <CardOpcao
                  key={tarefa.id}
                  selecionado={config.tarefa === tarefa.id}
                  onClick={() => atualizarConfig('tarefa', tarefa.id)}
                  titulo={`[${tarefa.id}] ${tarefa.nome}`}
                  descricao={tarefa.descricao}
                  small
                />
              ))}
            </div>
          </div>
        );

      case 2:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Unidade de Trabalho
            </h2>
            <p style={{ 
              fontFamily: "'Source Sans Pro', sans-serif",
              color: theme.textMuted,
              marginBottom: '32px'
            }}>
              Define a extensão de cada ciclo de trabalho.
            </p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
              {UNIDADES.map(unidade => (
                <CardOpcao
                  key={unidade.id}
                  selecionado={config.unidade === unidade.id}
                  onClick={() => atualizarConfig('unidade', unidade.id)}
                  titulo={`[${unidade.id}] ${unidade.nome}`}
                  descricao={unidade.descricao}
                  disabled={unidade.soR1 && config.regime === 'R2'}
                  small
                />
              ))}
            </div>
          </div>
        );

      case 3:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Modo de Saída
            </h2>
            <p style={{ 
              fontFamily: "'Source Sans Pro', sans-serif",
              color: theme.textMuted,
              marginBottom: '32px'
            }}>
              Escolha o formato das entregas.
            </p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
              {MODOS.map(modo => (
                <CardOpcao
                  key={modo.id}
                  selecionado={config.modo === modo.id}
                  onClick={() => atualizarConfig('modo', modo.id)}
                  titulo={`[${modo.id}] ${modo.nome}`}
                  descricao={modo.descricao}
                />
              ))}
            </div>
          </div>
        );

      case 4:
        const perfisDisponiveis = config.regime === 'R1' 
          ? [...PERFIS.geral, ...PERFIS.R1]
          : PERFIS.geral;
        
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Perfis Estilísticos
            </h2>
            <p style={{ 
              fontFamily: "'Source Sans Pro', sans-serif",
              color: theme.textMuted,
              marginBottom: '32px'
            }}>
              Selecione até 2 perfis para refinar o estilo. (Opcional)
            </p>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
              {perfisDisponiveis.map(perfil => (
                <ChipOpcao
                  key={perfil.id}
                  selecionado={config.perfis.includes(perfil.id)}
                  onClick={() => togglePerfil(perfil.id)}
                  label={`${perfil.id} ${perfil.nome}`}
                />
              ))}
            </div>
            {config.perfis.length > 0 && (
              <div style={{ 
                marginTop: '20px',
                padding: '16px',
                background: theme.hoverBg,
                borderRadius: '8px'
              }}>
                <strong style={{ color: theme.text }}>Selecionados:</strong>
                {config.perfis.map(pid => {
                  const perfil = perfisDisponiveis.find(p => p.id === pid);
                  return (
                    <div key={pid} style={{ marginTop: '8px', fontSize: '14px', color: theme.textMuted }}>
                      <strong style={{ color: theme.text }}>{perfil?.nome}:</strong> {perfil?.descricao}
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        );

      case 5:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Fonte e Limite
            </h2>
            
            <div style={{ marginBottom: '32px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '20px',
                marginBottom: '16px',
                color: theme.text
              }}>
                Fonte do texto
              </h3>
              <div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
                {[
                  { id: 'colado', nome: 'Texto colado' },
                  { id: 'arquivo', nome: 'Arquivo anexado' },
                  { id: 'briefing', nome: 'Briefing/descrição' }
                ].map(fonte => (
                  <ChipOpcao
                    key={fonte.id}
                    selecionado={config.fonte === fonte.id}
                    onClick={() => atualizarConfig('fonte', fonte.id)}
                    label={fonte.nome}
                  />
                ))}
              </div>
            </div>

            <div>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '20px',
                marginBottom: '16px',
                color: theme.text
              }}>
                Limite de intervenção
              </h3>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
                {LIMITES.map(limite => (
                  <CardOpcao
                    key={limite.id}
                    selecionado={config.limite === limite.id}
                    onClick={() => atualizarConfig('limite', limite.id)}
                    titulo={`[${limite.id}] ${limite.nome}`}
                    descricao={limite.descricao}
                    small
                  />
                ))}
              </div>
            </div>
          </div>
        );

      case 6:
        const discurso = config.regime === 'R1' ? DISCURSO_R1 : DISCURSO_R2;
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Tipo de Discurso
            </h2>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                {config.regime === 'R1' ? 'Modo narrativo' : 'Tipo textual'}
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {discurso.tipo.map(t => (
                  <ChipOpcao
                    key={t.id}
                    selecionado={config.discursoTipo === t.id}
                    onClick={() => atualizarConfig('discursoTipo', t.id)}
                    label={t.nome}
                  />
                ))}
              </div>
            </div>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                {config.regime === 'R1' ? 'Frequência de fala' : 'Nível de formalidade'}
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {(config.regime === 'R1' ? discurso.fala : discurso.nivel).map(f => (
                  <ChipOpcao
                    key={f.id}
                    selecionado={config.discursoFala === f.id}
                    onClick={() => atualizarConfig('discursoFala', f.id)}
                    label={f.nome}
                  />
                ))}
              </div>
            </div>

            {config.regime === 'R1' && config.discursoFala && config.discursoFala !== 'DR0' && (
              <div>
                <h3 style={{ 
                  fontFamily: "'Crimson Text', Georgia, serif",
                  fontSize: '18px',
                  marginBottom: '12px',
                  color: theme.text
                }}>
                  Extensão das falas
                </h3>
                <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                  {discurso.extensao.map(e => (
                    <ChipOpcao
                      key={e.id}
                      selecionado={config.discursoExt === e.id}
                      onClick={() => atualizarConfig('discursoExt', e.id)}
                      label={e.nome}
                    />
                  ))}
                </div>
              </div>
            )}
          </div>
        );

      case 7:
        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Contexto e Subtexto
            </h2>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Subtexto Crítico (SC) — opcional, até 2
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {SC_FT.SC.map(sc => (
                  <ChipOpcao
                    key={sc.id}
                    selecionado={config.scft.includes(sc.id)}
                    onClick={() => toggleScFt(sc.id)}
                    label={sc.nome}
                  />
                ))}
              </div>
            </div>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Fricção Temática (FT) — opcional, até 2
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {SC_FT.FT.map(ft => (
                  <ChipOpcao
                    key={ft.id}
                    selecionado={config.scft.includes(ft.id)}
                    onClick={() => toggleScFt(ft.id)}
                    label={ft.nome}
                  />
                ))}
              </div>
            </div>

            <div>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Contexto adicional (CX)
              </h3>
              <textarea
                value={config.contexto}
                onChange={(e) => atualizarConfig('contexto', e.target.value)}
                placeholder={config.regime === 'R1' 
                  ? 'lugar + ação física + objeto + luz/clima + tensão tácita + gesto + silêncio'
                  : 'tema/problema + objetivo + audiência + registro + evidência + limite'}
                style={{
                  width: '100%',
                  minHeight: '100px',
                  padding: '12px',
                  border: `1px solid ${theme.borderLight}`,
                  borderRadius: '8px',
                  fontFamily: "'Source Sans Pro', sans-serif",
                  fontSize: '14px',
                  resize: 'vertical',
                  background: theme.inputBg,
                  color: theme.text
                }}
              />
            </div>

            {config.tarefa === 'T4' && (
              <div style={{ marginTop: '24px' }}>
                <h3 style={{ 
                  fontFamily: "'Crimson Text', Georgia, serif",
                  fontSize: '18px',
                  marginBottom: '12px',
                  color: theme.text
                }}>
                  Tipo de Auditoria
                </h3>
                <div style={{ display: 'grid', gridTemplateColumns: deviceView === 'mobile' ? '1fr' : 'repeat(2, 1fr)', gap: '8px' }}>
                  {AUDIT_SUBMENU.map(item => (
                    <CardOpcao
                      key={item.id}
                      selecionado={config.auditTipo === item.id}
                      onClick={() => atualizarConfig('auditTipo', item.id)}
                      titulo={`[${item.id}] ${item.nome}`}
                      descricao={item.descricao}
                      small
                    />
                  ))}
                </div>
              </div>
            )}
          </div>
        );

      case 8:
        if (config.regime === 'R1') {
          return (
            <div style={{ animation: 'fadeIn 0.3s ease' }}>
              <h2 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '28px',
                marginBottom: '12px',
                color: getAccentColor()
              }}>
                Configuração Pronta
              </h2>
              <p style={{ 
                fontFamily: "'Source Sans Pro', sans-serif",
                color: theme.textMuted,
                marginBottom: '32px',
                lineHeight: 1.6
              }}>
                Todos os parâmetros obrigatórios para ficção foram coletados. 
                Clique em "Gerar Prompt" para ver a configuração final e inserir seu texto.
              </p>
              <div style={{
                padding: '20px',
                background: theme.accentBg(getAccentColor()),
                border: `1px solid ${theme.accentBorder(getAccentColor())}`,
                borderRadius: '8px'
              }}>
                <div style={{ 
                  fontFamily: "'IBM Plex Mono', monospace",
                  fontSize: '13px',
                  color: theme.textMuted
                }}>
                  <strong style={{ color: theme.text }}>Prévia:</strong> {config.regime} | {config.tarefa} | {config.unidade} | {config.modo} | 
                  {config.perfis.length > 0 ? ` ${config.perfis.join('+')} |` : ''} {config.limite} | {config.discursoTipo}
                </div>
              </div>
            </div>
          );
        }

        return (
          <div style={{ animation: 'fadeIn 0.3s ease' }}>
            <h2 style={{ 
              fontFamily: "'Crimson Text', Georgia, serif",
              fontSize: '28px',
              marginBottom: '12px',
              color: getAccentColor()
            }}>
              Referências (R2)
            </h2>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Formato bibliográfico
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {BIB_FORMATOS.map(formato => (
                  <ChipOpcao
                    key={formato}
                    selecionado={config.bib === formato}
                    onClick={() => atualizarConfig('bib', formato)}
                    label={formato}
                  />
                ))}
              </div>
            </div>

            <div style={{ marginBottom: '24px' }}>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Citação no corpo
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                <ChipOpcao
                  selecionado={config.cit === 'S'}
                  onClick={() => atualizarConfig('cit', 'S')}
                  label="CIT:S — Com atribuição"
                />
                <ChipOpcao
                  selecionado={config.cit === 'N'}
                  onClick={() => atualizarConfig('cit', 'N')}
                  label="CIT:N — Sem nomes"
                />
              </div>
            </div>

            <div>
              <h3 style={{ 
                fontFamily: "'Crimson Text', Georgia, serif",
                fontSize: '18px',
                marginBottom: '12px',
                color: theme.text
              }}>
                Pesquisa web
              </h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                <ChipOpcao
                  selecionado={config.web === 'SIM'}
                  onClick={() => atualizarConfig('web', 'SIM')}
                  label="WEB:SIM — Permitir busca"
                />
                <ChipOpcao
                  selecionado={config.web === 'NAO'}
                  onClick={() => atualizarConfig('web', 'NAO')}
                  label="WEB:NÃO — Só fontes fornecidas"
                />
              </div>
            </div>
          </div>
        );

      default:
        return null;
    }
  };

  const deviceWidth = DEVICE_SIZES[deviceView].width;

  return (
    <div
      ref={containerRef}
      style={{
        minHeight: '100vh',
        background: theme.bgGradient,
        fontFamily: "'Source Sans Pro', -apple-system, sans-serif",
        transition: 'all 0.3s ease'
      }}
    >
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400&family=Source+Sans+Pro:wght@400;600&family=IBM+Plex+Mono:wght@400;500&display=swap');
        
        @keyframes fadeIn {
          from { opacity: 0; transform: translateY(10px); }
          to { opacity: 1; transform: translateY(0); }
        }
        
        @keyframes pulse {
          0%, 100% { opacity: 0.4; }
          50% { opacity: 1; }
        }
        
        * { box-sizing: border-box; margin: 0; padding: 0; }
        
        button:hover:not(:disabled) {
          transform: translateY(-1px);
          box-shadow: 0 2px 8px rgba(0,0,0,${darkMode ? '0.3' : '0.1'});
        }
        
        textarea:focus, input:focus, button:focus {
          outline: none;
        }
        
        ::-webkit-scrollbar {
          width: 8px;
        }
        ::-webkit-scrollbar-track {
          background: ${darkMode ? '#2d2d2d' : '#f1f1f1'};
        }
        ::-webkit-scrollbar-thumb {
          background: ${darkMode ? '#555' : '#ccc'};
          border-radius: 4px;
        }
      `}</style>

      {/* Toolbar */}
      <div style={{
        position: 'sticky',
        top: 0,
        zIndex: 100,
        background: theme.cardBg,
        borderBottom: `1px solid ${theme.border}`,
        padding: '12px 24px',
        display: 'flex',
        justifyContent: 'center',
        gap: '8px',
        flexWrap: 'wrap'
      }}>
        {/* Device buttons */}
        <div style={{ display: 'flex', gap: '4px', marginRight: '16px' }}>
          {Object.entries(DEVICE_SIZES).map(([key, { label, icon }]) => (
            <ToolbarButton
              key={key}
              active={deviceView === key}
              onClick={() => setDeviceView(key)}
              title={label}
            >
              {icon} <span style={{ display: deviceView === 'mobile' ? 'none' : 'inline' }}>{label}</span>
            </ToolbarButton>
          ))}
        </div>

        {/* Theme toggle */}
        <ToolbarButton
          active={darkMode}
          onClick={() => setDarkMode(!darkMode)}
          title={darkMode ? 'Modo claro' : 'Modo escuro'}
        >
          {darkMode ? '☀️' : '🌙'} <span style={{ display: deviceView === 'mobile' ? 'none' : 'inline' }}>{darkMode ? 'Claro' : 'Escuro'}</span>
        </ToolbarButton>

        {/* Fullscreen toggle */}
        <ToolbarButton
          active={isFullscreen}
          onClick={toggleFullscreen}
          title={isFullscreen ? 'Sair da tela cheia' : 'Tela cheia'}
        >
          {isFullscreen ? '⊡' : '⛶'} <span style={{ display: deviceView === 'mobile' ? 'none' : 'inline' }}>{isFullscreen ? 'Sair' : 'Tela cheia'}</span>
        </ToolbarButton>

        {/* Chat toggle */}
        <ToolbarButton
          active={chatOpen}
          onClick={() => setChatOpen(!chatOpen)}
          title="Abrir chat de ajuda"
        >
          💬 <span style={{ display: deviceView === 'mobile' ? 'none' : 'inline' }}>Ajuda</span>
        </ToolbarButton>
      </div>

      {/* Device frame container */}
      <div style={{
        display: 'flex',
        justifyContent: 'center',
        padding: deviceView === 'desktop' ? '0' : '24px',
        paddingBottom: chatOpen && deviceView !== 'mobile' ? '540px' : (deviceView === 'desktop' ? '0' : '24px'),
        minHeight: 'calc(100vh - 60px)',
        transition: 'padding 0.3s ease'
      }}>
        <div style={{
          width: typeof deviceWidth === 'number' ? `${deviceWidth}px` : deviceWidth,
          maxWidth: '100%',
          background: theme.bg,
          borderRadius: deviceView === 'desktop' ? '0' : '24px',
          boxShadow: deviceView === 'desktop' ? 'none' : `0 8px 32px rgba(0,0,0,${darkMode ? '0.4' : '0.15'})`,
          border: deviceView === 'desktop' ? 'none' : `1px solid ${theme.border}`,
          overflow: 'hidden',
          transition: 'all 0.3s ease'
        }}>
          {/* Header */}
          <header style={{
            padding: deviceView === 'mobile' ? '16px 20px' : '24px 32px',
            borderBottom: `1px solid ${theme.border}`,
            background: theme.cardBg
          }}>
            <div style={{ 
              maxWidth: '800px', 
              margin: '0 auto', 
              display: 'flex', 
              alignItems: deviceView === 'mobile' ? 'flex-start' : 'center', 
              justifyContent: 'space-between',
              flexDirection: deviceView === 'mobile' ? 'column' : 'row',
              gap: '12px'
            }}>
              <div>
                <h1 style={{
                  fontFamily: "'Crimson Text', Georgia, serif",
                  fontSize: deviceView === 'mobile' ? '22px' : '28px',
                  fontWeight: 700,
                  color: theme.text,
                  letterSpacing: '-0.5px'
                }}>
                  Assistente de Escrita
                </h1>
                <p style={{
                  fontFamily: "'Source Sans Pro', sans-serif",
                  fontSize: '14px',
                  color: theme.textLight,
                  marginTop: '4px'
                }}>
                  Configurador Interativo de Estilo
                </p>
              </div>
              {regimeAtual && (
                <div style={{
                  padding: '8px 16px',
                  background: theme.accentBg(getAccentColor()),
                  border: `1px solid ${theme.accentBorder(getAccentColor())}`,
                  borderRadius: '6px',
                  fontFamily: "'IBM Plex Mono', monospace",
                  fontSize: '13px',
                  color: getAccentColor(),
                  fontWeight: 500
                }}>
                  {regimeAtual.id} — {regimeAtual.nome}
                </div>
              )}
            </div>
          </header>

          {/* Progress */}
          {!showResumo && (
            <div style={{
              maxWidth: '800px',
              margin: '0 auto',
              padding: deviceView === 'mobile' ? '16px 20px 0' : '24px 32px 0'
            }}>
              <div style={{
                display: 'flex',
                gap: '4px',
                marginBottom: '8px'
              }}>
                {[...Array(9)].map((_, i) => (
                  <div
                    key={i}
                    style={{
                      flex: 1,
                      height: '4px',
                      borderRadius: '2px',
                      background: i <= etapa ? getAccentColor() : (darkMode ? '#444' : '#e0e0e0'),
                      transition: 'background 0.3s ease'
                    }}
                  />
                ))}
              </div>
              <div style={{
                fontFamily: "'IBM Plex Mono', monospace",
                fontSize: '12px',
                color: theme.textLight
              }}>
                Etapa {etapa + 1} de 9
              </div>
            </div>
          )}

          {/* Content */}
          <main style={{
            maxWidth: '800px',
            margin: '0 auto',
            padding: deviceView === 'mobile' ? '20px' : '32px'
          }}>
            <div style={{
              background: theme.cardBg,
              borderRadius: '12px',
              padding: deviceView === 'mobile' ? '20px' : '32px',
              boxShadow: `0 1px 3px rgba(0,0,0,${darkMode ? '0.2' : '0.05'}), 0 4px 12px rgba(0,0,0,${darkMode ? '0.2' : '0.05'})`,
              border: `1px solid ${theme.border}`
            }}>
              {renderEtapa()}
            </div>

            {/* Navigation */}
            <div style={{
              display: 'flex',
              justifyContent: 'space-between',
              marginTop: '24px',
              gap: '16px',
              flexDirection: deviceView === 'mobile' ? 'column-reverse' : 'row'
            }}>
              <button
                onClick={etapa === 0 && !showResumo ? reiniciar : etapaAnterior}
                style={{
                  padding: '12px 24px',
                  background: theme.cardBg,
                  border: `1px solid ${theme.borderLight}`,
                  borderRadius: '8px',
                  fontFamily: "'Source Sans Pro', sans-serif",
                  fontSize: '15px',
                  fontWeight: 600,
                  color: theme.textMuted,
                  cursor: 'pointer',
                  transition: 'all 0.2s ease',
                  flex: deviceView === 'mobile' ? 1 : 'none'
                }}
              >
                {etapa === 0 && !showResumo ? 'Reiniciar' : '← Voltar'}
              </button>

              {showResumo ? (
                <button
                  onClick={reiniciar}
                  style={{
                    padding: '12px 32px',
                    background: getAccentColor(),
                    border: 'none',
                    borderRadius: '8px',
                    fontFamily: "'Source Sans Pro', sans-serif",
                    fontSize: '15px',
                    fontWeight: 600,
                    color: '#fff',
                    cursor: 'pointer',
                    transition: 'all 0.2s ease',
                    flex: deviceView === 'mobile' ? 1 : 'none'
                  }}
                >
                  Nova Configuração
                </button>
              ) : (
                <button
                  onClick={proximaEtapa}
                  disabled={!podeAvancar()}
                  style={{
                    padding: '12px 32px',
                    background: podeAvancar() ? getAccentColor() : (darkMode ? '#555' : '#ccc'),
                    border: 'none',
                    borderRadius: '8px',
                    fontFamily: "'Source Sans Pro', sans-serif",
                    fontSize: '15px',
                    fontWeight: 600,
                    color: '#fff',
                    cursor: podeAvancar() ? 'pointer' : 'not-allowed',
                    transition: 'all 0.2s ease',
                    flex: deviceView === 'mobile' ? 1 : 'none'
                  }}
                >
                  {etapa === 8 ? 'Gerar Prompt →' : 'Próximo →'}
                </button>
              )}
            </div>
          </main>

          {/* Footer */}
          <footer style={{
            textAlign: 'center',
            padding: '24px',
            fontFamily: "'Source Sans Pro', sans-serif",
            fontSize: '13px',
            color: theme.textLight
          }}>
            Estilos: Ficção (prosa concreta, estoica) • Não Ficção (clareza lógica, ceticismo metodológico)
          </footer>
        </div>
      </div>

      {/* Chat Panel */}
      <ChatPanel />
    </div>
  );
}

Comentários