const phases = { plan: { model: { en: 'OPUS / REASONING', pt: 'OPUS / RACIOCÍNIO' }, title: { en: 'Turn ambiguity into work', pt: 'Transforme ambiguidade em trabalho' }, copy: { en: 'Inspect the repository, choose the architecture, split the request, and write acceptance criteria.', pt: 'Inspecione o repositório, escolha a arquitetura, divida o pedido e escreva critérios de aceitação.' }, code: { en: 'plan → decompose → define acceptance', pt: 'planejar → decompor → definir aceitação' } }, build: { model: { en: 'SONNET, HAIKU, OR EQUIVALENT', pt: 'SONNET, HAIKU OU EQUIVALENTE' }, title: { en: 'Execute one bounded slice', pt: 'Execute uma fatia delimitada' }, copy: { en: 'Give each worker enough context, one responsibility, and its own worktree. Less context; less collision.', pt: 'Dê a cada worker contexto suficiente, uma responsabilidade e seu próprio worktree. Menos contexto; menos colisões.' }, code: { en: 'brief + worktree → implement → test', pt: 'brief + worktree → implementar → testar' } }, review: { model: { en: 'STRONG MODEL OR HUMAN', pt: 'MODELO FORTE OU HUMANO' }, title: { en: 'Reconnect result to intent', pt: 'Reconecte o resultado à intenção' }, copy: { en: 'Check the diff against the original brief, run the checks, then merge, request changes, or discard.', pt: 'Compare o diff com o brief original, execute as verificações e então faça merge, peça mudanças ou descarte.' }, code: { en: 'diff + checks → review → merge / iterate', pt: 'diff + verificações → revisar → merge / iterar' } } }; const interactiveCopy = { workers: { ui: { en: ['Interface worker', 'Receives: component contract + visual states', 'Returns: focused diff + viewport evidence'], pt: ['Worker de interface', 'Recebe: contrato do componente + estados visuais', 'Devolve: diff focado + evidência dos viewports'] }, tests: { en: ['Verification worker', 'Receives: acceptance criteria + changed surface', 'Returns: failing case, passing checks, risk notes'], pt: ['Worker de verificação', 'Recebe: critérios de aceitação + superfície alterada', 'Devolve: caso de falha, verificações passando e riscos'] }, docs: { en: ['Documentation worker', 'Receives: reviewed behavior + audience', 'Returns: guide, examples, and migration notes'], pt: ['Worker de documentação', 'Recebe: comportamento revisado + público', 'Devolve: guia, exemplos e notas de migração'] } }, trees: { main: { status: 'clean', owner: { en: 'Orchestrator', pt: 'Orquestrador' }, path: './project', command: 'git worktree list', note: { en: 'Shared history and integration point. Workers never edit here.', pt: 'Histórico compartilhado e ponto de integração. Workers nunca editam aqui.' } }, ui: { status: 'working', owner: { en: 'UI worker', pt: 'Worker de UI' }, path: '../task-ui', command: 'git worktree add ../task-ui -b agent/ui', note: { en: 'Own checkout and index. Safe to change presentation files in parallel.', pt: 'Checkout e índice próprios. Seguro para alterar a apresentação em paralelo.' } }, tests: { status: 'ready', owner: { en: 'Test worker', pt: 'Worker de testes' }, path: '../task-tests', command: 'git diff main...agent/tests', note: { en: 'Checks are green. Review the diff before merging into main.', pt: 'Verificações passaram. Revise o diff antes do merge em main.' } }, docs: { status: 'review', owner: { en: 'Docs worker', pt: 'Worker de docs' }, path: '../task-docs', command: 'git merge --no-ff agent/docs', note: { en: 'Review requested. Merge, request changes, or discard without touching another checkout.', pt: 'Revisão solicitada. Faça merge, peça mudanças ou descarte sem tocar em outro checkout.' } } }, routes: { plan: { score: 92, label: { en: 'High ambiguity', pt: 'Alta ambiguidade' }, why: { en: 'Architecture and decomposition have a wide error surface. Spend reasoning here.', pt: 'Arquitetura e decomposição têm grande superfície de erro. Invista raciocínio aqui.' } }, build: { score: 38, label: { en: 'Bounded execution', pt: 'Execução delimitada' }, why: { en: 'The brief already removed ambiguity. Optimize for speed and tight feedback.', pt: 'O brief já removeu a ambiguidade. Otimize para velocidade e feedback curto.' } }, explore: { score: 22, label: { en: 'Read-only discovery', pt: 'Descoberta somente leitura' }, why: { en: 'Search, map, and report. A lightweight model can return facts without editing.', pt: 'Busque, mapeie e reporte. Um modelo leve devolve fatos sem editar.' } }, review: { score: 74, label: { en: 'Independent judgment', pt: 'Julgamento independente' }, why: { en: 'Reconnect the diff to intent with fresh context and adversarial attention.', pt: 'Reconecte o diff à intenção com contexto novo e atenção crítica.' } } }, skillFiles: { skill: { icon: '◇', title: 'SKILL.md', en: 'Trigger, procedure, constraints, and the exact evidence the agent must return.', pt: 'Gatilho, procedimento, restrições e a evidência exata que o agente deve devolver.' }, references: { icon: '≡', title: 'references/', en: 'Stable facts loaded only when the procedure needs them. Keep the main instruction lean.', pt: 'Fatos estáveis carregados apenas quando o procedimento precisa. Mantenha a instrução principal enxuta.' }, scripts: { icon: '›_', title: 'scripts/', en: 'Deterministic checks and repeated operations. Prefer executable proof over prose.', pt: 'Verificações determinísticas e operações repetidas. Prefira prova executável a prosa.' }, assets: { icon: '▧', title: 'assets/', en: 'Templates and examples the agent can copy without reinventing the expected shape.', pt: 'Templates e exemplos que o agente pode copiar sem reinventar o formato esperado.' } } }; const translations = { pt: { '.chapter-links a:nth-child(1)': '01 frota', '.chapter-links a:nth-child(2)': '02 worktrees', '.chapter-links a:nth-child(3)': '03 skills', '.edition': 'ENGENHARIA DE IA 01 / 2026', '.hero .eyebrow': 'Uma apresentação para quem entrega software', '.lede': 'Você não precisa de um exército de modelos. Precisa de um sistema: uma mente para enquadrar o trabalho, várias mãos para executá-lo e uma fronteira clara entre cada tarefa.', '.hero-index span': 'NOTA DE CAMPO / 001', '.hero-index strong': 'Entregue o
sistema.', '.hero-index small': 'Skills · agentes · worktrees · evidências', '.hero-stats div:nth-child(1) span': 'modelo forte
para ambiguidade', '.hero-stats div:nth-child(2) span': 'workers delimitados
em paralelo', '.hero-stats div:nth-child(3) span': 'iterações
com evidências', '.hero-stats p': 'Leia isto como um mapa de rota, não como uma receita de prompt.', '.thesis span': 'REGRA ZERO', '.thesis strong': 'Modelo forte para ambiguidade.
Modelo leve para trabalho delimitado.', '.fleet .section-label span:nth-child(1)': 'Uma pequena frota', '.fleet .section-label span:nth-child(2)': 'coordenação antes do paralelismo', '.captain span': 'ORQUESTRADOR', '.captain h2': 'Decide o que
precisa acontecer.', '.worker-card[data-worker="ui"] strong': 'Componentes e estados visuais', '.worker-card[data-worker="tests"] strong': 'Casos de aceitação', '.worker-card[data-worker="docs"] strong': 'Guia e exemplos', '.caption': 'O orquestrador preserva a intenção, escreve pequenos contratos e reúne resultados verificáveis. Ele não precisa digitar cada linha.', '.failure-map .section-label span:nth-child(1)': 'Por que a fronteira importa', '.failure-map .section-label span:nth-child(2)': 'uma tarefa vaga / três falhas previsíveis', '.failure-grid article:nth-child(1) strong': 'Sopa de contexto', '.failure-grid article:nth-child(1) p': 'Cada worker lê tudo. Ninguém sabe quais fatos são essenciais.', '.failure-grid article:nth-child(2) strong': 'Colisão de branches', '.failure-grid article:nth-child(2) p': 'Dois agentes usam o mesmo checkout. O caminho mais rápido vira resolução de conflitos.', '.failure-grid article:nth-child(3) strong': 'Desvio confiante', '.failure-grid article:nth-child(3) p': 'O diff parece ótimo, mas ninguém verifica se resolveu o problema original.', '.workflow .eyebrow': 'O ciclo de subagentes', '#workflow-title': 'Clique em uma fase.
Veja a passagem.', '.workflow .copy > p:last-child': 'Delegar é mover uma tarefa delimitada para um contexto menor — não abrir mão da responsabilidade.', '.handoff .section-label span:nth-child(1)': 'O que atravessa contextos', '.handoff .section-label span:nth-child(2)': 'brief → diff → evidência', '.handoff thead th:nth-child(1)': 'Pacote', '.handoff thead th:nth-child(2)': 'Contém', '.handoff thead th:nth-child(3)': 'Por que importa', '.worktrees .eyebrow': 'Git worktrees', '.worktrees h2': 'Uma branch
por mão.', '.worktree-intro > p:nth-of-type(2)': 'Um worktree é outro diretório ligado ao mesmo repositório. Cada agente recebe seu próprio checkout e índice; o histórico continua compartilhado.', '.worktree-intro .interaction-hint': 'Selecione um nó para inspecionar checkout, responsável e próxima ação.', '.tree-toolbar > span:first-child': 'topologia do repositório', '.tree-live': ' 4 checkouts', '.tree-node.root span': 'RAIZ', '.tree-node.ui span': 'AGENTE DE UI', '.tree-node.tests span': 'AGENTE DE TESTES', '.tree-node.docs span': 'AGENTE DE DOCS', '.tree-node.root small': '● limpo', '.tree-node.ui small': '3 arquivos · trabalhando', '.tree-node.tests small': '8 verificações · pronto', '.tree-node.docs small': '2 páginas · revisão', '.routing .eyebrow': 'Roteamento de modelos', '.routing h2': 'Não pague por
raciocínio onde precisa
de ritmo.', '.routing .interaction-hint': 'Escolha um trabalho para entender por que o perfil do modelo muda.', '.route-table .head span:nth-child(1)': 'Trabalho', '.route-table .head span:nth-child(2)': 'Perfil', '.route-table .head span:nth-child(3)': 'Formato do prompt', '.route-table [data-route="plan"] strong': 'Planejar', '.route-table [data-route="build"] strong': 'Construir', '.route-table [data-route="explore"] strong': 'Explorar', '.route-table [data-route="review"] strong': 'Revisar', '.skills .eyebrow': 'Skills', '.skills h2': 'Escreva do jeito certo
uma vez.', '.skills > div:first-child > p': 'Uma skill é um procedimento reutilizável. Ela pode carregar instruções, referências, scripts e assets. Não é memória mágica e não substitui critérios de aceitação.', '.skill-principles span:nth-child(1)': '01 / defina o gatilho', '.skill-principles span:nth-child(2)': '02 / carregue detalhes sob demanda', '.skill-principles span:nth-child(3)': '03 / devolva evidências', '.skill-package > span': 'PACOTE DE SKILL', '.rule span': 'O PAPEL HUMANO', '.rule strong': 'O agente pode ser autônomo na execução. Intenção, limites e evidências continuam sendo seus.', '.callout span': 'COMECE AQUI', '.callout strong': 'Comece com um agente e uma skill. Adicione paralelismo apenas quando as tarefas forem realmente independentes.', '.sources .section-label span:nth-child(1)': 'Continue aprendendo', '.sources .section-label span:nth-child(2)': '12 novas leituras + documentação primária', '.sources p': 'Aprofunde com documentação oficial, casos de produção, Medium e fluxos de praticantes. Referências primárias → Trilha com 12 leituras →' } }; const panel = document.querySelector('#phase-panel'); const buttons = document.querySelectorAll('[data-phase]'); const originals = new Map(); let currentLanguage = 'en'; function setText(selector, value) { const nodes = document.querySelectorAll(selector); if (!nodes.length) return; if (!originals.has(selector)) originals.set(selector, [...nodes].map((node) => node.innerHTML)); nodes.forEach((node) => { node.innerHTML = value; }); } function render(id) { const phase = phases[id]; panel.innerHTML = `
${phase.model[currentLanguage]}${currentLanguage === 'pt' ? 'contexto: isolado' : 'context: isolated'}

${phase.title[currentLanguage]}

${phase.copy[currentLanguage]}

${phase.code[currentLanguage]}`; buttons.forEach((button) => { const active = button.dataset.phase === id; button.classList.toggle('active', active); button.setAttribute('aria-selected', String(active)); }); } function selectButtons(selector, activeValue, key) { document.querySelectorAll(selector).forEach((button) => { const active = button.dataset[key] === activeValue; button.classList.toggle('active', active); button.setAttribute(button.hasAttribute('aria-selected') ? 'aria-selected' : 'aria-pressed', String(active)); }); } function renderWorker(id) { const item = interactiveCopy.workers[id][currentLanguage]; document.querySelector('#worker-detail').innerHTML = `${item[0]}${item[1]}${item[2]}`; selectButtons('[data-worker]', id, 'worker'); } function renderTree(id) { const item = interactiveCopy.trees[id]; const language = currentLanguage; document.querySelector('#tree-detail').innerHTML = `
${language === 'pt' ? 'RESPONSÁVEL' : 'OWNER'}${item.owner[language]}
CHECKOUT${item.path}

${item.note[language]}

${item.command}`; selectButtons('[data-tree]', id, 'tree'); } function renderRoute(id) { const item = interactiveCopy.routes[id]; const language = currentLanguage; document.querySelector('#route-detail').innerHTML = `
${language === 'pt' ? 'CARGA DE RACIOCÍNIO' : 'REASONING LOAD'} · ${item.score}${item.label[language]}

${item.why[language]}

`; selectButtons('[data-route]', id, 'route'); } function renderSkillFile(id) { const item = interactiveCopy.skillFiles[id]; document.querySelector('#skill-detail').innerHTML = `${item.icon}
${item.title}

${item[currentLanguage]}

${currentLanguage === 'pt' ? 'clique em outro arquivo para explorar' : 'select another file to explore'}
`; selectButtons('[data-skill-file]', id, 'skillFile'); } function renderInteractive() { renderWorker(document.querySelector('[data-worker].active')?.dataset.worker || 'ui'); renderTree(document.querySelector('[data-tree].active')?.dataset.tree || 'main'); renderRoute(document.querySelector('[data-route].active')?.dataset.route || 'plan'); renderSkillFile(document.querySelector('[data-skill-file].active')?.dataset.skillFile || 'skill'); } function applyLanguage(language) { currentLanguage = language === 'pt' ? 'pt' : 'en'; document.documentElement.lang = currentLanguage === 'pt' ? 'pt-BR' : 'en'; if (currentLanguage === 'pt') Object.entries(translations.pt).forEach(([selector, value]) => setText(selector, value)); else originals.forEach((values, selector) => document.querySelectorAll(selector).forEach((node, index) => { node.innerHTML = values[index]; })); document.querySelectorAll('[data-lang]').forEach((button) => { const active = button.dataset.lang === currentLanguage; button.classList.toggle('active', active); button.setAttribute('aria-pressed', String(active)); }); render(document.querySelector('[data-phase].active')?.dataset.phase || 'plan'); renderInteractive(); try { localStorage.setItem('ai-for-dummies-language', currentLanguage); } catch (error) { /* previews may disable storage */ } } buttons.forEach((button) => button.addEventListener('click', () => render(button.dataset.phase))); document.querySelectorAll('[data-lang]').forEach((button) => button.addEventListener('click', () => applyLanguage(button.dataset.lang))); document.querySelectorAll('[data-worker]').forEach((button) => button.addEventListener('click', () => renderWorker(button.dataset.worker))); document.querySelectorAll('[data-tree]').forEach((button) => button.addEventListener('click', () => renderTree(button.dataset.tree))); document.querySelectorAll('[data-route]').forEach((button) => button.addEventListener('click', () => renderRoute(button.dataset.route))); document.querySelectorAll('[data-skill-file]').forEach((button) => button.addEventListener('click', () => renderSkillFile(button.dataset.skillFile))); window.addEventListener('scroll', () => { const height = document.documentElement.scrollHeight - window.innerHeight; document.querySelector('.reading-progress span').style.width = `${height > 0 ? (window.scrollY / height) * 100 : 0}%`; }, { passive: true }); let savedLanguage = 'en'; try { savedLanguage = localStorage.getItem('ai-for-dummies-language') || 'en'; } catch (error) { /* previews may disable storage */ } render('plan'); applyLanguage(savedLanguage);