{
  "schemaVersion": 1,
  "id": "frontend",
  "title": "Frontend",
  "version": "2026-10-12.40507d1e",
  "language": "pt-BR",
  "license": "MIT",
  "source": "https://github.com/flaviojmendes/trilhainfo/tree/main/src/roadmaps",
  "audience": "Para quem quer criar interfaces web e está começando a programar.",
  "outcome": "Uma aplicação responsiva e acessível, com API, testes e demonstração publicada.",
  "stages": [
    {
      "id": "frontend.comece-pela-web",
      "title": "Comece pela web",
      "description": "Sem pré-requisito de programação. Use um editor, o navegador e o terminal; publique pequenos exercícios desde o início.",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.internet-e-http",
        "curriculum.controle-de-versao",
        "aiLearning.seu-assistente-de-estudos"
      ]
    },
    {
      "id": "frontend.paginas-sem-framework",
      "title": "Páginas sem framework",
      "description": "Aprenda estrutura e layout antes de abstrações. Faça os exercícios em etapas.",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.html",
        "curriculum.css"
      ]
    },
    {
      "id": "frontend.interfaces-que-todos-podem-usar",
      "title": "Interfaces que todos podem usar",
      "description": "",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.acessibilidade"
      ]
    },
    {
      "id": "aiLearning.ia-prompting-e-contexto",
      "title": "IA: prompting e contexto",
      "description": "Depois dos primeiros fundamentos, pratique transformar uma dúvida em uma tarefa verificável. Use uma ferramenta por vez.",
      "optional": false,
      "kind": "ai",
      "groupIds": [
        "aiLearning.prompts-para-aprender-e-construir",
        "aiLearning.contexto-util-e-dados-protegidos"
      ]
    },
    {
      "id": "frontend.pagina-responsiva.stage",
      "title": "Projeto: Página responsiva",
      "description": "Construa antes de avançar. Registre as decisões e peça uma revisão.",
      "optional": false,
      "kind": "project",
      "groupIds": [
        "frontend.pagina-responsiva"
      ]
    },
    {
      "id": "frontend.interatividade-e-dados",
      "title": "Interatividade e dados",
      "description": "",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.javascript"
      ]
    },
    {
      "id": "aiLearning.ia-programacao-em-parceria",
      "title": "IA: programação em parceria",
      "description": "Use o primeiro projeto como contexto. Alterne pequenas implementações, leitura de código, depuração e testes.",
      "optional": false,
      "kind": "ai",
      "groupIds": [
        "aiLearning.planejar-implementar-e-revisar",
        "aiLearning.depuracao-com-evidencias"
      ]
    },
    {
      "id": "frontend.aplicacao-com-api.stage",
      "title": "Projeto: Aplicação com API",
      "description": "Construa antes de avançar. Registre as decisões e peça uma revisão.",
      "optional": false,
      "kind": "project",
      "groupIds": [
        "frontend.aplicacao-com-api"
      ]
    },
    {
      "id": "frontend.ferramentas-do-projeto",
      "title": "Ferramentas do projeto",
      "description": "Automatize tarefas que você já entende. Aprenda um gerenciador de pacotes e um build tool.",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.typescript",
        "frontend.vite-pacotes-e-qualidade"
      ]
    },
    {
      "id": "frontend.escolha-um-framework",
      "title": "Escolha um framework",
      "description": "React é uma opção de especialização. Vue ou Angular também podem fazer sentido conforme as vagas locais; escolha um para o primeiro projeto.",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "frontend.componentes-com-react",
        "frontend.componentes-com-angular",
        "frontend.componentes-com-vue"
      ]
    },
    {
      "id": "frontend.qualidade-e-entrega",
      "title": "Qualidade e entrega",
      "description": "",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "frontend.testes-de-interface",
        "frontend.desempenho-e-seguranca-web"
      ]
    },
    {
      "id": "aiLearning.ia-agentes-regras-e-verificacao",
      "title": "IA: agentes, regras e verificação",
      "description": "Depois de conseguir ler diffs, depurar e testar, delegue uma tarefa limitada no repositório de laboratório.",
      "optional": false,
      "kind": "ai",
      "groupIds": [
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente",
        "aiLearning.validar-trabalho-gerado-por-ia"
      ]
    },
    {
      "id": "frontend.produto-frontend.stage",
      "title": "Projeto: Produto frontend",
      "description": "Construa antes de avançar. Registre as decisões e peça uma revisão.",
      "optional": false,
      "kind": "project",
      "groupIds": [
        "frontend.produto-frontend"
      ]
    },
    {
      "id": "curriculum.preparacao-para-oportunidades",
      "title": "Preparação para oportunidades",
      "description": "Comece a buscar estágio ou vagas compatíveis com seus projetos. Ajuste o estudo aos requisitos recorrentes da sua região; concluir a trilha não garante contratação.",
      "optional": false,
      "kind": "study",
      "groupIds": [
        "curriculum.portfolio-e-candidatura",
        "curriculum.ia-no-fluxo-de-trabalho"
      ]
    },
    {
      "id": "frontend.aprofundamento-opcional",
      "title": "Aprofundamento opcional",
      "description": "Depois do projeto completo, escolha temas necessários ao produto ou à vaga. Não é preciso dominar todos para começar a se candidatar.",
      "optional": true,
      "kind": "study",
      "groupIds": [
        "frontend.renderizacao-design-system-e-css-avancado"
      ]
    }
  ],
  "groups": {
    "curriculum.internet-e-http": {
      "id": "curriculum.internet-e-http",
      "title": "Internet e HTTP",
      "description": "Entenda cliente e servidor, DNS, HTTPS, métodos, status, cabeçalhos, JSON e o ciclo de uma requisição. Use o painel Network do navegador.",
      "stageId": "frontend.comece-pela-web",
      "requiredIds": [
        "curriculum.internet-e-http.basics",
        "curriculum.internet-e-http.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Internet e HTTP e faça a prática essencial.",
          "stepIds": [
            "curriculum.internet-e-http.basics",
            "curriculum.internet-e-http.practice"
          ]
        },
        "standard": {
          "summary": "Entenda cliente e servidor, DNS, HTTPS, métodos, status, cabeçalhos, JSON e o ciclo de uma requisição. Use o painel Network do navegador.",
          "stepIds": [
            "curriculum.internet-e-http.basics",
            "curriculum.internet-e-http.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Internet e HTTP comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.internet-e-http.basics",
            "curriculum.internet-e-http.practice",
            "curriculum.internet-e-http.deepening"
          ]
        }
      }
    },
    "curriculum.controle-de-versao": {
      "id": "curriculum.controle-de-versao",
      "title": "Controle de Versão",
      "description": "Use Git desde o primeiro exercício: commits pequenos, branches, pull requests, revisão e resolução de conflitos. Não publique credenciais.",
      "stageId": "frontend.comece-pela-web",
      "requiredIds": [
        "curriculum.controle-de-versao.basics",
        "curriculum.controle-de-versao.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Controle de Versão e faça a prática essencial.",
          "stepIds": [
            "curriculum.controle-de-versao.basics",
            "curriculum.controle-de-versao.practice"
          ]
        },
        "standard": {
          "summary": "Use Git desde o primeiro exercício: commits pequenos, branches, pull requests, revisão e resolução de conflitos. Não publique credenciais.",
          "stepIds": [
            "curriculum.controle-de-versao.basics",
            "curriculum.controle-de-versao.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Controle de Versão comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.controle-de-versao.basics",
            "curriculum.controle-de-versao.practice",
            "curriculum.controle-de-versao.deepening"
          ]
        }
      }
    },
    "aiLearning.seu-assistente-de-estudos": {
      "id": "aiLearning.seu-assistente-de-estudos",
      "title": "Seu assistente de estudos",
      "description": "Aprenda programação e uso de IA em paralelo. Escolha uma ferramenta a que já tenha acesso; os exercícios também funcionam em um chat, compartilhando trechos pequenos. Documentação gratuita não significa serviço gratuito: consulte os limites da sua conta. Você não precisa assinar nem dominar três ferramentas.",
      "stageId": "frontend.comece-pela-web",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.escolha-uma-ferramenta",
        "aiLearning.pratique-tutoria"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Seu assistente de estudos e faça a prática essencial.",
          "stepIds": [
            "aiLearning.escolha-uma-ferramenta",
            "aiLearning.pratique-tutoria"
          ]
        },
        "standard": {
          "summary": "Aprenda programação e uso de IA em paralelo. Escolha uma ferramenta a que já tenha acesso; os exercícios também funcionam em um chat, compartilhando trechos pequenos. Documentação gratuita não significa serviço gratuito: consulte os limites da sua conta. Você não precisa assinar nem dominar três ferramentas.",
          "stepIds": [
            "aiLearning.escolha-uma-ferramenta",
            "aiLearning.pratique-tutoria"
          ]
        },
        "deep": {
          "summary": "Aprofunde Seu assistente de estudos comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.escolha-uma-ferramenta",
            "aiLearning.pratique-tutoria",
            "aiLearning.seu-assistente-de-estudos.deepening"
          ]
        }
      }
    },
    "curriculum.html": {
      "id": "curriculum.html",
      "title": "HTML",
      "description": "Aprenda estrutura semântica, títulos, links, imagens e formulários com labels e validação nativa. A página deve fazer sentido sem CSS.",
      "stageId": "frontend.paginas-sem-framework",
      "requiredIds": [
        "curriculum.html.basics",
        "curriculum.html.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de HTML e faça a prática essencial.",
          "stepIds": [
            "curriculum.html.basics",
            "curriculum.html.practice"
          ]
        },
        "standard": {
          "summary": "Aprenda estrutura semântica, títulos, links, imagens e formulários com labels e validação nativa. A página deve fazer sentido sem CSS.",
          "stepIds": [
            "curriculum.html.basics",
            "curriculum.html.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde HTML comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.html.basics",
            "curriculum.html.practice",
            "curriculum.html.deepening"
          ]
        }
      }
    },
    "curriculum.css": {
      "id": "curriculum.css",
      "title": "CSS",
      "description": "Aprenda cascata, especificidade, box model, Flexbox, Grid e layouts responsivos. Depois explore propriedades customizadas e container queries.",
      "stageId": "frontend.paginas-sem-framework",
      "requiredIds": [
        "curriculum.css.basics",
        "curriculum.css.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de CSS e faça a prática essencial.",
          "stepIds": [
            "curriculum.css.basics",
            "curriculum.css.practice"
          ]
        },
        "standard": {
          "summary": "Aprenda cascata, especificidade, box model, Flexbox, Grid e layouts responsivos. Depois explore propriedades customizadas e container queries.",
          "stepIds": [
            "curriculum.css.basics",
            "curriculum.css.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde CSS comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.css.basics",
            "curriculum.css.practice",
            "curriculum.css.deepening"
          ]
        }
      }
    },
    "curriculum.acessibilidade": {
      "id": "curriculum.acessibilidade",
      "title": "Acessibilidade",
      "description": "Inclua semântica, teclado, foco, contraste, mensagens de erro e teste com leitor de tela desde os primeiros componentes.",
      "stageId": "frontend.interfaces-que-todos-podem-usar",
      "requiredIds": [
        "curriculum.acessibilidade.basics",
        "curriculum.acessibilidade.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Acessibilidade e faça a prática essencial.",
          "stepIds": [
            "curriculum.acessibilidade.basics",
            "curriculum.acessibilidade.practice"
          ]
        },
        "standard": {
          "summary": "Inclua semântica, teclado, foco, contraste, mensagens de erro e teste com leitor de tela desde os primeiros componentes.",
          "stepIds": [
            "curriculum.acessibilidade.basics",
            "curriculum.acessibilidade.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Acessibilidade comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.acessibilidade.basics",
            "curriculum.acessibilidade.practice",
            "curriculum.acessibilidade.deepening"
          ]
        }
      }
    },
    "aiLearning.prompts-para-aprender-e-construir": {
      "id": "aiLearning.prompts-para-aprender-e-construir",
      "title": "Prompts para aprender e construir",
      "description": "Expresse objetivo, contexto, limites e como conferir o resultado. Mostre sua tentativa e exemplos de entrada/saída. Peça uma resposta no nível de quem está aprendendo e faça perguntas quando algo não estiver claro. Ajuste o prompt a partir do resultado, sem decorar fórmulas.",
      "stageId": "aiLearning.ia-prompting-e-contexto",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.prompts-para-aprender-e-construir.basics",
        "aiLearning.prompts-para-aprender-e-construir.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Prompts para aprender e construir e faça a prática essencial.",
          "stepIds": [
            "aiLearning.prompts-para-aprender-e-construir.basics",
            "aiLearning.prompts-para-aprender-e-construir.practice"
          ]
        },
        "standard": {
          "summary": "Expresse objetivo, contexto, limites e como conferir o resultado. Mostre sua tentativa e exemplos de entrada/saída. Peça uma resposta no nível de quem está aprendendo e faça perguntas quando algo não estiver claro. Ajuste o prompt a partir do resultado, sem decorar fórmulas.",
          "stepIds": [
            "aiLearning.prompts-para-aprender-e-construir.basics",
            "aiLearning.prompts-para-aprender-e-construir.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Prompts para aprender e construir comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.prompts-para-aprender-e-construir.basics",
            "aiLearning.prompts-para-aprender-e-construir.practice",
            "aiLearning.prompts-para-aprender-e-construir.deepening"
          ]
        }
      }
    },
    "aiLearning.contexto-util-e-dados-protegidos": {
      "id": "aiLearning.contexto-util-e-dados-protegidos",
      "title": "Contexto útil e dados protegidos",
      "description": "Forneça os arquivos relevantes, o erro completo sanitizado, a versão usada e o comportamento esperado. Diferencie conversar sobre código de permitir edição e execução. Use dados de laboratório; não compartilhe senhas, tokens ou dados pessoais.",
      "stageId": "aiLearning.ia-prompting-e-contexto",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.contexto-util-e-dados-protegidos.basics",
        "aiLearning.contexto-util-e-dados-protegidos.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Contexto útil e dados protegidos e faça a prática essencial.",
          "stepIds": [
            "aiLearning.contexto-util-e-dados-protegidos.basics",
            "aiLearning.contexto-util-e-dados-protegidos.practice"
          ]
        },
        "standard": {
          "summary": "Forneça os arquivos relevantes, o erro completo sanitizado, a versão usada e o comportamento esperado. Diferencie conversar sobre código de permitir edição e execução. Use dados de laboratório; não compartilhe senhas, tokens ou dados pessoais.",
          "stepIds": [
            "aiLearning.contexto-util-e-dados-protegidos.basics",
            "aiLearning.contexto-util-e-dados-protegidos.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Contexto útil e dados protegidos comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.contexto-util-e-dados-protegidos.basics",
            "aiLearning.contexto-util-e-dados-protegidos.practice",
            "aiLearning.contexto-util-e-dados-protegidos.deepening"
          ]
        }
      }
    },
    "frontend.pagina-responsiva": {
      "id": "frontend.pagina-responsiva",
      "title": "Página responsiva",
      "description": "Crie um site para um serviço ou iniciativa real com formulário e publique uma demonstração.",
      "stageId": "frontend.pagina-responsiva.stage",
      "ai": "assisted",
      "requiredIds": [
        "frontend.pagina-responsiva.criteria",
        "frontend.pagina-responsiva.ai-practice",
        "frontend.pagina-responsiva.verification"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Página responsiva e faça a prática essencial.",
          "stepIds": [
            "frontend.pagina-responsiva.criteria",
            "frontend.pagina-responsiva.ai-practice",
            "frontend.pagina-responsiva.verification"
          ]
        },
        "standard": {
          "summary": "Crie um site para um serviço ou iniciativa real com formulário e publique uma demonstração.",
          "stepIds": [
            "frontend.pagina-responsiva.criteria",
            "frontend.pagina-responsiva.ai-practice",
            "frontend.pagina-responsiva.verification"
          ]
        },
        "deep": {
          "summary": "Aprofunde Página responsiva comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.pagina-responsiva.criteria",
            "frontend.pagina-responsiva.ai-practice",
            "frontend.pagina-responsiva.verification",
            "frontend.pagina-responsiva.deepening"
          ]
        }
      }
    },
    "curriculum.javascript": {
      "id": "curriculum.javascript",
      "title": "JavaScript",
      "description": "Pratique variáveis, funções, arrays, objetos, módulos, DOM, eventos, promises, async/await e tratamento de erros antes de usar um framework.",
      "stageId": "frontend.interatividade-e-dados",
      "requiredIds": [
        "curriculum.javascript.basics",
        "curriculum.javascript.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de JavaScript e faça a prática essencial.",
          "stepIds": [
            "curriculum.javascript.basics",
            "curriculum.javascript.practice"
          ]
        },
        "standard": {
          "summary": "Pratique variáveis, funções, arrays, objetos, módulos, DOM, eventos, promises, async/await e tratamento de erros antes de usar um framework.",
          "stepIds": [
            "curriculum.javascript.basics",
            "curriculum.javascript.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde JavaScript comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.javascript.basics",
            "curriculum.javascript.practice",
            "curriculum.javascript.deepening"
          ]
        }
      }
    },
    "aiLearning.planejar-implementar-e-revisar": {
      "id": "aiLearning.planejar-implementar-e-revisar",
      "title": "Planejar, implementar e revisar",
      "description": "Defina um recorte pequeno e peça um plano. Decida o que implementar você e o que delegar. Revise cada diff, rode a aplicação e confira o comportamento antes de seguir para outra tarefa. A IA pode gerar código, testes e documentação, mas a evidência precisa ser executada.",
      "stageId": "aiLearning.ia-programacao-em-parceria",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.planejar-implementar-e-revisar.basics",
        "aiLearning.planejar-implementar-e-revisar.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Planejar, implementar e revisar e faça a prática essencial.",
          "stepIds": [
            "aiLearning.planejar-implementar-e-revisar.basics",
            "aiLearning.planejar-implementar-e-revisar.practice"
          ]
        },
        "standard": {
          "summary": "Defina um recorte pequeno e peça um plano. Decida o que implementar você e o que delegar. Revise cada diff, rode a aplicação e confira o comportamento antes de seguir para outra tarefa. A IA pode gerar código, testes e documentação, mas a evidência precisa ser executada.",
          "stepIds": [
            "aiLearning.planejar-implementar-e-revisar.basics",
            "aiLearning.planejar-implementar-e-revisar.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Planejar, implementar e revisar comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.planejar-implementar-e-revisar.basics",
            "aiLearning.planejar-implementar-e-revisar.practice",
            "aiLearning.planejar-implementar-e-revisar.deepening"
          ]
        }
      }
    },
    "aiLearning.depuracao-com-evidencias": {
      "id": "aiLearning.depuracao-com-evidencias",
      "title": "Depuração com evidências",
      "description": "Reproduza o problema e registre esperado versus observado. Peça hipóteses e uma forma de distinguir entre elas antes de tentar correções. Não confunda uma explicação plausível com uma causa confirmada.",
      "stageId": "aiLearning.ia-programacao-em-parceria",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.depuracao-com-evidencias.basics",
        "aiLearning.depuracao-com-evidencias.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Depuração com evidências e faça a prática essencial.",
          "stepIds": [
            "aiLearning.depuracao-com-evidencias.basics",
            "aiLearning.depuracao-com-evidencias.practice"
          ]
        },
        "standard": {
          "summary": "Reproduza o problema e registre esperado versus observado. Peça hipóteses e uma forma de distinguir entre elas antes de tentar correções. Não confunda uma explicação plausível com uma causa confirmada.",
          "stepIds": [
            "aiLearning.depuracao-com-evidencias.basics",
            "aiLearning.depuracao-com-evidencias.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Depuração com evidências comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.depuracao-com-evidencias.basics",
            "aiLearning.depuracao-com-evidencias.practice",
            "aiLearning.depuracao-com-evidencias.deepening"
          ]
        }
      }
    },
    "frontend.aplicacao-com-api": {
      "id": "frontend.aplicacao-com-api",
      "title": "Aplicação com API",
      "description": "Construa um catálogo com busca, filtros e favoritos usando JavaScript sem framework.",
      "stageId": "frontend.aplicacao-com-api.stage",
      "ai": "assisted",
      "requiredIds": [
        "frontend.aplicacao-com-api.criteria",
        "frontend.aplicacao-com-api.ai-practice",
        "frontend.aplicacao-com-api.verification"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Aplicação com API e faça a prática essencial.",
          "stepIds": [
            "frontend.aplicacao-com-api.criteria",
            "frontend.aplicacao-com-api.ai-practice",
            "frontend.aplicacao-com-api.verification"
          ]
        },
        "standard": {
          "summary": "Construa um catálogo com busca, filtros e favoritos usando JavaScript sem framework.",
          "stepIds": [
            "frontend.aplicacao-com-api.criteria",
            "frontend.aplicacao-com-api.ai-practice",
            "frontend.aplicacao-com-api.verification"
          ]
        },
        "deep": {
          "summary": "Aprofunde Aplicação com API comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.aplicacao-com-api.criteria",
            "frontend.aplicacao-com-api.ai-practice",
            "frontend.aplicacao-com-api.verification",
            "frontend.aplicacao-com-api.deepening"
          ]
        }
      }
    },
    "curriculum.typescript": {
      "id": "curriculum.typescript",
      "title": "TypeScript",
      "description": "Use tipos, interfaces, unions, narrowing e generics simples. Ative strict e entenda que tipos não validam dados recebidos em tempo de execução.",
      "stageId": "frontend.ferramentas-do-projeto",
      "requiredIds": [
        "curriculum.typescript.basics",
        "curriculum.typescript.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de TypeScript e faça a prática essencial.",
          "stepIds": [
            "curriculum.typescript.basics",
            "curriculum.typescript.practice"
          ]
        },
        "standard": {
          "summary": "Use tipos, interfaces, unions, narrowing e generics simples. Ative strict e entenda que tipos não validam dados recebidos em tempo de execução.",
          "stepIds": [
            "curriculum.typescript.basics",
            "curriculum.typescript.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde TypeScript comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.typescript.basics",
            "curriculum.typescript.practice",
            "curriculum.typescript.deepening"
          ]
        }
      }
    },
    "frontend.vite-pacotes-e-qualidade": {
      "id": "frontend.vite-pacotes-e-qualidade",
      "title": "Vite, pacotes e qualidade",
      "description": "Use npm, scripts, lockfile, Vite, lint e formatação. Separe variáveis públicas do cliente de segredos do servidor.",
      "stageId": "frontend.ferramentas-do-projeto",
      "requiredIds": [
        "frontend.vite-pacotes-e-qualidade.basics",
        "frontend.vite-pacotes-e-qualidade.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Vite, pacotes e qualidade e faça a prática essencial.",
          "stepIds": [
            "frontend.vite-pacotes-e-qualidade.basics",
            "frontend.vite-pacotes-e-qualidade.practice"
          ]
        },
        "standard": {
          "summary": "Use npm, scripts, lockfile, Vite, lint e formatação. Separe variáveis públicas do cliente de segredos do servidor.",
          "stepIds": [
            "frontend.vite-pacotes-e-qualidade.basics",
            "frontend.vite-pacotes-e-qualidade.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Vite, pacotes e qualidade comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.vite-pacotes-e-qualidade.basics",
            "frontend.vite-pacotes-e-qualidade.practice",
            "frontend.vite-pacotes-e-qualidade.deepening"
          ]
        }
      }
    },
    "frontend.componentes-com-react": {
      "id": "frontend.componentes-com-react",
      "title": "Componentes com React",
      "description": "Estude componentes, props, estado, eventos e composição depois de dominar JavaScript. Continue pela trilha React para aprofundar.",
      "stageId": "frontend.escolha-um-framework",
      "requiredIds": [
        "frontend.componentes-com-react.basics",
        "frontend.componentes-com-react.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Componentes com React e faça a prática essencial.",
          "stepIds": [
            "frontend.componentes-com-react.basics",
            "frontend.componentes-com-react.practice"
          ]
        },
        "standard": {
          "summary": "Estude componentes, props, estado, eventos e composição depois de dominar JavaScript. Continue pela trilha React para aprofundar.",
          "stepIds": [
            "frontend.componentes-com-react.basics",
            "frontend.componentes-com-react.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Componentes com React comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.componentes-com-react.basics",
            "frontend.componentes-com-react.practice",
            "frontend.componentes-com-react.deepening"
          ]
        }
      }
    },
    "frontend.componentes-com-angular": {
      "id": "frontend.componentes-com-angular",
      "title": "Componentes com Angular",
      "description": "Estude componentes, templates, signals, serviços, injeção de dependência e rotas depois de dominar JavaScript e TypeScript.",
      "stageId": "frontend.escolha-um-framework",
      "requiredIds": [
        "frontend.componentes-com-angular.basics",
        "frontend.componentes-com-angular.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Componentes com Angular e faça a prática essencial.",
          "stepIds": [
            "frontend.componentes-com-angular.basics",
            "frontend.componentes-com-angular.practice"
          ]
        },
        "standard": {
          "summary": "Estude componentes, templates, signals, serviços, injeção de dependência e rotas depois de dominar JavaScript e TypeScript.",
          "stepIds": [
            "frontend.componentes-com-angular.basics",
            "frontend.componentes-com-angular.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Componentes com Angular comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.componentes-com-angular.basics",
            "frontend.componentes-com-angular.practice",
            "frontend.componentes-com-angular.deepening"
          ]
        }
      }
    },
    "frontend.componentes-com-vue": {
      "id": "frontend.componentes-com-vue",
      "title": "Componentes com Vue",
      "description": "Estude componentes, props, reatividade, eventos e composables depois de dominar JavaScript.",
      "stageId": "frontend.escolha-um-framework",
      "requiredIds": [
        "frontend.componentes-com-vue.basics",
        "frontend.componentes-com-vue.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Componentes com Vue e faça a prática essencial.",
          "stepIds": [
            "frontend.componentes-com-vue.basics",
            "frontend.componentes-com-vue.practice"
          ]
        },
        "standard": {
          "summary": "Estude componentes, props, reatividade, eventos e composables depois de dominar JavaScript.",
          "stepIds": [
            "frontend.componentes-com-vue.basics",
            "frontend.componentes-com-vue.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Componentes com Vue comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.componentes-com-vue.basics",
            "frontend.componentes-com-vue.practice",
            "frontend.componentes-com-vue.deepening"
          ]
        }
      }
    },
    "frontend.testes-de-interface": {
      "id": "frontend.testes-de-interface",
      "title": "Testes de interface",
      "description": "Teste funções e comportamento de componentes. Cubra o fluxo principal com um teste de ponta a ponta, sem depender de detalhes internos.",
      "stageId": "frontend.qualidade-e-entrega",
      "requiredIds": [
        "frontend.testes-de-interface.basics",
        "frontend.testes-de-interface.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Testes de interface e faça a prática essencial.",
          "stepIds": [
            "frontend.testes-de-interface.basics",
            "frontend.testes-de-interface.practice"
          ]
        },
        "standard": {
          "summary": "Teste funções e comportamento de componentes. Cubra o fluxo principal com um teste de ponta a ponta, sem depender de detalhes internos.",
          "stepIds": [
            "frontend.testes-de-interface.basics",
            "frontend.testes-de-interface.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Testes de interface comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.testes-de-interface.basics",
            "frontend.testes-de-interface.practice",
            "frontend.testes-de-interface.deepening"
          ]
        }
      }
    },
    "frontend.desempenho-e-seguranca-web": {
      "id": "frontend.desempenho-e-seguranca-web",
      "title": "Desempenho e segurança web",
      "description": "Meça carregamento e interação, reduza imagens e JavaScript desnecessários. Entenda XSS, dependências e por que um segredo não pode ficar no frontend.",
      "stageId": "frontend.qualidade-e-entrega",
      "requiredIds": [
        "frontend.desempenho-e-seguranca-web.basics",
        "frontend.desempenho-e-seguranca-web.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Desempenho e segurança web e faça a prática essencial.",
          "stepIds": [
            "frontend.desempenho-e-seguranca-web.basics",
            "frontend.desempenho-e-seguranca-web.practice"
          ]
        },
        "standard": {
          "summary": "Meça carregamento e interação, reduza imagens e JavaScript desnecessários. Entenda XSS, dependências e por que um segredo não pode ficar no frontend.",
          "stepIds": [
            "frontend.desempenho-e-seguranca-web.basics",
            "frontend.desempenho-e-seguranca-web.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Desempenho e segurança web comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.desempenho-e-seguranca-web.basics",
            "frontend.desempenho-e-seguranca-web.practice",
            "frontend.desempenho-e-seguranca-web.deepening"
          ]
        }
      }
    },
    "aiLearning.instrucoes-do-projeto-e-escopo-do-agente": {
      "id": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente",
      "title": "Instruções do projeto e escopo do agente",
      "description": "Documente como rodar, testar e organizar o projeto. Pratique regras do Cursor, CLAUDE.md ou AGENTS.md conforme a ferramenta escolhida. Defina arquivos, tarefa, limites e permissões. Comece com uma branch e uma alteração pequena; deixe MCP, múltiplos agentes e automações amplas para aprofundamento.",
      "stageId": "aiLearning.ia-agentes-regras-e-verificacao",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Instruções do projeto e escopo do agente e faça a prática essencial.",
          "stepIds": [
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice"
          ]
        },
        "standard": {
          "summary": "Documente como rodar, testar e organizar o projeto. Pratique regras do Cursor, CLAUDE.md ou AGENTS.md conforme a ferramenta escolhida. Defina arquivos, tarefa, limites e permissões. Comece com uma branch e uma alteração pequena; deixe MCP, múltiplos agentes e automações amplas para aprofundamento.",
          "stepIds": [
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Instruções do projeto e escopo do agente comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice",
            "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.deepening"
          ]
        }
      }
    },
    "aiLearning.validar-trabalho-gerado-por-ia": {
      "id": "aiLearning.validar-trabalho-gerado-por-ia",
      "title": "Validar trabalho gerado por IA",
      "description": "Confira comportamento e requisitos além dos testes produzidos pelo próprio agente. Verifique casos negativos, dependências, documentação da versão e o resultado dos comandos. Para interface, faça inspeção visual e por teclado; para dados, use uma amostra com resultado conhecido.",
      "stageId": "aiLearning.ia-agentes-regras-e-verificacao",
      "ai": "focused",
      "requiredIds": [
        "aiLearning.validar-trabalho-gerado-por-ia.basics",
        "aiLearning.validar-trabalho-gerado-por-ia.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Validar trabalho gerado por IA e faça a prática essencial.",
          "stepIds": [
            "aiLearning.validar-trabalho-gerado-por-ia.basics",
            "aiLearning.validar-trabalho-gerado-por-ia.practice"
          ]
        },
        "standard": {
          "summary": "Confira comportamento e requisitos além dos testes produzidos pelo próprio agente. Verifique casos negativos, dependências, documentação da versão e o resultado dos comandos. Para interface, faça inspeção visual e por teclado; para dados, use uma amostra com resultado conhecido.",
          "stepIds": [
            "aiLearning.validar-trabalho-gerado-por-ia.basics",
            "aiLearning.validar-trabalho-gerado-por-ia.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Validar trabalho gerado por IA comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "aiLearning.validar-trabalho-gerado-por-ia.basics",
            "aiLearning.validar-trabalho-gerado-por-ia.practice",
            "aiLearning.validar-trabalho-gerado-por-ia.deepening"
          ]
        }
      }
    },
    "frontend.produto-frontend": {
      "id": "frontend.produto-frontend",
      "title": "Produto frontend",
      "description": "Evolua o catálogo para uma aplicação tipada, acessível, testada e publicada. Peça feedback de alguém que possa usá-la.",
      "stageId": "frontend.produto-frontend.stage",
      "ai": "assisted",
      "requiredIds": [
        "frontend.produto-frontend.criteria",
        "frontend.produto-frontend.ai-practice",
        "frontend.produto-frontend.verification"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Produto frontend e faça a prática essencial.",
          "stepIds": [
            "frontend.produto-frontend.criteria",
            "frontend.produto-frontend.ai-practice",
            "frontend.produto-frontend.verification"
          ]
        },
        "standard": {
          "summary": "Evolua o catálogo para uma aplicação tipada, acessível, testada e publicada. Peça feedback de alguém que possa usá-la.",
          "stepIds": [
            "frontend.produto-frontend.criteria",
            "frontend.produto-frontend.ai-practice",
            "frontend.produto-frontend.verification"
          ]
        },
        "deep": {
          "summary": "Aprofunde Produto frontend comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.produto-frontend.criteria",
            "frontend.produto-frontend.ai-practice",
            "frontend.produto-frontend.verification",
            "frontend.produto-frontend.deepening"
          ]
        }
      }
    },
    "curriculum.portfolio-e-candidatura": {
      "id": "curriculum.portfolio-e-candidatura",
      "title": "Portfólio e candidatura",
      "description": "Publique projetos com problema, instruções de execução, testes, decisões e limitações. Prepare currículo conciso, uma demonstração e exemplos de colaboração. Pratique leitura de documentação em inglês aos poucos.",
      "stageId": "curriculum.preparacao-para-oportunidades",
      "requiredIds": [
        "curriculum.portfolio-e-candidatura.basics",
        "curriculum.portfolio-e-candidatura.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Portfólio e candidatura e faça a prática essencial.",
          "stepIds": [
            "curriculum.portfolio-e-candidatura.basics",
            "curriculum.portfolio-e-candidatura.practice"
          ]
        },
        "standard": {
          "summary": "Publique projetos com problema, instruções de execução, testes, decisões e limitações. Prepare currículo conciso, uma demonstração e exemplos de colaboração. Pratique leitura de documentação em inglês aos poucos.",
          "stepIds": [
            "curriculum.portfolio-e-candidatura.basics",
            "curriculum.portfolio-e-candidatura.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Portfólio e candidatura comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.portfolio-e-candidatura.basics",
            "curriculum.portfolio-e-candidatura.practice",
            "curriculum.portfolio-e-candidatura.deepening"
          ]
        }
      }
    },
    "curriculum.ia-no-fluxo-de-trabalho": {
      "id": "curriculum.ia-no-fluxo-de-trabalho",
      "title": "IA no fluxo de trabalho",
      "description": "Use IA para explicar erros, propor testes e revisar hipóteses. Confira a documentação, o diff e os resultados. Proteja dados privados e segredos.",
      "stageId": "curriculum.preparacao-para-oportunidades",
      "ai": "focused",
      "requiredIds": [
        "curriculum.ia-no-fluxo-de-trabalho.basics",
        "curriculum.ia-no-fluxo-de-trabalho.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de IA no fluxo de trabalho e faça a prática essencial.",
          "stepIds": [
            "curriculum.ia-no-fluxo-de-trabalho.basics",
            "curriculum.ia-no-fluxo-de-trabalho.practice"
          ]
        },
        "standard": {
          "summary": "Use IA para explicar erros, propor testes e revisar hipóteses. Confira a documentação, o diff e os resultados. Proteja dados privados e segredos.",
          "stepIds": [
            "curriculum.ia-no-fluxo-de-trabalho.basics",
            "curriculum.ia-no-fluxo-de-trabalho.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde IA no fluxo de trabalho comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "curriculum.ia-no-fluxo-de-trabalho.basics",
            "curriculum.ia-no-fluxo-de-trabalho.practice",
            "curriculum.ia-no-fluxo-de-trabalho.deepening"
          ]
        }
      }
    },
    "frontend.renderizacao-design-system-e-css-avancado": {
      "id": "frontend.renderizacao-design-system-e-css-avancado",
      "title": "Renderização, design system e CSS avançado",
      "description": "Compare SPA, SSR e geração estática. Explore componentes reutilizáveis, CSS moderno e SEO. PWA, mobile, desktop e WebAssembly são caminhos separados.",
      "stageId": "frontend.aprofundamento-opcional",
      "requiredIds": [
        "frontend.renderizacao-design-system-e-css-avancado.basics",
        "frontend.renderizacao-design-system-e-css-avancado.practice"
      ],
      "variants": {
        "simple": {
          "summary": "Comece por uma referência de Renderização, design system e CSS avançado e faça a prática essencial.",
          "stepIds": [
            "frontend.renderizacao-design-system-e-css-avancado.basics",
            "frontend.renderizacao-design-system-e-css-avancado.practice"
          ]
        },
        "standard": {
          "summary": "Compare SPA, SSR e geração estática. Explore componentes reutilizáveis, CSS moderno e SEO. PWA, mobile, desktop e WebAssembly são caminhos separados.",
          "stepIds": [
            "frontend.renderizacao-design-system-e-css-avancado.basics",
            "frontend.renderizacao-design-system-e-css-avancado.practice"
          ]
        },
        "deep": {
          "summary": "Aprofunde Renderização, design system e CSS avançado comparando soluções e demonstrando suas decisões.",
          "stepIds": [
            "frontend.renderizacao-design-system-e-css-avancado.basics",
            "frontend.renderizacao-design-system-e-css-avancado.practice",
            "frontend.renderizacao-design-system-e-css-avancado.deepening"
          ]
        }
      }
    }
  },
  "nodes": {
    "curriculum.internet-e-http.basics": {
      "id": "curriculum.internet-e-http.basics",
      "groupId": "curriculum.internet-e-http",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.web",
        "resource.http",
        "resource.youtubeDeschampsWeb",
        "resource.youtubeCodigoFonte"
      ],
      "kind": "concept",
      "legacyIds": [
        "Internet e HTTP-O básico",
        "O básico-Internet e HTTP"
      ]
    },
    "curriculum.internet-e-http.practice": {
      "id": "curriculum.internet-e-http.practice",
      "groupId": "curriculum.internet-e-http",
      "title": "Pratique e confira",
      "description": "Inspecione uma requisição real e explique URL, método, resposta, status e por que uma falha ocorreu. Peça à IA hipóteses para a falha e confira cada uma no painel Network.",
      "requires": [
        "curriculum.internet-e-http.basics"
      ],
      "resourceIds": [
        "resource.web",
        "resource.http",
        "resource.youtubeDeschampsWeb",
        "resource.youtubeCodigoFonte"
      ],
      "kind": "practice",
      "legacyIds": [
        "Internet e HTTP-Pratique e confira",
        "Pratique e confira-Internet e HTTP"
      ]
    },
    "curriculum.internet-e-http.deepening": {
      "id": "curriculum.internet-e-http.deepening",
      "groupId": "curriculum.internet-e-http",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Compare cabeçalhos de cache em duas requisições reais. Explique idempotência e demonstre como distinguir uma falha de rede de um erro HTTP.",
      "requires": [
        "curriculum.internet-e-http.basics",
        "curriculum.internet-e-http.practice"
      ],
      "resourceIds": [
        "resource.web",
        "resource.http",
        "resource.youtubeDeschampsWeb",
        "resource.youtubeCodigoFonte"
      ],
      "legacyIds": []
    },
    "curriculum.controle-de-versao.basics": {
      "id": "curriculum.controle-de-versao.basics",
      "groupId": "curriculum.controle-de-versao",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.git",
        "resource.contribute",
        "resource.youtubeGitJusten",
        "resource.youtubeGitCourse"
      ],
      "kind": "concept",
      "legacyIds": [
        "Controle de Versão-O básico",
        "O básico-Controle de Versão"
      ]
    },
    "curriculum.controle-de-versao.practice": {
      "id": "curriculum.controle-de-versao.practice",
      "groupId": "curriculum.controle-de-versao",
      "title": "Pratique e confira",
      "description": "Crie um repositório com README, abra um pull request e resolva um conflito em uma branch de exercício. Peça à IA que explique o diff e confira a explicação no histórico do Git.",
      "requires": [
        "curriculum.controle-de-versao.basics"
      ],
      "resourceIds": [
        "resource.git",
        "resource.contribute",
        "resource.youtubeGitJusten",
        "resource.youtubeGitCourse"
      ],
      "kind": "practice",
      "legacyIds": [
        "Controle de Versão-Pratique e confira",
        "Pratique e confira-Controle de Versão"
      ]
    },
    "curriculum.controle-de-versao.deepening": {
      "id": "curriculum.controle-de-versao.deepening",
      "groupId": "curriculum.controle-de-versao",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Controle de Versão no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "curriculum.controle-de-versao.basics",
        "curriculum.controle-de-versao.practice"
      ],
      "resourceIds": [
        "resource.git",
        "resource.contribute",
        "resource.youtubeGitJusten",
        "resource.youtubeGitCourse"
      ],
      "legacyIds": []
    },
    "aiLearning.escolha-uma-ferramenta": {
      "id": "aiLearning.escolha-uma-ferramenta",
      "groupId": "aiLearning.seu-assistente-de-estudos",
      "title": "Escolha uma ferramenta",
      "description": "Experimente uma opção neste momento. Para concluir esta etapa, basta abrir um exercício em uma ferramenta e localizar como conversar, fornecer contexto e revisar uma mudança.\n\nCursor: abra um projeto no editor, converse sobre um arquivo e forneça trechos ou arquivos como contexto. Peça uma alteração pequena, examine o diff e execute o exemplo.\n\nClaude: use o chat com trechos fornecidos por você, ou Claude Code para trabalhar no projeto por terminal ou integrações de editor, se já tiver acesso. Siga o quickstart e peça uma explicação do repositório antes da primeira mudança.\n\nCodex: consulte o quickstart e escolha a superfície disponível para sua conta, como aplicativo, editor ou terminal. Peça que explique o projeto e como executar o exercício; depois experimente uma mudança pequena.\n\nSe ainda não tiver acesso a uma IA, siga os exercícios de programação e retome estas práticas quando uma opção estiver disponível.",
      "requires": [],
      "resourceIds": [
        "resource.cursor",
        "resource.cursorPrompts",
        "resource.claude",
        "resource.claudePractices",
        "resource.codex",
        "resource.codexPrompts"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Seu assistente de estudos-Escolha uma ferramenta",
        "Escolha uma ferramenta-Seu assistente de estudos"
      ]
    },
    "aiLearning.pratique-tutoria": {
      "id": "aiLearning.pratique-tutoria",
      "groupId": "aiLearning.seu-assistente-de-estudos",
      "title": "Pratique tutoria",
      "description": "Faça uma tentativa, peça uma explicação ou pista e confira o resultado executando o exemplo. Solicite perguntas e exercícios de revisão. Quando a IA gerar código, leia, altere e teste esse código. Conclua esta etapa após responder uma pergunta sobre o exemplo e resolver uma pequena variação.",
      "requires": [
        "aiLearning.escolha-uma-ferramenta"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.claudePractices",
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "focused",
      "prompt": "Estou aprendendo [conceito] na trilha [nome].\nMeu objetivo é [resultado pequeno e observável].\nJá tentei [tentativa] e observei [resultado ou erro].\nUse este trecho como contexto: [código ou exemplo sem dados privados].\nExplique a ideia com um exemplo curto e faça uma pergunta para conferir minha compreensão.\nDepois proponha uma variação do exercício. Aguarde minha tentativa antes de dar feedback.",
      "legacyIds": [
        "Seu assistente de estudos-Pratique tutoria",
        "Pratique tutoria-Seu assistente de estudos"
      ]
    },
    "aiLearning.seu-assistente-de-estudos.deepening": {
      "id": "aiLearning.seu-assistente-de-estudos.deepening",
      "groupId": "aiLearning.seu-assistente-de-estudos",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Seu assistente de estudos no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.escolha-uma-ferramenta",
        "aiLearning.pratique-tutoria"
      ],
      "resourceIds": [
        "resource.cursor",
        "resource.cursorPrompts",
        "resource.claude",
        "resource.claudePractices",
        "resource.codex",
        "resource.codexPrompts",
        "resource.ai"
      ],
      "legacyIds": []
    },
    "curriculum.html.basics": {
      "id": "curriculum.html.basics",
      "groupId": "curriculum.html",
      "title": "O básico",
      "description": "",
      "requires": [
        "curriculum.internet-e-http.basics"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.html",
        "resource.youtubeHtmlCourse"
      ],
      "kind": "concept",
      "legacyIds": [
        "HTML-O básico",
        "O básico-HTML"
      ]
    },
    "curriculum.html.practice": {
      "id": "curriculum.html.practice",
      "groupId": "curriculum.html",
      "title": "Pratique e confira",
      "description": "Monte uma página com navegação, formulário e imagens com texto alternativo. Peça à IA uma revisão de semântica e labels; confira as sugestões na documentação e percorra os controles pelo teclado.",
      "requires": [
        "curriculum.html.basics"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.html",
        "resource.youtubeHtmlCourse"
      ],
      "kind": "practice",
      "legacyIds": [
        "HTML-Pratique e confira",
        "Pratique e confira-HTML"
      ]
    },
    "curriculum.html.deepening": {
      "id": "curriculum.html.deepening",
      "groupId": "curriculum.html",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Compare a semântica de duas estruturas para a mesma página. Implemente um formulário com validação nativa, confira a árvore de acessibilidade e justifique suas escolhas.",
      "requires": [
        "curriculum.html.basics",
        "curriculum.html.practice"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.html",
        "resource.youtubeHtmlCourse"
      ],
      "legacyIds": []
    },
    "curriculum.css.basics": {
      "id": "curriculum.css.basics",
      "groupId": "curriculum.css",
      "title": "O básico",
      "description": "",
      "requires": [
        "curriculum.html.basics"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.css",
        "resource.youtubeCssCourse",
        "resource.youtubeOrigamid"
      ],
      "kind": "concept",
      "legacyIds": [
        "CSS-O básico",
        "O básico-CSS"
      ]
    },
    "curriculum.css.practice": {
      "id": "curriculum.css.practice",
      "groupId": "curriculum.css",
      "title": "Pratique e confira",
      "description": "Adapte a mesma página a celular e desktop sem rolagem horizontal, com texto legível e foco visível. Descreva um problema de layout à IA, teste a hipótese nas ferramentas do navegador e explique a correção.",
      "requires": [
        "curriculum.css.basics"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.css",
        "resource.youtubeCssCourse",
        "resource.youtubeOrigamid"
      ],
      "kind": "practice",
      "legacyIds": [
        "CSS-Pratique e confira",
        "Pratique e confira-CSS"
      ]
    },
    "curriculum.css.deepening": {
      "id": "curriculum.css.deepening",
      "groupId": "curriculum.css",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Resolva o mesmo layout com Flexbox e Grid. Teste a 320px, com zoom e texto longo; compare o comportamento e documente quando escolher cada abordagem.",
      "requires": [
        "curriculum.css.basics",
        "curriculum.css.practice"
      ],
      "resourceIds": [
        "resource.htmlCourse",
        "resource.css",
        "resource.youtubeCssCourse",
        "resource.youtubeOrigamid"
      ],
      "legacyIds": []
    },
    "curriculum.acessibilidade.basics": {
      "id": "curriculum.acessibilidade.basics",
      "groupId": "curriculum.acessibilidade",
      "title": "O básico",
      "description": "",
      "requires": [
        "curriculum.html.basics"
      ],
      "resourceIds": [
        "resource.accessibility"
      ],
      "kind": "concept",
      "legacyIds": [
        "Acessibilidade-O básico",
        "O básico-Acessibilidade"
      ]
    },
    "curriculum.acessibilidade.practice": {
      "id": "curriculum.acessibilidade.practice",
      "groupId": "curriculum.acessibilidade",
      "title": "Pratique e confira",
      "description": "Peça à IA que sugira uma lista de verificações. Conclua uma tarefa apenas com teclado e confira labels, foco e anúncios de erro com leitor de tela; a revisão do código não confirma sozinha a acessibilidade.",
      "requires": [
        "curriculum.acessibilidade.basics"
      ],
      "resourceIds": [
        "resource.accessibility"
      ],
      "kind": "practice",
      "legacyIds": [
        "Acessibilidade-Pratique e confira",
        "Pratique e confira-Acessibilidade"
      ]
    },
    "curriculum.acessibilidade.deepening": {
      "id": "curriculum.acessibilidade.deepening",
      "groupId": "curriculum.acessibilidade",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Conclua o fluxo usando somente teclado e leitor de tela. Introduza e corrija uma falha de foco ou anúncio de erro, registrando a evidência.",
      "requires": [
        "curriculum.acessibilidade.basics",
        "curriculum.acessibilidade.practice"
      ],
      "resourceIds": [
        "resource.accessibility"
      ],
      "legacyIds": []
    },
    "aiLearning.prompts-para-aprender-e-construir.basics": {
      "id": "aiLearning.prompts-para-aprender-e-construir.basics",
      "groupId": "aiLearning.prompts-para-aprender-e-construir",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Prompts para aprender e construir-O básico",
        "O básico-Prompts para aprender e construir"
      ]
    },
    "aiLearning.prompts-para-aprender-e-construir.practice": {
      "id": "aiLearning.prompts-para-aprender-e-construir.practice",
      "groupId": "aiLearning.prompts-para-aprender-e-construir",
      "title": "Pratique e confira",
      "description": "Compare um pedido vago com um pedido que inclui sua tentativa e critérios. Execute os exemplos e registre qual informação melhorou a resposta.",
      "requires": [
        "aiLearning.prompts-para-aprender-e-construir.basics"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "kind": "practice",
      "ai": "focused",
      "prompt": "Estou aprendendo [conceito] na trilha [nome].\nMeu objetivo é [resultado pequeno e observável].\nJá tentei [tentativa] e observei [resultado ou erro].\nUse este trecho como contexto: [código ou exemplo sem dados privados].\nExplique a ideia com um exemplo curto e faça uma pergunta para conferir minha compreensão.\nDepois proponha uma variação do exercício. Aguarde minha tentativa antes de dar feedback.",
      "legacyIds": [
        "Prompts para aprender e construir-Pratique e confira",
        "Pratique e confira-Prompts para aprender e construir"
      ]
    },
    "aiLearning.prompts-para-aprender-e-construir.deepening": {
      "id": "aiLearning.prompts-para-aprender-e-construir.deepening",
      "groupId": "aiLearning.prompts-para-aprender-e-construir",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Prompts para aprender e construir no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.prompts-para-aprender-e-construir.basics",
        "aiLearning.prompts-para-aprender-e-construir.practice"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "legacyIds": []
    },
    "aiLearning.contexto-util-e-dados-protegidos.basics": {
      "id": "aiLearning.contexto-util-e-dados-protegidos.basics",
      "groupId": "aiLearning.contexto-util-e-dados-protegidos",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.cursorPrompts",
        "resource.codexPrompts",
        "resource.ai"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Contexto útil e dados protegidos-O básico",
        "O básico-Contexto útil e dados protegidos"
      ]
    },
    "aiLearning.contexto-util-e-dados-protegidos.practice": {
      "id": "aiLearning.contexto-util-e-dados-protegidos.practice",
      "groupId": "aiLearning.contexto-util-e-dados-protegidos",
      "title": "Pratique e confira",
      "description": "Peça ajuda para a mesma dúvida com e sem o trecho relevante. Identifique uma suposição incorreta e corrija o contexto antes de aceitar a solução.",
      "requires": [
        "aiLearning.contexto-util-e-dados-protegidos.basics"
      ],
      "resourceIds": [
        "resource.cursorPrompts",
        "resource.codexPrompts",
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "focused",
      "legacyIds": [
        "Contexto útil e dados protegidos-Pratique e confira",
        "Pratique e confira-Contexto útil e dados protegidos"
      ]
    },
    "aiLearning.contexto-util-e-dados-protegidos.deepening": {
      "id": "aiLearning.contexto-util-e-dados-protegidos.deepening",
      "groupId": "aiLearning.contexto-util-e-dados-protegidos",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Contexto útil e dados protegidos no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.contexto-util-e-dados-protegidos.basics",
        "aiLearning.contexto-util-e-dados-protegidos.practice"
      ],
      "resourceIds": [
        "resource.cursorPrompts",
        "resource.codexPrompts",
        "resource.ai"
      ],
      "legacyIds": []
    },
    "frontend.pagina-responsiva.criteria": {
      "id": "frontend.pagina-responsiva.criteria",
      "groupId": "frontend.pagina-responsiva",
      "title": "Critérios de conclusão",
      "description": "A página funciona em celular e desktop, usa HTML semântico, permite navegação por teclado e tem README com decisões e URL publicada.",
      "requires": [],
      "resourceIds": [
        "resource.html",
        "resource.css",
        "resource.pages"
      ],
      "kind": "criteria",
      "legacyIds": [
        "Página responsiva-Critérios de conclusão",
        "Critérios de conclusão-Página responsiva"
      ]
    },
    "frontend.pagina-responsiva.ai-practice": {
      "id": "frontend.pagina-responsiva.ai-practice",
      "groupId": "frontend.pagina-responsiva",
      "title": "Prática de IA neste projeto",
      "description": "Planeje e explique o primeiro recorte antes de implementar. Adapte o prompt ao que você já construiu nesta etapa. Altere uma regra de layout ou validação e explique o resultado antes de consultar a IA.",
      "requires": [
        "frontend.pagina-responsiva.criteria"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "kind": "practice",
      "ai": "assisted",
      "prompt": "Projeto: Página responsiva.\nObjetivo: revisar um componente de interface e propor uma melhoria pequena de semântica, responsividade ou tratamento de erro.\nContexto: [arquivos da interface que já existirem, comportamento esperado e problema observado].\nNesta etapa: Planeje e explique o primeiro recorte antes de implementar.\nLimites: apenas este projeto de laboratório; use as ferramentas já escolhidas, dados públicos ou sintéticos e não exponha segredos.\nCritérios: funciona em celular e desktop, pelo teclado, com carregamento, erro e lista vazia quando aplicáveis.\nMostre as hipóteses e como verificá-las. Informe o que foi executado e o que ainda falta conferir.",
      "legacyIds": [
        "Página responsiva-Prática de IA neste projeto",
        "Prática de IA neste projeto-Página responsiva"
      ]
    },
    "frontend.pagina-responsiva.verification": {
      "id": "frontend.pagina-responsiva.verification",
      "groupId": "frontend.pagina-responsiva",
      "title": "Registre sua verificação",
      "description": "Registre um prompt sanitizado, uma sugestão aceita ou corrigida, a verificação executada e seu resultado. Explique a mudança com suas palavras. Conclua o projeto após demonstrar os critérios, mesmo quando parte do código vier de IA.",
      "requires": [
        "frontend.pagina-responsiva.criteria"
      ],
      "resourceIds": [
        "resource.git",
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "assisted",
      "legacyIds": [
        "Página responsiva-Registre sua verificação",
        "Registre sua verificação-Página responsiva"
      ]
    },
    "frontend.pagina-responsiva.deepening": {
      "id": "frontend.pagina-responsiva.deepening",
      "groupId": "frontend.pagina-responsiva",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Página responsiva no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.pagina-responsiva.criteria",
        "frontend.pagina-responsiva.ai-practice",
        "frontend.pagina-responsiva.verification"
      ],
      "resourceIds": [
        "resource.html",
        "resource.css",
        "resource.pages",
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices",
        "resource.git",
        "resource.ai"
      ],
      "legacyIds": []
    },
    "curriculum.javascript.basics": {
      "id": "curriculum.javascript.basics",
      "groupId": "curriculum.javascript",
      "title": "O básico",
      "description": "",
      "requires": [
        "curriculum.html.basics"
      ],
      "resourceIds": [
        "resource.jsCourse",
        "resource.js",
        "resource.fetch",
        "resource.youtubeJsCourse",
        "resource.youtubeHoraDeCodarJs"
      ],
      "kind": "concept",
      "legacyIds": [
        "JavaScript-O básico",
        "O básico-JavaScript"
      ]
    },
    "curriculum.javascript.practice": {
      "id": "curriculum.javascript.practice",
      "groupId": "curriculum.javascript",
      "title": "Pratique e confira",
      "description": "Crie uma lista com filtros e dados de uma API. Mostre carregamento, lista vazia e erro; peça uma pista à IA para um bug e investigue a hipótese com breakpoints. Altere uma função gerada e preveja o resultado.",
      "requires": [
        "curriculum.javascript.basics"
      ],
      "resourceIds": [
        "resource.jsCourse",
        "resource.js",
        "resource.fetch",
        "resource.youtubeJsCourse",
        "resource.youtubeHoraDeCodarJs"
      ],
      "kind": "practice",
      "legacyIds": [
        "JavaScript-Pratique e confira",
        "Pratique e confira-JavaScript"
      ]
    },
    "curriculum.javascript.deepening": {
      "id": "curriculum.javascript.deepening",
      "groupId": "curriculum.javascript",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Implemente busca com cancelamento de requisições e tratamento de respostas fora de ordem. Reproduza uma conexão lenta e explique como evitar dados desatualizados.",
      "requires": [
        "curriculum.javascript.basics",
        "curriculum.javascript.practice"
      ],
      "resourceIds": [
        "resource.jsCourse",
        "resource.js",
        "resource.fetch",
        "resource.youtubeJsCourse",
        "resource.youtubeHoraDeCodarJs"
      ],
      "legacyIds": []
    },
    "aiLearning.planejar-implementar-e-revisar.basics": {
      "id": "aiLearning.planejar-implementar-e-revisar.basics",
      "groupId": "aiLearning.planejar-implementar-e-revisar",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts",
        "resource.cursor"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Planejar, implementar e revisar-O básico",
        "O básico-Planejar, implementar e revisar"
      ]
    },
    "aiLearning.planejar-implementar-e-revisar.practice": {
      "id": "aiLearning.planejar-implementar-e-revisar.practice",
      "groupId": "aiLearning.planejar-implementar-e-revisar",
      "title": "Pratique e confira",
      "description": "Implemente uma pequena mudança em parceria. Explique o diff, rejeite ou ajuste uma sugestão e acrescente um caso de teste que não veio da mesma proposta.",
      "requires": [
        "aiLearning.planejar-implementar-e-revisar.basics"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts",
        "resource.cursor"
      ],
      "kind": "practice",
      "ai": "focused",
      "prompt": "Quero implementar [mudança pequena] neste projeto.\nContexto: [arquivos relevantes, comportamento atual e versão].\nResultado esperado: [exemplo de entrada e saída].\nLimites: [arquivos que podem mudar e requisitos que devem ser preservados].\nPrimeiro proponha um plano curto e a verificação. Depois trabalharemos uma etapa por vez.\nAo implementar, mostre o diff, explique as decisões e informe os comandos executados e seus resultados.",
      "legacyIds": [
        "Planejar, implementar e revisar-Pratique e confira",
        "Pratique e confira-Planejar, implementar e revisar"
      ]
    },
    "aiLearning.planejar-implementar-e-revisar.deepening": {
      "id": "aiLearning.planejar-implementar-e-revisar.deepening",
      "groupId": "aiLearning.planejar-implementar-e-revisar",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Planejar, implementar e revisar no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.planejar-implementar-e-revisar.basics",
        "aiLearning.planejar-implementar-e-revisar.practice"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts",
        "resource.cursor"
      ],
      "legacyIds": []
    },
    "aiLearning.depuracao-com-evidencias.basics": {
      "id": "aiLearning.depuracao-com-evidencias.basics",
      "groupId": "aiLearning.depuracao-com-evidencias",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Depuração com evidências-O básico",
        "O básico-Depuração com evidências"
      ]
    },
    "aiLearning.depuracao-com-evidencias.practice": {
      "id": "aiLearning.depuracao-com-evidencias.practice",
      "groupId": "aiLearning.depuracao-com-evidencias",
      "title": "Pratique e confira",
      "description": "Introduza um bug no laboratório, confirme uma hipótese por log, breakpoint ou teste e verifique uma correção mínima.",
      "requires": [
        "aiLearning.depuracao-com-evidencias.basics"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts"
      ],
      "kind": "practice",
      "ai": "focused",
      "prompt": "Problema reproduzível: [passos].\nEsperado: [resultado]. Observado: [resultado ou erro sanitizado].\nContexto: [trecho, configuração e versões relevantes].\nListe até três hipóteses e uma verificação para distinguir cada uma.\nPrimeiro vamos confirmar a causa. Depois proponha a menor correção e um teste de regressão.",
      "legacyIds": [
        "Depuração com evidências-Pratique e confira",
        "Pratique e confira-Depuração com evidências"
      ]
    },
    "aiLearning.depuracao-com-evidencias.deepening": {
      "id": "aiLearning.depuracao-com-evidencias.deepening",
      "groupId": "aiLearning.depuracao-com-evidencias",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Depuração com evidências no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.depuracao-com-evidencias.basics",
        "aiLearning.depuracao-com-evidencias.practice"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.codexPrompts"
      ],
      "legacyIds": []
    },
    "frontend.aplicacao-com-api.criteria": {
      "id": "frontend.aplicacao-com-api.criteria",
      "groupId": "frontend.aplicacao-com-api",
      "title": "Critérios de conclusão",
      "description": "Trate carregamento, falhas e lista vazia. Persista favoritos localmente, valide entradas e explique uma requisição no painel Network.",
      "requires": [],
      "resourceIds": [
        "resource.js",
        "resource.fetch"
      ],
      "kind": "criteria",
      "legacyIds": [
        "Aplicação com API-Critérios de conclusão",
        "Critérios de conclusão-Aplicação com API"
      ]
    },
    "frontend.aplicacao-com-api.ai-practice": {
      "id": "frontend.aplicacao-com-api.ai-practice",
      "groupId": "frontend.aplicacao-com-api",
      "title": "Prática de IA neste projeto",
      "description": "Implemente em parceria uma etapa pequena e compare com sua própria solução. Adapte o prompt ao que você já construiu nesta etapa. Altere uma regra de layout ou validação e explique o resultado antes de consultar a IA.",
      "requires": [
        "frontend.aplicacao-com-api.criteria"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "kind": "practice",
      "ai": "assisted",
      "prompt": "Projeto: Aplicação com API.\nObjetivo: revisar um componente de interface e propor uma melhoria pequena de semântica, responsividade ou tratamento de erro.\nContexto: [arquivos da interface que já existirem, comportamento esperado e problema observado].\nNesta etapa: Implemente em parceria uma etapa pequena e compare com sua própria solução.\nLimites: apenas este projeto de laboratório; use as ferramentas já escolhidas, dados públicos ou sintéticos e não exponha segredos.\nCritérios: funciona em celular e desktop, pelo teclado, com carregamento, erro e lista vazia quando aplicáveis.\nMostre as hipóteses e como verificá-las. Informe o que foi executado e o que ainda falta conferir.",
      "legacyIds": [
        "Aplicação com API-Prática de IA neste projeto",
        "Prática de IA neste projeto-Aplicação com API"
      ]
    },
    "frontend.aplicacao-com-api.verification": {
      "id": "frontend.aplicacao-com-api.verification",
      "groupId": "frontend.aplicacao-com-api",
      "title": "Registre sua verificação",
      "description": "Registre um prompt sanitizado, uma sugestão aceita ou corrigida, a verificação executada e seu resultado. Explique a mudança com suas palavras. Conclua o projeto após demonstrar os critérios, mesmo quando parte do código vier de IA.",
      "requires": [
        "frontend.aplicacao-com-api.criteria"
      ],
      "resourceIds": [
        "resource.git",
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "assisted",
      "legacyIds": [
        "Aplicação com API-Registre sua verificação",
        "Registre sua verificação-Aplicação com API"
      ]
    },
    "frontend.aplicacao-com-api.deepening": {
      "id": "frontend.aplicacao-com-api.deepening",
      "groupId": "frontend.aplicacao-com-api",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Aplicação com API no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.aplicacao-com-api.criteria",
        "frontend.aplicacao-com-api.ai-practice",
        "frontend.aplicacao-com-api.verification"
      ],
      "resourceIds": [
        "resource.js",
        "resource.fetch",
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices",
        "resource.git",
        "resource.ai"
      ],
      "legacyIds": []
    },
    "curriculum.typescript.basics": {
      "id": "curriculum.typescript.basics",
      "groupId": "curriculum.typescript",
      "title": "O básico",
      "description": "",
      "requires": [
        "curriculum.javascript.basics"
      ],
      "resourceIds": [
        "resource.ts",
        "resource.youtubeBranasTs",
        "resource.youtubeRocketseatTs"
      ],
      "kind": "concept",
      "legacyIds": [
        "TypeScript-O básico",
        "O básico-TypeScript"
      ]
    },
    "curriculum.typescript.practice": {
      "id": "curriculum.typescript.practice",
      "groupId": "curriculum.typescript",
      "title": "Pratique e confira",
      "description": "Tipifique os dados do projeto sem any e valide a resposta de uma API antes de usá-la. Peça à IA que explique um erro de tipo e confira a correção com o compilador, preservando strict.",
      "requires": [
        "curriculum.typescript.basics"
      ],
      "resourceIds": [
        "resource.ts",
        "resource.youtubeBranasTs",
        "resource.youtubeRocketseatTs"
      ],
      "kind": "practice",
      "legacyIds": [
        "TypeScript-Pratique e confira",
        "Pratique e confira-TypeScript"
      ]
    },
    "curriculum.typescript.deepening": {
      "id": "curriculum.typescript.deepening",
      "groupId": "curriculum.typescript",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Modele estados de carregamento, sucesso e falha com uma union discriminada. Valide dados externos em tempo de execução e demonstre um caso que o compilador sozinho não detecta.",
      "requires": [
        "curriculum.typescript.basics",
        "curriculum.typescript.practice"
      ],
      "resourceIds": [
        "resource.ts",
        "resource.youtubeBranasTs",
        "resource.youtubeRocketseatTs"
      ],
      "legacyIds": []
    },
    "frontend.vite-pacotes-e-qualidade.basics": {
      "id": "frontend.vite-pacotes-e-qualidade.basics",
      "groupId": "frontend.vite-pacotes-e-qualidade",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.vite",
        "resource.node"
      ],
      "kind": "concept",
      "legacyIds": [
        "Vite, pacotes e qualidade-O básico",
        "O básico-Vite, pacotes e qualidade"
      ]
    },
    "frontend.vite-pacotes-e-qualidade.practice": {
      "id": "frontend.vite-pacotes-e-qualidade.practice",
      "groupId": "frontend.vite-pacotes-e-qualidade",
      "title": "Pratique e confira",
      "description": "Crie scripts de desenvolvimento, build e checagem de tipos. Reproduza a instalação a partir do lockfile.",
      "requires": [
        "frontend.vite-pacotes-e-qualidade.basics"
      ],
      "resourceIds": [
        "resource.vite",
        "resource.node"
      ],
      "kind": "practice",
      "legacyIds": [
        "Vite, pacotes e qualidade-Pratique e confira",
        "Pratique e confira-Vite, pacotes e qualidade"
      ]
    },
    "frontend.vite-pacotes-e-qualidade.deepening": {
      "id": "frontend.vite-pacotes-e-qualidade.deepening",
      "groupId": "frontend.vite-pacotes-e-qualidade",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Vite, pacotes e qualidade no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.vite-pacotes-e-qualidade.basics",
        "frontend.vite-pacotes-e-qualidade.practice"
      ],
      "resourceIds": [
        "resource.vite",
        "resource.node"
      ],
      "legacyIds": []
    },
    "frontend.componentes-com-react.basics": {
      "id": "frontend.componentes-com-react.basics",
      "groupId": "frontend.componentes-com-react",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.react",
        "resource.reactSetup",
        "resource.youtubeHoraDeCodarReact",
        "resource.youtubeRocketseatReact"
      ],
      "kind": "concept",
      "legacyIds": [
        "Componentes com React-O básico",
        "O básico-Componentes com React"
      ]
    },
    "frontend.componentes-com-react.practice": {
      "id": "frontend.componentes-com-react.practice",
      "groupId": "frontend.componentes-com-react",
      "title": "Pratique e confira",
      "description": "Recrie uma tela do catálogo com componentes pequenos e explique onde o estado deve ficar.",
      "requires": [
        "frontend.componentes-com-react.basics"
      ],
      "resourceIds": [
        "resource.react",
        "resource.reactSetup",
        "resource.youtubeHoraDeCodarReact",
        "resource.youtubeRocketseatReact"
      ],
      "kind": "practice",
      "legacyIds": [
        "Componentes com React-Pratique e confira",
        "Pratique e confira-Componentes com React"
      ]
    },
    "frontend.componentes-com-react.deepening": {
      "id": "frontend.componentes-com-react.deepening",
      "groupId": "frontend.componentes-com-react",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Componentes com React no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.componentes-com-react.basics",
        "frontend.componentes-com-react.practice"
      ],
      "resourceIds": [
        "resource.react",
        "resource.reactSetup",
        "resource.youtubeHoraDeCodarReact",
        "resource.youtubeRocketseatReact"
      ],
      "legacyIds": []
    },
    "frontend.componentes-com-angular.basics": {
      "id": "frontend.componentes-com-angular.basics",
      "groupId": "frontend.componentes-com-angular",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.angular",
        "resource.youtubeLoiane"
      ],
      "kind": "concept",
      "legacyIds": [
        "Componentes com Angular-O básico",
        "O básico-Componentes com Angular"
      ]
    },
    "frontend.componentes-com-angular.practice": {
      "id": "frontend.componentes-com-angular.practice",
      "groupId": "frontend.componentes-com-angular",
      "title": "Pratique e confira",
      "description": "Recrie uma tela do catálogo com componentes standalone e um serviço para os dados; explique onde o estado deve ficar.",
      "requires": [
        "frontend.componentes-com-angular.basics"
      ],
      "resourceIds": [
        "resource.angular",
        "resource.youtubeLoiane"
      ],
      "kind": "practice",
      "legacyIds": [
        "Componentes com Angular-Pratique e confira",
        "Pratique e confira-Componentes com Angular"
      ]
    },
    "frontend.componentes-com-angular.deepening": {
      "id": "frontend.componentes-com-angular.deepening",
      "groupId": "frontend.componentes-com-angular",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Componentes com Angular no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.componentes-com-angular.basics",
        "frontend.componentes-com-angular.practice"
      ],
      "resourceIds": [
        "resource.angular",
        "resource.youtubeLoiane"
      ],
      "legacyIds": []
    },
    "frontend.componentes-com-vue.basics": {
      "id": "frontend.componentes-com-vue.basics",
      "groupId": "frontend.componentes-com-vue",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.vue",
        "resource.youtubeTiagoMatos"
      ],
      "kind": "concept",
      "legacyIds": [
        "Componentes com Vue-O básico",
        "O básico-Componentes com Vue"
      ]
    },
    "frontend.componentes-com-vue.practice": {
      "id": "frontend.componentes-com-vue.practice",
      "groupId": "frontend.componentes-com-vue",
      "title": "Pratique e confira",
      "description": "Recrie uma tela do catálogo com componentes pequenos e explique onde o estado deve ficar.",
      "requires": [
        "frontend.componentes-com-vue.basics"
      ],
      "resourceIds": [
        "resource.vue",
        "resource.youtubeTiagoMatos"
      ],
      "kind": "practice",
      "legacyIds": [
        "Componentes com Vue-Pratique e confira",
        "Pratique e confira-Componentes com Vue"
      ]
    },
    "frontend.componentes-com-vue.deepening": {
      "id": "frontend.componentes-com-vue.deepening",
      "groupId": "frontend.componentes-com-vue",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Componentes com Vue no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.componentes-com-vue.basics",
        "frontend.componentes-com-vue.practice"
      ],
      "resourceIds": [
        "resource.vue",
        "resource.youtubeTiagoMatos"
      ],
      "legacyIds": []
    },
    "frontend.testes-de-interface.basics": {
      "id": "frontend.testes-de-interface.basics",
      "groupId": "frontend.testes-de-interface",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.vitest",
        "resource.testingLibrary",
        "resource.playwright"
      ],
      "kind": "concept",
      "legacyIds": [
        "Testes de interface-O básico",
        "O básico-Testes de interface"
      ]
    },
    "frontend.testes-de-interface.practice": {
      "id": "frontend.testes-de-interface.practice",
      "groupId": "frontend.testes-de-interface",
      "title": "Pratique e confira",
      "description": "Teste busca, uma falha de API e um formulário inválido; rode os testes em CI.",
      "requires": [
        "frontend.testes-de-interface.basics"
      ],
      "resourceIds": [
        "resource.vitest",
        "resource.testingLibrary",
        "resource.playwright"
      ],
      "kind": "practice",
      "legacyIds": [
        "Testes de interface-Pratique e confira",
        "Pratique e confira-Testes de interface"
      ]
    },
    "frontend.testes-de-interface.deepening": {
      "id": "frontend.testes-de-interface.deepening",
      "groupId": "frontend.testes-de-interface",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Testes de interface no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.testes-de-interface.basics",
        "frontend.testes-de-interface.practice"
      ],
      "resourceIds": [
        "resource.vitest",
        "resource.testingLibrary",
        "resource.playwright"
      ],
      "legacyIds": []
    },
    "frontend.desempenho-e-seguranca-web.basics": {
      "id": "frontend.desempenho-e-seguranca-web.basics",
      "groupId": "frontend.desempenho-e-seguranca-web",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.performance",
        "resource.security",
        "resource.actions"
      ],
      "kind": "concept",
      "legacyIds": [
        "Desempenho e segurança web-O básico",
        "O básico-Desempenho e segurança web"
      ]
    },
    "frontend.desempenho-e-seguranca-web.practice": {
      "id": "frontend.desempenho-e-seguranca-web.practice",
      "groupId": "frontend.desempenho-e-seguranca-web",
      "title": "Pratique e confira",
      "description": "Compare uma medição antes e depois da otimização e revise dados externos antes de inseri-los na página.",
      "requires": [
        "frontend.desempenho-e-seguranca-web.basics"
      ],
      "resourceIds": [
        "resource.performance",
        "resource.security",
        "resource.actions"
      ],
      "kind": "practice",
      "legacyIds": [
        "Desempenho e segurança web-Pratique e confira",
        "Pratique e confira-Desempenho e segurança web"
      ]
    },
    "frontend.desempenho-e-seguranca-web.deepening": {
      "id": "frontend.desempenho-e-seguranca-web.deepening",
      "groupId": "frontend.desempenho-e-seguranca-web",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Desempenho e segurança web no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.desempenho-e-seguranca-web.basics",
        "frontend.desempenho-e-seguranca-web.practice"
      ],
      "resourceIds": [
        "resource.performance",
        "resource.security",
        "resource.actions"
      ],
      "legacyIds": []
    },
    "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics": {
      "id": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
      "groupId": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.cursorRules",
        "resource.claudePractices",
        "resource.codexRules"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Instruções do projeto e escopo do agente-O básico",
        "O básico-Instruções do projeto e escopo do agente"
      ]
    },
    "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice": {
      "id": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice",
      "groupId": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente",
      "title": "Pratique e confira",
      "description": "Escreva instruções curtas com comandos reais do projeto. Peça uma alteração pequena e confira que as instruções foram usadas e que o diff respeita o escopo.",
      "requires": [
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics"
      ],
      "resourceIds": [
        "resource.cursorRules",
        "resource.claudePractices",
        "resource.codexRules"
      ],
      "kind": "practice",
      "ai": "focused",
      "legacyIds": [
        "Instruções do projeto e escopo do agente-Pratique e confira",
        "Pratique e confira-Instruções do projeto e escopo do agente"
      ]
    },
    "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.deepening": {
      "id": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.deepening",
      "groupId": "aiLearning.instrucoes-do-projeto-e-escopo-do-agente",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Instruções do projeto e escopo do agente no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.basics",
        "aiLearning.instrucoes-do-projeto-e-escopo-do-agente.practice"
      ],
      "resourceIds": [
        "resource.cursorRules",
        "resource.claudePractices",
        "resource.codexRules"
      ],
      "legacyIds": []
    },
    "aiLearning.validar-trabalho-gerado-por-ia.basics": {
      "id": "aiLearning.validar-trabalho-gerado-por-ia.basics",
      "groupId": "aiLearning.validar-trabalho-gerado-por-ia",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.claudePractices",
        "resource.ai",
        "resource.codexPrompts"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "Validar trabalho gerado por IA-O básico",
        "O básico-Validar trabalho gerado por IA"
      ]
    },
    "aiLearning.validar-trabalho-gerado-por-ia.practice": {
      "id": "aiLearning.validar-trabalho-gerado-por-ia.practice",
      "groupId": "aiLearning.validar-trabalho-gerado-por-ia",
      "title": "Pratique e confira",
      "description": "Revise uma proposta que parece correta, mas tem um caso-limite errado. Acrescente uma verificação independente, corrija e documente a evidência.",
      "requires": [
        "aiLearning.validar-trabalho-gerado-por-ia.basics"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.ai",
        "resource.codexPrompts"
      ],
      "kind": "practice",
      "ai": "focused",
      "legacyIds": [
        "Validar trabalho gerado por IA-Pratique e confira",
        "Pratique e confira-Validar trabalho gerado por IA"
      ]
    },
    "aiLearning.validar-trabalho-gerado-por-ia.deepening": {
      "id": "aiLearning.validar-trabalho-gerado-por-ia.deepening",
      "groupId": "aiLearning.validar-trabalho-gerado-por-ia",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de Validar trabalho gerado por IA no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "aiLearning.validar-trabalho-gerado-por-ia.basics",
        "aiLearning.validar-trabalho-gerado-por-ia.practice"
      ],
      "resourceIds": [
        "resource.claudePractices",
        "resource.ai",
        "resource.codexPrompts"
      ],
      "legacyIds": []
    },
    "frontend.produto-frontend.criteria": {
      "id": "frontend.produto-frontend.criteria",
      "groupId": "frontend.produto-frontend",
      "title": "Critérios de conclusão",
      "description": "Documente o problema, rode build e testes na CI, demonstre busca e erros pelo teclado e registre uma melhoria feita após feedback.",
      "requires": [],
      "resourceIds": [
        "resource.vite",
        "resource.playwright",
        "resource.actions"
      ],
      "kind": "criteria",
      "legacyIds": [
        "Produto frontend-Critérios de conclusão",
        "Critérios de conclusão-Produto frontend"
      ]
    },
    "frontend.produto-frontend.ai-practice": {
      "id": "frontend.produto-frontend.ai-practice",
      "groupId": "frontend.produto-frontend",
      "title": "Prática de IA neste projeto",
      "description": "Delegue uma tarefa pequena e revise o diff e a evidência de execução. Adapte o prompt ao que você já construiu nesta etapa. Altere uma regra de layout ou validação e explique o resultado antes de consultar a IA.",
      "requires": [
        "frontend.produto-frontend.criteria"
      ],
      "resourceIds": [
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices"
      ],
      "kind": "practice",
      "ai": "assisted",
      "prompt": "Projeto: Produto frontend.\nObjetivo: revisar um componente de interface e propor uma melhoria pequena de semântica, responsividade ou tratamento de erro.\nContexto: [arquivos da interface que já existirem, comportamento esperado e problema observado].\nNesta etapa: Delegue uma tarefa pequena e revise o diff e a evidência de execução.\nLimites: apenas este projeto de laboratório; use as ferramentas já escolhidas, dados públicos ou sintéticos e não exponha segredos.\nCritérios: funciona em celular e desktop, pelo teclado, com carregamento, erro e lista vazia quando aplicáveis.\nMostre as hipóteses e como verificá-las. Informe o que foi executado e o que ainda falta conferir.",
      "legacyIds": [
        "Produto frontend-Prática de IA neste projeto",
        "Prática de IA neste projeto-Produto frontend"
      ]
    },
    "frontend.produto-frontend.verification": {
      "id": "frontend.produto-frontend.verification",
      "groupId": "frontend.produto-frontend",
      "title": "Registre sua verificação",
      "description": "Registre um prompt sanitizado, uma sugestão aceita ou corrigida, a verificação executada e seu resultado. Explique a mudança com suas palavras. Conclua o projeto após demonstrar os critérios, mesmo quando parte do código vier de IA.",
      "requires": [
        "frontend.produto-frontend.criteria"
      ],
      "resourceIds": [
        "resource.git",
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "assisted",
      "legacyIds": [
        "Produto frontend-Registre sua verificação",
        "Registre sua verificação-Produto frontend"
      ]
    },
    "frontend.produto-frontend.deepening": {
      "id": "frontend.produto-frontend.deepening",
      "groupId": "frontend.produto-frontend",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Produto frontend no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.produto-frontend.criteria",
        "frontend.produto-frontend.ai-practice",
        "frontend.produto-frontend.verification"
      ],
      "resourceIds": [
        "resource.vite",
        "resource.playwright",
        "resource.actions",
        "resource.codexPrompts",
        "resource.cursorPrompts",
        "resource.claudePractices",
        "resource.git",
        "resource.ai"
      ],
      "legacyIds": []
    },
    "curriculum.portfolio-e-candidatura.basics": {
      "id": "curriculum.portfolio-e-candidatura.basics",
      "groupId": "curriculum.portfolio-e-candidatura",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.git",
        "resource.contribute"
      ],
      "kind": "concept",
      "legacyIds": [
        "Portfólio e candidatura-O básico",
        "O básico-Portfólio e candidatura"
      ]
    },
    "curriculum.portfolio-e-candidatura.practice": {
      "id": "curriculum.portfolio-e-candidatura.practice",
      "groupId": "curriculum.portfolio-e-candidatura",
      "title": "Pratique e confira",
      "description": "Peça feedback sobre um projeto, corrija uma issue e explique sua contribuição. Compare vagas de entrada e escolha uma lacuna concreta para estudar.",
      "requires": [
        "curriculum.portfolio-e-candidatura.basics"
      ],
      "resourceIds": [
        "resource.git",
        "resource.contribute"
      ],
      "kind": "practice",
      "legacyIds": [
        "Portfólio e candidatura-Pratique e confira",
        "Pratique e confira-Portfólio e candidatura"
      ]
    },
    "curriculum.portfolio-e-candidatura.deepening": {
      "id": "curriculum.portfolio-e-candidatura.deepening",
      "groupId": "curriculum.portfolio-e-candidatura",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Portfólio e candidatura no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "curriculum.portfolio-e-candidatura.basics",
        "curriculum.portfolio-e-candidatura.practice"
      ],
      "resourceIds": [
        "resource.git",
        "resource.contribute"
      ],
      "legacyIds": []
    },
    "curriculum.ia-no-fluxo-de-trabalho.basics": {
      "id": "curriculum.ia-no-fluxo-de-trabalho.basics",
      "groupId": "curriculum.ia-no-fluxo-de-trabalho",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.ai"
      ],
      "kind": "concept",
      "ai": "focused",
      "legacyIds": [
        "IA no fluxo de trabalho-O básico",
        "O básico-IA no fluxo de trabalho"
      ]
    },
    "curriculum.ia-no-fluxo-de-trabalho.practice": {
      "id": "curriculum.ia-no-fluxo-de-trabalho.practice",
      "groupId": "curriculum.ia-no-fluxo-de-trabalho",
      "title": "Pratique e confira",
      "description": "Compare uma sugestão de IA com sua solução, identifique uma limitação e teste a mudança. Explique o código sem depender da ferramenta.",
      "requires": [
        "curriculum.ia-no-fluxo-de-trabalho.basics"
      ],
      "resourceIds": [
        "resource.ai"
      ],
      "kind": "practice",
      "ai": "focused",
      "legacyIds": [
        "IA no fluxo de trabalho-Pratique e confira",
        "Pratique e confira-IA no fluxo de trabalho"
      ]
    },
    "curriculum.ia-no-fluxo-de-trabalho.deepening": {
      "id": "curriculum.ia-no-fluxo-de-trabalho.deepening",
      "groupId": "curriculum.ia-no-fluxo-de-trabalho",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "ai": "focused",
      "description": "Escolha uma decisão de IA no fluxo de trabalho no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "curriculum.ia-no-fluxo-de-trabalho.basics",
        "curriculum.ia-no-fluxo-de-trabalho.practice"
      ],
      "resourceIds": [
        "resource.ai"
      ],
      "legacyIds": []
    },
    "frontend.renderizacao-design-system-e-css-avancado.basics": {
      "id": "frontend.renderizacao-design-system-e-css-avancado.basics",
      "groupId": "frontend.renderizacao-design-system-e-css-avancado",
      "title": "O básico",
      "description": "",
      "requires": [],
      "resourceIds": [
        "resource.next",
        "resource.css",
        "resource.curriculum",
        "resource.youtubeRocketseatTailwind",
        "resource.youtubeHoraDeCodarCss"
      ],
      "kind": "concept",
      "legacyIds": [
        "Renderização, design system e CSS avançado-O básico",
        "O básico-Renderização, design system e CSS avançado"
      ]
    },
    "frontend.renderizacao-design-system-e-css-avancado.practice": {
      "id": "frontend.renderizacao-design-system-e-css-avancado.practice",
      "groupId": "frontend.renderizacao-design-system-e-css-avancado",
      "title": "Pratique e confira",
      "description": "Justifique a estratégia de renderização de uma página e implemente uma melhoria mensurável.",
      "requires": [
        "frontend.renderizacao-design-system-e-css-avancado.basics"
      ],
      "resourceIds": [
        "resource.next",
        "resource.css",
        "resource.curriculum",
        "resource.youtubeRocketseatTailwind",
        "resource.youtubeHoraDeCodarCss"
      ],
      "kind": "practice",
      "legacyIds": [
        "Renderização, design system e CSS avançado-Pratique e confira",
        "Pratique e confira-Renderização, design system e CSS avançado"
      ]
    },
    "frontend.renderizacao-design-system-e-css-avancado.deepening": {
      "id": "frontend.renderizacao-design-system-e-css-avancado.deepening",
      "groupId": "frontend.renderizacao-design-system-e-css-avancado",
      "title": "Desafio de aprofundamento",
      "kind": "challenge",
      "description": "Escolha uma decisão de Renderização, design system e CSS avançado no seu projeto. Construa uma segunda solução, compare os resultados com um caso de teste e explique os limites de cada abordagem. Use as referências para verificar sua conclusão.",
      "requires": [
        "frontend.renderizacao-design-system-e-css-avancado.basics",
        "frontend.renderizacao-design-system-e-css-avancado.practice"
      ],
      "resourceIds": [
        "resource.next",
        "resource.css",
        "resource.curriculum",
        "resource.youtubeRocketseatTailwind",
        "resource.youtubeHoraDeCodarCss"
      ],
      "legacyIds": []
    }
  },
  "resources": {
    "resource.web": {
      "id": "resource.web",
      "title": "MDN: como a web funciona (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Learn_web_development/Getting_started/Web_standards/How_the_web_works",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.http": {
      "id": "resource.http",
      "title": "MDN: HTTP (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/HTTP",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeDeschampsWeb": {
      "id": "resource.youtubeDeschampsWeb",
      "title": "Filipe Deschamps: como a internet funciona e APIs (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/FilipeDeschamps",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeCodigoFonte": {
      "id": "resource.youtubeCodigoFonte",
      "title": "Código Fonte TV: Dicionário do Programador (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/codigofontetv",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.git": {
      "id": "resource.git",
      "title": "Pro Git: livro gratuito (português)",
      "url": "https://git-scm.com/book/pt-br/v2",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.contribute": {
      "id": "resource.contribute",
      "title": "GitHub: como contribuir com projetos (português)",
      "url": "https://docs.github.com/pt/get-started/exploring-projects-on-github/contributing-to-a-project",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeGitJusten": {
      "id": "resource.youtubeGitJusten",
      "title": "Willian Justen: Git e GitHub para iniciantes (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLlAbYrWSYTiPA2iEiQ2PF_A9j__C4hi0A",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeGitCourse": {
      "id": "resource.youtubeGitCourse",
      "title": "Curso em Vídeo: Git e GitHub (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLHz_AreHm4dm7ZULPAmadvNhH6vk9oNZA",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.cursor": {
      "id": "resource.cursor",
      "title": "Cursor: uso do agente (inglês; documentação gratuita)",
      "url": "https://cursor.com/docs/agent/overview",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.cursorPrompts": {
      "id": "resource.cursorPrompts",
      "title": "Cursor: prompts e contexto (inglês; documentação gratuita)",
      "url": "https://cursor.com/docs/agent/prompting",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.claude": {
      "id": "resource.claude",
      "title": "Claude Code: primeiros passos (inglês; documentação gratuita)",
      "url": "https://code.claude.com/docs/en/quickstart",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.claudePractices": {
      "id": "resource.claudePractices",
      "title": "Claude Code: boas práticas (inglês; documentação gratuita)",
      "url": "https://code.claude.com/docs/en/best-practices",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.codex": {
      "id": "resource.codex",
      "title": "OpenAI: primeiros passos com Codex (inglês; documentação gratuita)",
      "url": "https://developers.openai.com/codex/quickstart/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.codexPrompts": {
      "id": "resource.codexPrompts",
      "title": "OpenAI: prompting para tarefas de código (inglês; documentação gratuita)",
      "url": "https://developers.openai.com/codex/prompting/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.ai": {
      "id": "resource.ai",
      "title": "GitHub: uso responsável de sugestões de IA (português)",
      "url": "https://docs.github.com/pt/copilot/responsible-use/copilot-code-completion",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.htmlCourse": {
      "id": "resource.htmlCourse",
      "title": "Curso em Vídeo: HTML e CSS, módulo 1 (português; conteúdo gratuito, certificado opcional pago)",
      "url": "https://www.cursoemvideo.com/curso/html5-css3-modulo1/",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.html": {
      "id": "resource.html",
      "title": "MDN: HTML (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/HTML",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeHtmlCourse": {
      "id": "resource.youtubeHtmlCourse",
      "title": "Curso em Vídeo: HTML5 completo (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLHz_AreHm4dlAnJ_jJtV29RFxnPHDuk9o",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.css": {
      "id": "resource.css",
      "title": "MDN: CSS (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/CSS",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeCssCourse": {
      "id": "resource.youtubeCssCourse",
      "title": "Curso em Vídeo: HTML5 e CSS3, módulo 2 (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLHz_AreHm4dlUpEXkY1AyVLQGcpSgVF8s",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeOrigamid": {
      "id": "resource.youtubeOrigamid",
      "title": "Origamid: CSS avançado e interfaces (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/Origamid",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.accessibility": {
      "id": "resource.accessibility",
      "title": "MDN: acessibilidade (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/Accessibility",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.pages": {
      "id": "resource.pages",
      "title": "GitHub Pages: publicação de um site (português)",
      "url": "https://docs.github.com/pt/pages/getting-started-with-github-pages/creating-a-github-pages-site",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.jsCourse": {
      "id": "resource.jsCourse",
      "title": "Curso em Vídeo: JavaScript (português; conteúdo gratuito, certificado opcional pago)",
      "url": "https://www.cursoemvideo.com/curso/javascript/",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.js": {
      "id": "resource.js",
      "title": "MDN: guia de JavaScript (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Guide",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.fetch": {
      "id": "resource.fetch",
      "title": "MDN: usando Fetch (português)",
      "url": "https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API/Using_Fetch",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeJsCourse": {
      "id": "resource.youtubeJsCourse",
      "title": "Curso em Vídeo: JavaScript para iniciantes (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLHz_AreHm4dlsK3Nr9GVvXCbpQyHQl1o1",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeHoraDeCodarJs": {
      "id": "resource.youtubeHoraDeCodarJs",
      "title": "Hora de Codar: JavaScript e projetos (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLnDvRpP8BneysKU8KivhnrVaKpILD3gZ6",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.ts": {
      "id": "resource.ts",
      "title": "TypeScript: handbook (inglês)",
      "url": "https://www.typescriptlang.org/docs/handbook/intro.html",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeBranasTs": {
      "id": "resource.youtubeBranasTs",
      "title": "Rodrigo Branas: masterclass de TypeScript (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/RodrigoBranas",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeRocketseatTs": {
      "id": "resource.youtubeRocketseatTs",
      "title": "Rocketseat: TypeScript na prática (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/rocketseat",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.vite": {
      "id": "resource.vite",
      "title": "Vite: primeiros passos (português)",
      "url": "https://pt.vite.dev/guide/",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.node": {
      "id": "resource.node",
      "title": "Node.js: introdução (inglês)",
      "url": "https://nodejs.org/en/learn/getting-started/introduction-to-nodejs",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.react": {
      "id": "resource.react",
      "title": "React: aprenda React (português)",
      "url": "https://pt-br.react.dev/learn",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.reactSetup": {
      "id": "resource.reactSetup",
      "title": "React: criar um projeto (português)",
      "url": "https://pt-br.react.dev/learn/creating-a-react-app",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeHoraDeCodarReact": {
      "id": "resource.youtubeHoraDeCodarReact",
      "title": "Hora de Codar: curso de React (português; playlist gratuita no YouTube)",
      "url": "https://www.youtube.com/playlist?list=PLnDvRpP8BneyVA0SZ2okm-QBojomniQVO",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeRocketseatReact": {
      "id": "resource.youtubeRocketseatReact",
      "title": "Rocketseat: ecossistema React e Next.js (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/rocketseat",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.angular": {
      "id": "resource.angular",
      "title": "Angular: tutorial interativo (inglês)",
      "url": "https://angular.dev/tutorials/learn-angular",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeLoiane": {
      "id": "resource.youtubeLoiane",
      "title": "Loiane Groner: curso completo de Angular (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/loianegroner",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.vue": {
      "id": "resource.vue",
      "title": "Vue.js: introdução (inglês)",
      "url": "https://vuejs.org/guide/introduction.html",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeTiagoMatos": {
      "id": "resource.youtubeTiagoMatos",
      "title": "Tiago Matos: cursos de Vue.js (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/tiagomatosweb",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.vitest": {
      "id": "resource.vitest",
      "title": "Vitest: primeiros passos (inglês)",
      "url": "https://vitest.dev/guide/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.testingLibrary": {
      "id": "resource.testingLibrary",
      "title": "Testing Library: testes centrados no usuário (inglês)",
      "url": "https://testing-library.com/docs/react-testing-library/intro/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.playwright": {
      "id": "resource.playwright",
      "title": "Playwright: testes de ponta a ponta (inglês)",
      "url": "https://playwright.dev/docs/intro",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.performance": {
      "id": "resource.performance",
      "title": "web.dev: métricas de desempenho (português)",
      "url": "https://web.dev/articles/vitals?hl=pt-br",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.security": {
      "id": "resource.security",
      "title": "OWASP: guia de segurança de aplicações (inglês)",
      "url": "https://cheatsheetseries.owasp.org/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.actions": {
      "id": "resource.actions",
      "title": "GitHub Actions: integração contínua (português)",
      "url": "https://docs.github.com/pt/actions/get-started/continuous-integration",
      "language": "pt-BR",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.cursorRules": {
      "id": "resource.cursorRules",
      "title": "Cursor: regras do projeto (inglês; documentação gratuita)",
      "url": "https://cursor.com/docs/rules",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.codexRules": {
      "id": "resource.codexRules",
      "title": "OpenAI: instruções de projeto com AGENTS.md (inglês; documentação gratuita)",
      "url": "https://developers.openai.com/codex/guides/agents-md/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.next": {
      "id": "resource.next",
      "title": "Next.js: curso oficial de aplicação completa (inglês)",
      "url": "https://nextjs.org/learn",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.curriculum": {
      "id": "resource.curriculum",
      "title": "MDN: currículo de desenvolvimento web (inglês)",
      "url": "https://developer.mozilla.org/en-US/curriculum/",
      "language": "en",
      "kind": "Leia",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeRocketseatTailwind": {
      "id": "resource.youtubeRocketseatTailwind",
      "title": "Rocketseat: projetos com Tailwind CSS (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/c/rocketseat",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    },
    "resource.youtubeHoraDeCodarCss": {
      "id": "resource.youtubeHoraDeCodarCss",
      "title": "Hora de Codar: Bootstrap e Tailwind (português; vídeos gratuitos no YouTube)",
      "url": "https://www.youtube.com/@MatheusBattisti",
      "language": "pt-BR",
      "kind": "Assista",
      "free": true,
      "estimatedMinutes": null,
      "lastReviewedAt": null
    }
  }
}