(() => { const cfg = window.SVB_GAME_CONFIG; const app = document.querySelector('#app'); const state = { index: 0, selected: new Set(), answered: false, discoveries: 0 }; const reducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches; const utmKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; function captureUtm() { const current = new URLSearchParams(location.search); const saved = JSON.parse(sessionStorage.getItem('svb_utm') || '{}'); utmKeys.forEach(key => { if (current.has(key)) saved[key] = current.get(key); }); sessionStorage.setItem('svb_utm', JSON.stringify(saved)); return saved; } const utm = captureUtm(); function track(event, detail = {}) { const payload = { event, ...detail, ...utm }; window.dataLayer = window.dataLayer || []; window.dataLayer.push(payload); window.dispatchEvent(new CustomEvent('svb:analytics', { detail: payload })); } function screen(html, className = '') { app.innerHTML = `
${html}
`; if (!reducedMotion) requestAnimationFrame(() => app.querySelector('.screen')?.classList.add('entered')); window.scrollTo(0, 0); } function logo() { return ``; } function renderIntro() { screen(` ${logo()}

QUEM É QUEM?

Você conhece mesmo os animais?

${cfg.texts.introSubtitle}

`, 'intro'); app.querySelector('[data-action="start"]').addEventListener('click', () => { track('game_start'); renderQuestion(0); }); } function animalButton(animal) { return ``; } function renderQuestion(index) { state.index = index; state.selected.clear(); state.answered = false; const q = cfg.questions[index]; const number = index + 1; screen(`
SVB
${number} de ${cfg.questions.length}Quem é quem?

PERGUNTA ${String(number).padStart(2, '0')}

${q.prompt}

${q.instruction}

${cfg.animals.map(animalButton).join('')}
`, 'game'); const multi = q.correct.length > 1; app.querySelectorAll('.animal-choice').forEach(btn => btn.addEventListener('click', () => { const id = btn.dataset.animal; if (!multi) { state.selected = new Set([id]); submitAnswer(); return; } state.selected.has(id) ? state.selected.delete(id) : state.selected.add(id); btn.setAttribute('aria-pressed', String(state.selected.has(id))); app.querySelector('[data-action="confirm"]').disabled = state.selected.size === 0; })); const confirm = app.querySelector('[data-action="confirm"]'); if (!multi) confirm.hidden = true; confirm.addEventListener('click', submitAnswer); } function sameAnswer(a, b) { return a.length === b.length && a.every(x => b.includes(x)); } function submitAnswer() { if (state.answered || state.selected.size === 0) return; state.answered = true; const q = cfg.questions[state.index]; const selected = [...state.selected]; const exact = sameAnswer(selected.sort(), [...q.correct].sort()); if (exact) state.discoveries++; track('question_answered', { question_id: q.id, question_number: state.index + 1, selected_answers: selected.join(','), matched_reference_answer: exact }); const correctAnimals = cfg.animals.filter(a => q.correct.includes(a.id)); screen(`
${state.index + 1} de ${cfg.questions.length}${exact ? 'VOCÊ PERCEBEU!' : 'OLHA SÓ…'}
${correctAnimals.map(a => ``).join('')}

${q.reveal}

${q.explanation}

Fontes para revisão científica
`, `feedback ${exact ? 'matched' : 'surprise'}`); app.querySelector('[data-action="next"]').addEventListener('click', () => { state.index === cfg.questions.length - 1 ? renderBridge() : renderQuestion(state.index + 1); }); } function renderBridge() { const lines = ['Eles brincam.', 'Eles aprendem.', 'Eles criam vínculos.', 'Eles têm preferências.', 'Eles sentem.']; screen(`
Ilustração de um cachorro, um porco, uma vaca e uma galinha lado a lado
${lines.map((line, i) => `

${line}

`).join('')}

Talvez eles tenham mais em comum do que você imaginava.

`, 'bridge'); const button = app.querySelector('.bridge-next'); if (!reducedMotion) { button.disabled = true; setTimeout(() => { button.disabled = false; }, 3400); } button.addEventListener('click', renderReveal); } function renderReveal() { screen(`

SE VOCÊ

AMA UM,

POR QUE COME

O OUTRO?

`, 'reveal'); app.querySelector('button').addEventListener('click', renderFinal); } function finalUrl() { const url = new URL(cfg.finalLink); Object.entries(utm).forEach(([key, value]) => { if (value) url.searchParams.set(key, value); }); return url.href; } function renderFinal() { track('game_complete', { matched_reference_answers: state.discoveries, total_questions: cfg.questions.length }); screen(` ${logo()}
Cachorro, porco, vaca e galinha juntos

Um novo olhar
pode ser o começo.

${cfg.texts.finalBody}

${cfg.texts.finalCta}

`, 'final'); app.querySelector('[data-action="cta"]').addEventListener('click', () => track('cta_start_vegan')); app.querySelector('[data-action="replay"]').addEventListener('click', () => { track('replay'); state.discoveries = 0; renderIntro(); }); app.querySelector('[data-action="share"]').addEventListener('click', shareGame); } async function shareGame() { const data = { title: cfg.campaign, text: cfg.shareText, url: location.href }; try { if (navigator.share) await navigator.share(data); else { await navigator.clipboard.writeText(`${data.text} ${data.url}`); app.querySelector('.copy-status').textContent = 'Link copiado! Agora é só compartilhar.'; } track('share', { method: navigator.share ? 'web_share' : 'copy_link' }); } catch (error) { if (error.name !== 'AbortError') app.querySelector('.copy-status').textContent = 'Não foi possível compartilhar agora.'; } } function registerWebMcp() { const context = document.modelContext; if (!context?.registerTool) return; const animalIds = new Set(cfg.animals.map(animal => animal.id)); const register = tool => { try { Promise.resolve(context.registerTool(tool)).catch(() => {}); } catch (_) {} }; register({ name: 'start_quiz', title: 'Começar o desafio', description: 'Inicia o quiz Quem é Quem? e mostra a primeira pergunta.', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, annotations: { readOnlyHint: false, untrustedContentHint: false }, execute() { track('game_start', { input_method: 'webmcp' }); renderQuestion(0); return { status: 'started', question_number: 1, total_questions: cfg.questions.length }; } }); register({ name: 'answer_current_question', title: 'Responder à pergunta atual', description: 'Seleciona uma ou mais espécies para a pergunta visível e exibe a explicação.', inputSchema: { type: 'object', properties: { animal_ids: { type: 'array', items: { type: 'string', enum: [...animalIds] }, minItems: 1, uniqueItems: true } }, required: ['animal_ids'], additionalProperties: false }, annotations: { readOnlyHint: false, untrustedContentHint: false }, execute(input) { if (!document.querySelector('.game')) throw new Error('Nenhuma pergunta está aberta.'); if (!input || !Array.isArray(input.animal_ids) || input.animal_ids.length === 0 || input.animal_ids.some(id => !animalIds.has(id))) throw new Error('Informe uma ou mais espécies válidas.'); state.selected = new Set(input.animal_ids); const id = cfg.questions[state.index].id; submitAnswer(); return { status: 'answered', question_id: id, selected_answers: input.animal_ids }; } }); register({ name: 'continue_quiz', title: 'Continuar o desafio', description: 'Avança da explicação atual para a próxima pergunta ou para a conclusão.', inputSchema: { type: 'object', properties: {}, additionalProperties: false }, annotations: { readOnlyHint: false, untrustedContentHint: false }, execute() { const current = document.querySelector('.screen'); if (current?.classList.contains('feedback')) state.index === cfg.questions.length - 1 ? renderBridge() : renderQuestion(state.index + 1); else if (current?.classList.contains('bridge')) renderReveal(); else if (current?.classList.contains('reveal')) renderFinal(); else throw new Error('Não há uma etapa pronta para avançar.'); return { status: 'advanced', screen: document.querySelector('.screen')?.classList[1] || 'unknown' }; } }); } registerWebMcp(); track('landing_view', { referrer: document.referrer || 'direct' }); renderIntro(); })();