const languageCopy = {
  en: {
    back: 'field guide', navPipeline: 'Pipeline', navExamples: 'Examples', stageContext: 'CONTEXT', stageReview: 'REVIEW', heroEyebrow: 'A real repository case study', heroTitle: 'Rules that<br />survive the <em>prompt.</em>',
    heroText: 'Prompts ask for behavior. Repositories preserve it. The interview project combines written context, reusable skills, executable checks, commit hooks, and independent review so the rule is still present when the conversation is gone.',
    heroAside: '8 skills · 3 agents · 4 enforcement layers', thesisLabel: 'THE SHORT VERSION', thesis: 'A prompt is advice for one run. A repository rule is reusable context plus an executable boundary.',
    pipelineLabel: 'Enforcement pipeline', pipelineMeta: 'select a checkpoint', pipelineEyebrow: 'From intent to evidence', pipelineTitle: 'Five places<br />a rule can <em>hold.</em>', pipelineText: 'Not every rule belongs in a hook. Put guidance where an agent can discover it, deterministic policy in a command, cheap checks at commit time, and independent judgment at review.',
    skillsLabel: 'Project-local skills', skillsMeta: 'procedures born from repeated friction', skillsEyebrow: 'Small instruction packages', skillsTitle: 'Teach the trap.<br />Name the <em>trigger.</em>', skillsText: 'These skills are not downloaded magic. They are repository-specific procedures under <code>.agents/skills/</code>, distilled from mistakes, commands, and architectural decisions that kept recurring.', skillGate: 'prove green is real', skillParallel: 'worktree per task', skillRepo: 'query before crawling', skillDebt: 'separate line of work', skillWriter: 'repeat twice, encode once', skillArea: 'stack-specific traps',
    examplesLabel: 'Concrete examples', examplesMeta: 'open the source, then adapt', ratchetLabel: 'CLI RATCHET', ratchetTitle: 'Debt may go down.<br />Never silently up.', hookTitle: 'Fast checks before history.', commitLabel: 'COMMIT MESSAGE', commitTitle: 'Intent has a grammar.', reviewLabel: 'INDEPENDENT REVIEW', reviewTitle: 'A second reader checks intent.', readChecker: 'Read the checker →', readHook: 'Read the hook →', readCommit: 'Read commitlint config →', readReview: 'Read review policy →',
    copyLabel: 'COPY / ADAPT', copyTitle: 'Ask your agent to map the enforcement stack.', copyText: 'Use this in the interview repository or adapt the path names to another project.', copyButton: 'COPY PROMPT', deeperLabel: 'GO DEEPER', deeperTitle: 'Read the implementation, not just this summary.', deepContext: 'Repository context', deepSkills: 'Skill catalog', deepAgents: 'Specialist agents', deepPolicy: 'Staged-file policy'
  },
  pt: {
    back: 'guia de campo', navPipeline: 'Pipeline', navExamples: 'Exemplos', stageContext: 'CONTEXTO', stageReview: 'REVISÃO', heroEyebrow: 'Um estudo de caso de repositório real', heroTitle: 'Regras que<br />sobrevivem ao <em>prompt.</em>',
    heroText: 'Prompts pedem comportamento. Repositórios o preservam. O projeto interview combina contexto escrito, skills reutilizáveis, verificações executáveis, hooks de commit e revisão independente para que a regra continue existindo quando a conversa terminar.',
    heroAside: '8 skills · 3 agentes · 4 camadas de enforcement', thesisLabel: 'A VERSÃO CURTA', thesis: 'Um prompt orienta uma execução. Uma regra de repositório é contexto reutilizável mais uma fronteira executável.',
    pipelineLabel: 'Pipeline de enforcement', pipelineMeta: 'selecione um checkpoint', pipelineEyebrow: 'Da intenção à evidência', pipelineTitle: 'Cinco lugares<br />onde a regra <em>segura.</em>', pipelineText: 'Nem toda regra pertence a um hook. Coloque orientação onde o agente descobre, política determinística em um comando, checks baratos no commit e julgamento independente na revisão.',
    skillsLabel: 'Skills locais do projeto', skillsMeta: 'procedimentos nascidos de atrito repetido', skillsEyebrow: 'Pequenos pacotes de instrução', skillsTitle: 'Ensine a armadilha.<br />Nomeie o <em>gatilho.</em>', skillsText: 'Estas skills não são mágica baixada. São procedimentos específicos do repositório em <code>.agents/skills/</code>, extraídos de erros, comandos e decisões arquiteturais recorrentes.', skillGate: 'prove que o verde é real', skillParallel: 'um worktree por tarefa', skillRepo: 'consulte antes de explorar', skillDebt: 'linha de trabalho separada', skillWriter: 'repita duas vezes, codifique uma', skillArea: 'armadilhas da stack',
    examplesLabel: 'Exemplos concretos', examplesMeta: 'abra a fonte, depois adapte', ratchetLabel: 'CATRACA CLI', ratchetTitle: 'A dívida pode cair.<br />Nunca subir em silêncio.', hookTitle: 'Checks rápidos antes do histórico.', commitLabel: 'MENSAGEM DE COMMIT', commitTitle: 'A intenção tem gramática.', reviewLabel: 'REVISÃO INDEPENDENTE', reviewTitle: 'Um segundo leitor verifica a intenção.', readChecker: 'Ler o checker →', readHook: 'Ler o hook →', readCommit: 'Ler config do commitlint →', readReview: 'Ler política de revisão →',
    copyLabel: 'COPIAR / ADAPTAR', copyTitle: 'Peça ao agente para mapear o enforcement.', copyText: 'Use isto no repositório interview ou adapte os caminhos para outro projeto.', copyButton: 'COPIAR PROMPT', deeperLabel: 'APROFUNDE', deeperTitle: 'Leia a implementação, não apenas este resumo.', deepContext: 'Contexto do repositório', deepSkills: 'Catálogo de skills', deepAgents: 'Agentes especialistas', deepPolicy: 'Política dos arquivos staged'
  }
};

const stages = {
  context: { number: '01', file: 'AGENTS.md', title: { en: 'Give every agent the same map', pt: 'Dê o mesmo mapa a cada agente' }, text: { en: 'Stack, commands, product boundaries, and known traps load before implementation. This is discoverable guidance—not an executable guarantee.', pt: 'Stack, comandos, limites do produto e armadilhas conhecidas carregam antes da implementação. É orientação descobrível — não garantia executável.' }, code: 'Read AGENTS.md\n→ query .agents/db\n→ load area skill', link: 'https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/AGENTS.md' },
  skills: { number: '02', file: '.agents/skills/', title: { en: 'Load only the relevant procedure', pt: 'Carregue apenas o procedimento relevante' }, text: { en: 'Frontend, Go API, gate discipline, parallel agents, repo databases, issues, skill writing, and tech debt each have a narrow trigger.', pt: 'Frontend, API Go, disciplina de gates, agentes paralelos, bancos do repo, issues, escrita de skills e dívida técnica têm gatilhos estreitos.' }, code: 'request + description\n→ matching SKILL.md\n→ focused workflow', link: 'https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/.agents/skills' },
  cli: { number: '03', file: 'scripts/check-ui-contract.mjs', title: { en: 'Turn measurable policy into a ratchet', pt: 'Transforme política mensurável em catraca' }, text: { en: 'The UI checker counts known violations and fails only when a count rises. Existing debt can be reduced, but a new change cannot quietly increase it.', pt: 'O checker de UI conta violações conhecidas e falha quando o total sobe. Dívida existente pode cair, mas uma mudança não pode aumentá-la em silêncio.' }, code: 'pnpm check:ui\ncurrent ≤ baseline → pass\ncurrent > baseline → fail', link: 'https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/scripts/check-ui-contract.mjs' },
  commit: { number: '04', file: '.husky/pre-commit', title: { en: 'Block cheap mistakes at the boundary', pt: 'Bloqueie erros baratos na fronteira' }, text: { en: 'Husky runs lint-staged plus the whole-tree UI ratchet. Commitlint separately enforces Conventional Commit messages.', pt: 'Husky executa lint-staged mais a catraca de UI da árvore inteira. Commitlint aplica Conventional Commits separadamente.' }, code: 'git commit\n├─ lint-staged\n├─ check:ui\n└─ commitlint', link: 'https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/.husky/pre-commit' },
  review: { number: '05', file: '.pr-review.json', title: { en: 'Reserve judgment for the PR', pt: 'Reserve julgamento para o PR' }, text: { en: 'An AI reviewer checks security, generated-code discipline, test quality, scope, and repository-specific traps. A verifier independently reruns gates before merge.', pt: 'Um revisor de IA verifica segurança, código gerado, qualidade dos testes, escopo e armadilhas do repositório. Um verifier roda os gates novamente antes do merge.' }, code: 'diff + house rules + prior review\n→ findings + risks\n→ human merge decision', link: 'https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/.pr-review.json' }
};

const skills = {
  gate: { name: 'gate-discipline', trigger: { en: 'Before commit, PR, or merge.', pt: 'Antes de commit, PR ou merge.' }, lesson: { en: 'Run canonical gates separately, inspect exit codes, distrust convenient cache hits, and prove generated code is current.', pt: 'Rode gates separadamente, leia exit codes, desconfie de cache conveniente e prove que código gerado está atual.' }, example: 'pnpm lint; echo "lint=$?"', path: '.agents/skills/gate-discipline/SKILL.md' },
  parallel: { name: 'parallel-agents', trigger: { en: 'When independent tasks can run concurrently.', pt: 'Quando tarefas independentes podem rodar juntas.' }, lesson: { en: 'One worktree and file ownership per task; prior-art scout first, verifier last, merge sequentially.', pt: 'Um worktree e ownership por tarefa; prior-art scout primeiro, verifier por último, merges sequenciais.' }, example: 'git worktree add .claude/worktrees/task -b feat/task', path: '.agents/skills/parallel-agents/SKILL.md' },
  repo: { name: 'repo-db', trigger: { en: 'At task start and before debugging.', pt: 'No início da tarefa e antes de diagnosticar.' }, lesson: { en: 'Query the repo map, canonical commands, and known-issues ledger before crawling thousands of files.', pt: 'Consulte mapa, comandos canônicos e known-issues antes de vasculhar milhares de arquivos.' }, example: "jq -r '.verify[]' .agents/db/commands.json", path: '.agents/skills/repo-db/SKILL.md' },
  debt: { name: 'tech-debt', trigger: { en: 'When unrelated debt appears mid-task.', pt: 'Quando dívida não relacionada aparece no meio.' }, lesson: { en: 'Do not smuggle cleanup into a feature. Record it, give it its own branch, and finish the underlying condition.', pt: 'Não esconda limpeza em uma feature. Registre, dê uma branch própria e finalize a condição original.' }, example: 'feature diff ≠ debt cleanup', path: '.agents/skills/tech-debt/SKILL.md' },
  writer: { name: 'skill-writer', trigger: { en: 'When a workflow is explained twice.', pt: 'Quando um fluxo é explicado duas vezes.' }, lesson: { en: 'Procedures become skills; isolated facts become known-issues entries. Keep the body short and the trigger discriminating.', pt: 'Procedimentos viram skills; fatos isolados viram known-issues. Corpo curto e gatilho discriminante.' }, example: '.agents/skills/<name>/SKILL.md', path: '.agents/skills/skill-writer/SKILL.md' },
  area: { name: 'frontend / go-api', trigger: { en: 'When changing the matching subsystem.', pt: 'Ao alterar o subsistema correspondente.' }, lesson: { en: 'Encode version-specific traps close to the work: Next/React/AntD boundaries, Connect APIs, sqlc types, migrations, and code generation.', pt: 'Codifique armadilhas de versão perto do trabalho: Next/React/AntD, APIs Connect, tipos sqlc, migrations e codegen.' }, example: 'area → local skill → canonical checks', path: '.agents/skills/' }
};

const prompts = {
  en: `Inspect this repository's enforcement stack before changing code.\n\n1. Read AGENTS.md.\n2. List .agents/skills and select only skills whose descriptions match the task.\n3. Query .agents/db/commands.json and .agents/db/known-issues.json.\n4. Explain what is guidance versus mechanically enforced by scripts, Husky, commitlint, CI, and PR review.\n5. For each relevant rule, cite the source path and the command that proves it.\n6. Identify gaps where documentation claims enforcement but no executable check exists.\n\nDo not modify files. Return a compact map: rule → source → enforcement point → verification command → remaining gap.`,
  pt: `Inspecione a stack de enforcement deste repositório antes de alterar código.\n\n1. Leia AGENTS.md.\n2. Liste .agents/skills e selecione apenas skills cuja descrição corresponda à tarefa.\n3. Consulte .agents/db/commands.json e .agents/db/known-issues.json.\n4. Explique o que é orientação e o que é imposto mecanicamente por scripts, Husky, commitlint, CI e revisão de PR.\n5. Para cada regra relevante, cite o caminho fonte e o comando que a comprova.\n6. Identifique lacunas onde a documentação promete enforcement sem check executável.\n\nNão modifique arquivos. Retorne um mapa compacto: regra → fonte → ponto de enforcement → comando de verificação → lacuna restante.`
};

let language = localStorage.getItem('rules-language') === 'pt' ? 'pt' : 'en';

function select(selector, value, key) {
  document.querySelectorAll(selector).forEach((button) => {
    const active = button.dataset[key] === value;
    button.classList.toggle('active', active);
    button.setAttribute('aria-selected', String(active));
  });
}

function renderStage(id) {
  const item = stages[id];
  document.querySelector('#stage-detail').innerHTML = `<div class="stage-number">${item.number}</div><div><span>${item.file}</span><h3>${item.title[language]}</h3><p>${item.text[language]}</p><a href="${item.link}">${language === 'pt' ? 'ABRIR FONTE ↗' : 'OPEN SOURCE ↗'}</a></div><pre><code>${item.code}</code></pre>`;
  select('[data-stage]', id, 'stage');
}

function renderSkill(id) {
  const item = skills[id];
  document.querySelector('#skill-detail').innerHTML = `<header><span>${language === 'pt' ? 'GATILHO' : 'TRIGGER'}</span><strong>${item.trigger[language]}</strong></header><h3>${item.name}</h3><p>${item.lesson[language]}</p><pre><code>${item.example}</code></pre><a href="https://git.marcospaulo.dev.br/netcracker/interview/src/branch/main/${item.path}">${language === 'pt' ? 'LER SKILL ↗' : 'READ SKILL ↗'}</a>`;
  select('[data-skill]', id, 'skill');
}

function renderLanguage(next) {
  language = next;
  document.documentElement.lang = language === 'pt' ? 'pt-BR' : 'en';
  document.querySelectorAll('[data-copy]').forEach((node) => { node.innerHTML = languageCopy[language][node.dataset.copy]; });
  document.querySelector('#explore-prompt').textContent = prompts[language];
  document.querySelectorAll('[data-lang]').forEach((button) => { const active = button.dataset.lang === language; button.classList.toggle('active', active); button.setAttribute('aria-pressed', String(active)); });
  renderStage(document.querySelector('[data-stage].active')?.dataset.stage || 'context');
  renderSkill(document.querySelector('[data-skill].active')?.dataset.skill || 'gate');
  localStorage.setItem('rules-language', language);
}

async function copyPrompt() {
  const value = prompts[language];
  try {
    await navigator.clipboard.writeText(value);
    document.querySelector('#copy-status').textContent = language === 'pt' ? 'Prompt copiado.' : 'Prompt copied.';
  } catch {
    document.querySelector('#copy-status').textContent = language === 'pt' ? 'Selecione o texto manualmente.' : 'Select the text manually.';
  }
}

document.querySelectorAll('[data-stage]').forEach((button) => button.addEventListener('click', () => renderStage(button.dataset.stage)));
document.querySelectorAll('[data-skill]').forEach((button) => button.addEventListener('click', () => renderSkill(button.dataset.skill)));
document.querySelectorAll('[data-lang]').forEach((button) => button.addEventListener('click', () => renderLanguage(button.dataset.lang)));
document.querySelector('[data-copy-prompt]').addEventListener('click', copyPrompt);
window.addEventListener('scroll', () => { const height = document.documentElement.scrollHeight - innerHeight; document.querySelector('.progress span').style.width = `${height > 0 ? scrollY / height * 100 : 0}%`; }, { passive: true });
renderLanguage(language);
