Skip to content

adeondev/terra-roxa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Logotipo do Terra Roxa

Terra Roxa

Site feito para o agrinho, sobre agricultura sustentável, desenvolvido em 2026 com HTML, CSS e JavaScript.

HTML5 estático CSS3 design system JavaScript vanilla Sem backend


Sumário

  1. Sobre o projeto
  2. O concurso e o que o regulamento exige
  3. A regra que guia todo o projeto: sem servidor, sem biblioteca, sem nada
  4. Tecnologias e APIs do navegador
  5. Como abrir e usar o site
  6. Estrutura de pastas
  7. Como o front-end está organizado
  8. Componentes globais
  9. Design system
  10. Acessibilidade
  11. Modo escuro
  12. Página inicial
  13. Aprender
  14. Quizzes
  15. Analisar e Capturar
  16. Resultados — o simulador de talhão
  17. Jogo — Lavoura em Equilíbrio
  18. Glossário
  19. Agrinho
  20. Dados salvos no navegador
  21. Escopo educativo e limitações
  22. Privacidade e segurança
  23. Guia de manutenção
  24. Roteiro de testes
  25. Créditos e fontes

1. Sobre o projeto

O Terra Roxa é um site educativo que criei, que apresenta de forma interativa a ideia de uma agricultura que mostra cuidados sobre produção e meio ambiente, criando um agro forte, que por sua vez, gera uma cultura sustentável. Ele reúne conteúdos de leituras, quizzes, análise visual automática de folhas de feijão e milho, um simulador do seu próprio campo em pixel art e um mini-game.

Todos esses pensados para explicar conceitos de campo de um jeito educativo e simples!

O objetivo é organizar esse conteúdo em um site estático, que funciona só com o navegador, sem servidor, banco de dados ou etapa de instalação. A proposta não é representar um sistema agrícola real nem substituir orientação técnica... É oferecer um material de estudo e demonstração construído inteiramente com tecnologias de front-end. E claro, para o agrinho! :)


2. O concurso e o que o regulamento exige

Eu desenvolvi o Terra Roxa para o Concurso Agrinho 2026, promovido pelo SENAR-PR e pela SEED-PR, na categoria de Programação — mais precisamente na Subcategoria 3: Programação Front-End (HTML, CSS e JavaScript), voltada a estudantes do Ensino Médio da rede pública do Paraná.

O tema proposto pelo concurso é:

Agro forte, futuro sustentável: equilíbrio entre produção e meio ambiente.

Todo o conteúdo do site gira em torno desse tema. As trilhas de estudo, os quizzes, a análise de folhas, o simulador e o jogo abordam aspectos do equilíbrio entre produzir alimentos e preservar solo, água e biodiversidade, sempre com linguagem voltada ao público escolar.

O regulamento da Subcategoria 3 traz regras técnicas bem específicas, e elas guiaram boa parte das minhas decisões. Por isso, deixei registrado abaixo cada uma delas e como procurei atendê-la:

Exigência do regulamento Como o Terra Roxa atende
Usar somente HTML, CSS e JavaScript O site inteiro usa apenas essas três linguagens, sem nenhuma outra.
Não utilizar frameworks Não há React, Vue, jQuery, Bootstrap nem qualquer biblioteca. Tudo é escrito à mão.
Sem CSS ou JavaScript embutido (inline) no HTML Estilos e scripts ficam em arquivos .css e .js, sempre declarados nos HTML.
Repositório público com todos os arquivos para rodar Todo o HTML, CSS, JS e as mídias estão versionados no repositório.
README com instruções de uso, lista de tecnologias e o objetivo do tema Estão nas seções 5, 4 e 1–2 deste documento, respectivamente.
Código identado, com comentários breves nas funções JS O código segue indentação consistente e comenta os trechos centrais.
Mídias organizadas em pastas próprias Imagens em public/images/, ícones em icons/, fontes em public/fonts/.
Sem erros no console e com todos os caminhos funcionando Os caminhos são relativos e resolvidos com cuidado (ver seção 8).

Há ainda duas exigências que pertencem à configuração do repositório, e não ao código em si, mas que valem o registro porque a rubrica as pontua: a etiqueta (topic) oficial agrinho precisa estar configurada nos topics do repositório no GitHub, e o link do GitHub Pages (ou Vercel) onde o site está publicado deve estar declarado e funcional no campo About.


3. A regra que guia todo o projeto: sem servidor, sem biblioteca, sem nada

Mais do que uma regra a cumprir, fazer tudo sem dependências virou o princípio que guiou o projeto inteiro. Como quase toda decisão que tomei nasce daqui, vale explicar o que isso significa na prática.

Não há servidor nem back-end. Nenhuma parte do site precisa de um processo rodando do outro lado. Não existe API própria, rota, endpoint ou camada de servidor. Abrir o index.html é suficiente para o site funcionar por inteiro.

Não há banco de dados. Nada é gravado em um banco externo. Quando o site precisa lembrar de alguma coisa — o progresso de uma trilha, a melhor pontuação do jogo, as preferências de acessibilidade —, ele usa o localStorage do próprio navegador, que vive na máquina de quem está usando. Os dados ficam ali e não saem dali (ver seção 20).

Não há framework nem biblioteca. Não usei React, Vue, Angular, jQuery, Bootstrap, Tailwind, D3 nem nenhum outro pacote. Tudo o que normalmente a gente joga para uma biblioteca, resolvi com os próprios recursos do navegador: componentes reusáveis viraram Web Components, os gráficos e o mapa do simulador são desenhados na Canvas API, as animações usam CSS e a Web Animations API, e a leitura por voz usa a Web Speech API. Não foi por purismo: o regulamento veda frameworks, e o resultado acabou sendo um projeto leve, sem etapa de build e sem código de terceiros para auditar.

Não há etapa de instalação ou compilação. Não existe package.json, node_modules, bundler, transpilador ou comando obrigatório. O que está no repositório é exatamente o que roda no navegador. Isso torna o projeto fácil de publicar (basta servir os arquivos) e fácil de inspecionar (o código não é minificado nem gerado).

Não há dependência de CDN. Fontes e ícones são servidos localmente, a partir das pastas do próprio projeto. Não há <link> ou <script> apontando para servidores externos. Em consequência, o site funciona mesmo offline, depois de aberto.

O quadro abaixo resume as escolhas que substituíram as dependências usuais:

No lugar de… O Terra Roxa usa…
Um framework de componentes Web Components nativos (<terra-header>, <terra-accessibility>)
Um banco de dados / login localStorage no navegador
Uma biblioteca de gráficos Desenho manual na Canvas API
Uma CDN de fontes/ícones Arquivos locais em public/ e icons/
Um bundler e cache de build Páginas separadas e cache busting por query string

4. Tecnologias e APIs do navegador

Tudo o que usei é nativo do navegador — não há nada para instalar.

  • HTML5 — a estrutura semântica de cada página, com tags como header, nav, main, section, article e footer.
  • CSS3 — layout (Flexbox e Grid), responsividade com media queries, tema, animações e o design system inteiro baseado em variáveis (custom properties).
  • JavaScript (ES) puro — toda a interatividade e a lógica das páginas, organizada em um arquivo por página mais dois componentes compartilhados.
  • Web Components / Custom Elements — o cabeçalho e o painel de acessibilidade são elementos customizados (<terra-header> e <terra-accessibility>), reaproveitados em todas as páginas sem repetição de HTML.
  • Canvas API — usada para ler os pixels da imagem na análise de folhas e para desenhar o mapa em pixel art do simulador de talhão, seu minimapa e os efeitos do jogo.
  • Web Animations API — anima aberturas e transições (como o acordeão do FAQ) de um jeito que respeita a opção de reduzir movimento.
  • Web Speech API (SpeechSynthesis) — lê em voz alta o conteúdo apontado, quando o navegador oferece suporte.
  • MediaDevices / getUserMedia — acessa a câmera na página de captura, quando o usuário autoriza.
  • localStorage — guarda progresso, preferências e históricos no próprio navegador.
  • IntersectionObserver — dispara animações (como os contadores da home) só quando o elemento entra na tela.
  • Fontes WOFF2 e ícones SVG locais — incluindo a fonte OpenDyslexic, carregada da pasta do projeto.

Uma observação que o regulamento cobra explicitamente: scripts e folhas de estilo são sempre declarados nos arquivos HTML por meio de <link> e <script>. Não há CSS em atributos style nem JavaScript embutido nas páginas.


5. Como abrir e usar o site

Por ser um site estático, não há instalação, dependências ou build. Há duas formas de abrir.

Forma mais simples — abrir o arquivo:

1. baixe ou clone a pasta do projeto
2. dê um duplo clique em index.html (ou arraste-o para o navegador)
3. navegue pelas páginas usando o menu no topo

Forma recomendada — servir por um servidor estático local. Abrir via file:// funciona para quase tudo, mas alguns recursos do navegador (como o acesso à câmera) só são liberados em http:// ou https://. Se você tiver o Python instalado, um servidor local resolve, sem instalar nada além disso:

# dentro da pasta do projeto
python -m http.server 8000
# depois acesse http://localhost:8000 no navegador

O site também funciona publicado em qualquer hospedagem de arquivos estáticos, como o GitHub Pages ou a Vercel — que são, aliás, as opções previstas pelo regulamento.

Sobre a câmera: na página de análise, a captura por câmera só é ativada quando o navegador autoriza o acesso. Se a câmera estiver bloqueada ou indisponível, a própria página oferece o envio de uma foto como alternativa, de modo que nada se perde e tudo continua dentro do escopo estático.


6. Estrutura de pastas

terra-roxa/
├── index.html              página inicial
├── README.md               este documento
│
├── agrinho/                página sobre o programa Agrinho
│   └── index.html
├── analisar/               entrada da análise visual
│   ├── index.html
│   └── capturar/           captura, upload e resultado da análise
│       └── index.html
├── aprendizado/            trilhas de estudo
│   └── index.html
├── glossario/              consulta de termos técnicos
│   └── index.html
├── jogo/                   mini-game "Lavoura em Equilíbrio"
│   └── index.html
├── quizzes/                quizzes de revisão
│   └── index.html
├── resultados/             simulador de talhão
│   └── index.html
│
├── css/
│   ├── style.css           base visual e componentes globais
│   ├── theme-dark.css      ajustes do modo escuro
│   ├── pages/              um arquivo de estilo por página
│   │   ├── agrinho.css
│   │   ├── analisar.css
│   │   ├── aprendizado.css
│   │   ├── glossario.css
│   │   ├── jogo.css
│   │   ├── quizzes.css
│   │   └── resultados.css
│   └── sections/           seções reutilizadas (FAQ, rodapé, próximos passos)
│       ├── faq.css
│       ├── footer.css
│       └── next-actions.css
│
├── js/
│   ├── components/         Web Components globais
│   │   ├── site-header.js
│   │   └── accessibility-dock.js
│   ├── main.js             interações da página inicial
│   ├── courses.js          dados das trilhas de estudo
│   ├── aprendizado.js      interface e progresso das trilhas
│   ├── quizzes.js          lógica dos quizzes
│   ├── analisar.js         entrada e histórico da análise
│   ├── detector.js         fluxo de captura, upload e resultado
│   ├── leaf-vision.js      classificador de cores da folha
│   ├── diagnostics-data.js textos das condições da folha
│   ├── analise-historico.js histórico local das análises
│   ├── resultados.js       simulador de talhão
│   ├── jogo.js             motor do mini-game
│   ├── glossario-data.js   base de 1.200 termos do glossário
│   ├── glossario.js        busca e lista virtualizada
│   └── agrinho.js          interações da página Agrinho
│
├── icons/                  76 ícones em SVG
└── public/
    ├── fonts/              fontes locais (inclui a OpenDyslexic e sua licença)
    └── images/             60 imagens, organizadas por seção

Em números redondos, são 9 páginas HTML, 12 arquivos CSS, 16 arquivos JavaScript, 60 imagens e 76 ícones. As mídias ficam sempre separadas em pastas próprias, como o regulamento pede.


7. Como o front-end está organizado

Organizei tudo seguindo uma ideia simples, repetida em todas as páginas: um HTML por página, estilos globais separados dos estilos específicos, e um script dedicado para cada página, somados a dois componentes que aparecem em todas elas.

Separação de responsabilidades. Cada página carrega a base (style.css), os ajustes de tema (theme-dark.css) e, quando precisa, seu CSS específico em css/pages/. No JavaScript, a regra é a mesma: o que é global vem dos componentes em js/components/, e o resto fica no script daquela página.

Dados fora da lógica. Os conteúdos mais volumosos não ficam embutidos no HTML nem misturados ao código que os exibe. As trilhas de estudo vivem em courses.js, os 1.200 termos do glossário em glossario-data.js e os textos das condições da folha em diagnostics-data.js. Cada um desses arquivos publica seus dados em um objeto global (window.TerraRoxaCourses, window.TerraDiagnostics, etc.), que o script da página consome. Assim, atualizar conteúdo é mexer em dados, não em lógica.

Relação entre páginas, scripts e estilos:

Página Caminho Script(s) principal(is) CSS específico
Início index.html main.js seções faq, next-actions, footer
Aprender aprendizado/index.html courses.js, aprendizado.js pages/aprendizado.css
Quizzes quizzes/index.html courses.js, quizzes.js pages/quizzes.css
Analisar analisar/index.html (componentes globais) pages/analisar.css
Capturar analisar/capturar/index.html leaf-vision.js, diagnostics-data.js, analise-historico.js, detector.js, analisar.js pages/analisar.css
Resultados resultados/index.html resultados.js pages/resultados.css
Jogo jogo/index.html jogo.js pages/jogo.css
Glossário glossario/index.html glossario-data.js, glossario.js pages/glossario.css
Agrinho agrinho/index.html agrinho.js pages/agrinho.css

Em todas as páginas estão presentes os dois scripts globais — site-header.js e accessibility-dock.js — e as folhas de estilo base.

Cache busting. Para garantir que o navegador não reutilize uma versão antiga de um arquivo do cache, os CSS e JS são carregados com uma query string de versão, como style.css?v=... ou quizzes.js?v=.... Quando um arquivo importante muda, basta atualizar esse número no HTML correspondente para forçar o recarregamento. É uma técnica manual e sem ferramentas — coerente com a proposta sem build.


8. Componentes globais

Para não copiar o mesmo cabeçalho e o mesmo painel de acessibilidade em nove páginas, escrevi essas duas partes como Web Components — elementos HTML customizados, recurso nativo do navegador. Cada página só declara a tag; o componente cuida do resto.

<terra-header> — o cabeçalho (js/components/site-header.js)

Este componente monta o cabeçalho e o menu de navegação. Ele tem duas particularidades que resolvem problemas comuns de um site com páginas em subpastas:

  • Caminhos relativos corretos. Como as páginas vivem em subpastas de profundidades diferentes (quizzes/ está um nível abaixo da raiz; analisar/capturar/ está dois), um link fixo quebraria em algumas delas. O componente descobre a raiz do site a partir da própria URL do script e resolve cada link a partir dela, então o menu funciona igual em qualquer página.
  • Página ativa em destaque. Cada página declara qual item está ativo, e o componente marca esse item com aria-current="page", o que ajuda tanto visualmente quanto para leitores de tela.

O uso na página é direto:

<terra-header active="home"></terra-header>

O atributo active aceita um destes valores, conforme a página: home, aprendizado, quizzes, ia (Analisar), resultados, jogo, glossario ou agrinho. O componente ainda cuida do menu sanfona no mobile, fechando-o ao clicar fora ou ao escolher um link.

<terra-accessibility> — o painel de acessibilidade (js/components/accessibility-dock.js)

Este componente desenha o painel lateral de acessibilidade e aplica as preferências escolhidas. Um detalhe de implementação importante: o estado salvo é lido e aplicado antes de a tela aparecer, ainda no carregamento do script, para que a página não "pisque" no tema claro antes de trocar para o escuro, por exemplo.

As preferências são guardadas no localStorage, sob a chave terra-roxa-accessibility, e cada uma aplica uma classe no documento que o CSS usa para ajustar a aparência. A seção 10 detalha os recursos. O uso na página é igualmente simples:

<terra-accessibility></terra-accessibility>

9. Design system

A base visual fica em css/style.css, e montei tudo sobre variáveis CSS declaradas em :root. Centralizar cores, espaçamentos, tipografia e tempos de animação em um só lugar mantém o site consistente e facilita ajustes — inclusive o modo escuro, que só precisa redefinir algumas dessas variáveis.

:root {
  /* cores */
  --color-primary: #43215c;        /* roxo principal */
  --color-primary-light: #68417f;  /* roxo claro */
  --color-accent-yellow: #d99b37;  /* dourado de destaque */
  --color-accent-green: #748b58;   /* verde principal */
  --color-accent-dark-green: #4e6544;
  --color-accent-clay: #b96b50;    /* tom terroso */

  /* fundos e textos */
  --color-bg-main: #f7f0e8;
  --color-bg-card: #fff9ef;
  --color-bg-soft: #efe4d9;
  --color-text-main: #43215c;
  --color-text-muted: #725e77;
  --color-text-light: #ffffff;
}

Os tokens estão agrupados por finalidade:

Cores. Roxo principal e sua variação clara, dourado de destaque, dois tons de verde, um tom terroso (clay), três fundos (principal, cards e secundário) e três cores de texto (principal, secundário e claro sobre fundo escuro). Há também versões -rgb de algumas cores, usadas quando o CSS precisa aplicar transparência via rgba().

Ícones. Os ícones são SVGs monocromáticos coloridos por filter de CSS — há filtros prontos para tingi-los de roxo (--icon-filter-primary), verde (--icon-filter-green) ou branco (--icon-filter-light). Isso permite reaproveitar o mesmo arquivo de ícone em contextos de cores diferentes, inclusive no modo escuro.

Tipografia.

Token Uso
--font-family texto geral (Trebuchet MS / Segoe UI / Arial)
--font-family-display títulos (Georgia / Cambria, serifada)
--font-family-dyslexic fonte OpenDyslexic, usada no modo dislexia
--a11y-content-font-size tamanho do texto, controlado pela acessibilidade
--a11y-content-line-height altura de linha do conteúdo
--a11y-heading-line-height altura de linha dos títulos
--a11y-word-spacing espaçamento entre palavras

As variáveis com prefixo --a11y- são reescritas em tempo real pelo painel de acessibilidade, o que faz o site inteiro responder ao aumento de fonte e de espaçamento sem quebrar o layout.

Espaçamento, bordas e movimento.

Espaçamento Valor Bordas Valor Movimento Uso
--spacing-xs 0.5rem --radius-sm 8px --transition-fast transições rápidas (0.2s)
--spacing-sm 1rem --radius-md 16px --transition-micro microinterações (0.16s)
--spacing-md 1.5rem --radius-lg 24px --transition-normal transições padrão (0.3s)
--spacing-lg 2rem --radius-xl 40px
--spacing-xl 3rem --radius-full 9999px
--spacing-xxl 5rem

Sombras. O projeto opta por um visual mais "chapado": as variáveis de sombra (--shadow-sm, --shadow-md, etc.) ficam em none por padrão, e a separação entre elementos é feita com cor, borda e espaçamento em vez de sombras pesadas.

A fonte para dislexia é carregada localmente via @font-face, apontando para os arquivos OpenDyslexic-Regular.woff2 e OpenDyslexic-Bold.woff2 em public/fonts/ — sem CDN.


10. Acessibilidade

Não quis tratar a acessibilidade como um extra: ela faz parte do componente que acompanha todas as páginas. O painel <terra-accessibility> reúne os ajustes abaixo, todos aplicados no front-end e lembrados entre visitas:

  • Fonte maior — quatro níveis de tamanho (Normal, Maior, Grande, Extra), independentes do zoom geral do navegador.
  • Espaçamento — três níveis que ampliam, juntos, a altura de linha e o espaçamento entre palavras, ajudando na leitura.
  • Velocidade da narração — Normal, Lenta ou Rápida, para a leitura por voz.
  • Modo escuro — alterna o tema do site (ver seção 11).
  • Reduzir animações — minimiza ou desliga transições e efeitos, respeitando também a preferência prefers-reduced-motion do sistema.
  • Alto contraste — reforça o contraste de texto e elementos.
  • Fonte para dislexia — troca a tipografia pela OpenDyslexic.
  • Sublinhar clicáveis — marca links e botões com sublinhado, tornando-os mais fáceis de identificar.
  • Clique direito para ouvir — quando ativo, o clique com o botão direito sobre um texto faz o navegador lê-lo em voz alta (usando a Web Speech API, se houver suporte).

Cada opção liga uma classe no documento, que o CSS usa para mudar a aparência:

Recurso Classe / efeito
Reduzir animações a11y-reduced-motion
Modo escuro theme-dark
Alto contraste a11y-contrast
Fonte para dislexia a11y-dyslexic
Sublinhar clicáveis a11y-underline
Tamanho e espaçamento variáveis --a11y-* reescritas em tempo real

Como o estado é guardado. Tudo fica na chave terra-roxa-accessibility do localStorage, em um objeto com os campos fontIndex, lineIndex, speechRateIndex, dark, reduceMotion, contrast, dyslexic, underline e speech. Na leitura, os valores são validados (índices fora da faixa são corrigidos), de modo que um dado corrompido nunca quebra a página. Há ainda um botão Redefinir, que volta tudo ao padrão.

Se o navegador não oferecer suporte à Web Speech API, as opções de narração aparecem desativadas e rotuladas como indisponíveis, em vez de simplesmente falharem.


11. Modo escuro

O modo escuro vive em css/theme-dark.css e é ativado quando a classe theme-dark está presente no elemento html. Como o site é construído sobre variáveis, o tema escuro em boa parte apenas redefine essas variáveis de cor — e tudo que as consome se ajusta junto.

Algumas áreas têm elementos mais delicados (gradientes, brilhos, ícones que poderiam sumir no escuro) e por isso recebem ajustes pontuais: a timeline da página Agrinho, o glossário, o analisador, o simulador, o jogo e o próprio painel de acessibilidade. A intenção desses ajustes é sempre a mesma — garantir que texto, ícones, cards e botões continuem legíveis e com contraste suficiente quando o fundo escurece.


12. Página inicial

A página inicial (index.html, com js/main.js) apresenta o projeto e encaminha o visitante para as demais áreas. Além do hero de abertura, ela reúne uma explicação da proposta, situações do campo, uma área de métricas, depoimentos, uma seção de perguntas frequentes e chamadas para as próximas páginas.

A interatividade da home, concentrada em main.js, é toda feita à mão:

  • Contadores animados. Os números das métricas sobem do zero até o valor final com uma animação suave. Para não animar fora da tela, um IntersectionObserver só dispara a contagem quando o número aparece; e, se o usuário pediu para reduzir animações, o valor final é mostrado direto.
  • Carrossel de depoimentos. Os cards giram em uma disposição em "órbita" (ativo ao centro, vizinhos nas laterais), com avanço automático a cada poucos segundos. O avanço pausa quando o ponteiro está sobre o carrossel ou quando ele recebe foco pelo teclado, e não roda se o modo de reduzir animações estiver ligado.
  • FAQ em acordeão. Abrir uma pergunta fecha as demais. A altura é animada com a Web Animations API, e a animação é descartada quando o usuário prefere menos movimento.
  • Dica que segue o cursor. Em telas com ponteiro fino (mouse), alguns elementos exibem uma pequena dica que acompanha o cursor; em telas de toque, ela simplesmente não aparece.

13. Aprender

A página Aprender (aprendizado/index.html, com js/aprendizado.js) organiza o conteúdo teórico em trilhas de estudo. Os dados de cada trilha vêm de js/courses.js, no objeto global window.TerraRoxaCourses.

As trilhas disponíveis:

Trilha Duração Lições
Agro forte, futuro sustentável 35 min 7
Solo vivo 18 min 3
Água no campo 16 min 3
Biodiversidade que trabalha 15 min 3
Manejo Integrado de Pragas 20 min 3
Plantio direto e rotação 19 min 3
Tecnologia com propósito 17 min 3
Clima e resiliência 18 min 3
Gestão e renda sustentável 17 min 3
Campo e cidade conectados 15 min 3

Cada trilha é um objeto com slug, número, título, descrição, categoria, duração, número de lições e os capítulos. Cada capítulo traz parágrafos e, quando faz sentido, um destaque (callout), uma lista ou uma imagem de apoio. Muitas trilhas terminam com uma pergunta de verificação e uma atividade prática sugerida.

O que a página guarda no navegador:

Chave Uso
terra-roxa-course-progress progresso (em %) de cada trilha
terra-roxa-course-notes anotações do usuário
terra-roxa-course-seen trilhas já abertas
terra-roxa-last-course última trilha aberta
terra-roxa-course-completion-celebrated se a conclusão geral já foi comemorada

O progresso é calculado conforme a rolagem dentro da trilha e fica salvo, de modo que ao voltar a página reabre no ponto certo. Quando todas as trilhas são concluídas, uma animação de comemoração (um confete desenhado na Canvas) aparece uma única vez — o registro em localStorage evita repeti-la a cada visita.


14. Quizzes

A página Quizzes (quizzes/index.html, com js/quizzes.js) revisa o conteúdo das trilhas. Como as perguntas derivam dos cursos, ela também carrega courses.js.

O fluxo cobre o ciclo completo de um quiz: listar os quizzes disponíveis, iniciar um, responder pergunta a pergunta, calcular o resultado e registrar a pontuação. Dois recursos de conforto se destacam:

  • Rascunho automático. Se o usuário sai no meio de um quiz, as respostas já dadas ficam salvas como rascunho. Ao voltar, ele pode retomar de onde parou.
  • Pontuação e retomada. O melhor resultado de cada quiz fica registrado, e a interface mostra um rótulo de progresso com base nele.

O que a página guarda:

Chave Uso
terraRoxaQuizScores melhores pontuações por quiz
terraRoxaQuizDrafts rascunhos de quizzes em andamento

Um detalhe de implementação: a resposta correta de cada pergunta não fica gravada de forma óbvia no estado salvo. A verificação usa uma pequena assinatura, em vez de expor o índice da alternativa certa, para que não seja trivial "espiar" o gabarito pelo armazenamento do navegador. As transições de altura entre perguntas são animadas manualmente, para que o card não "salte" quando o tamanho do conteúdo muda.


15. Analisar e Capturar

Essa é a parte mais elaborada do projeto em termos de processamento, e também a que eu mais tomo cuidado ao descrever — por isso a seção 21 reforça seus limites.

A página Analisar (analisar/index.html) é a porta de entrada: ela apresenta a ferramenta, explica o uso educativo e encaminha para a captura. Ela não executa a análise.

A página Capturar (analisar/capturar/index.html) é onde a análise acontece, e tudo se passa dentro do navegador — nenhuma imagem é enviada para qualquer servidor. Os scripts envolvidos dividem bem as tarefas:

  • detector.js cuida do fluxo de interface: escolher a cultura (milho ou feijão), enviar uma foto ou abrir a câmera, preparar a imagem em um <canvas>, mostrar o resultado e salvar no histórico.
  • leaf-vision.js é o "motor" da leitura de cores.
  • diagnostics-data.js guarda os textos de cada condição.
  • analise-historico.js administra o histórico local.

Como a leitura funciona. A imagem é desenhada em um <canvas> e seus pixels são percorridos (em uma amostragem, para manter tudo leve). Cada pixel é convertido de RGB para o espaço de cor HSV, que separa melhor matiz, saturação e brilho. A partir daí, o leaf-vision.js classifica a cor em uma de quatro faixas — verde, amarelo, laranja ou marrom —, descartando antes o fundo branco e os tons frios (azuis), que não fazem parte da folha. As faixas são definidas por limites simples de matiz, saturação e brilho.

Com a contagem de cada cor, o motor estima a cobertura (quanto da imagem é folha) e calcula uma pontuação para quatro condições, aplicando pesos diferentes para cada sinal:

Condição Sinal de cor associado
Folha saudável predomínio de verde
Ferrugem manchas alaranjadas
Mancha foliar áreas marrons/secas
Amarelecimento (clorose) amarelo difuso

A condição mais provável é a de maior pontuação. O motor também mede a "indecisão" do resultado: se a cobertura de folha for baixa demais, ou se as condições ficarem muito empatadas (calculado por uma entropia normalizada), o resultado é marcado como de baixa confiança, e a interface comunica isso em vez de cravar um veredito. A barra de progresso que aparece durante a análise é uma animação de interface — a leitura em si é praticamente instantânea sobre a amostra de pixels.

Os textos do resultado vêm de diagnostics-data.js, que para cada condição traz um resumo, sinais a observar, ações sugeridas, medidas de prevenção e uma nota específica por cultura (feijão e milho). São textos educativos, escritos para ajudar o estudante a entender o que aquele padrão de cor costuma indicar — sempre lembrando que observar não é diagnosticar.

Histórico. Cada análise pode ser guardada localmente (analise-historico.js), na chave terra-roxa:analises, limitada às 24 entradas mais recentes. Se o armazenamento do navegador estiver cheio, o código reduz a lista pela metade em vez de falhar. A chave terra-roxa-history-seen-count controla quantas análises já foram vistas, para sinalizar novidades.


16. Resultados — o simulador de talhão

A página Resultados (resultados/index.html, com js/resultados.js) é um simulador educativo de talhão, desenhado em pixel art. É o maior arquivo de JavaScript que escrevi no projeto, e tudo nele — inclusive o desenho do mapa — é feito sem bibliotecas.

O mapa. O talhão é uma grade de células, desenhada célula a célula em um <canvas>. O "terreno" inicial não é aleatório de qualquer jeito: ele é gerado por uma função de ruído (value noise combinado em várias frequências, técnica conhecida como fbm) a partir de uma semente, o que produz manchas de fertilidade e relevo com aparência orgânica e reproduzível. O usuário navega com câmera e zoom, e um minimapa mostra a visão geral.

As decisões e os indicadores. O usuário aplica ações sobre as células — escolher culturas, ajustar fertilidade, etc. — e o simulador recalcula camadas e indicadores como crescimento, saúde da planta, pressão de pragas e risco de geada. A ideia é tornar visível a relação entre o que se decide e como o sistema responde. Há também uma checagem de conflitos (combinações que não fazem sentido) e um modo para daltonismo, que troca as cores das culturas por uma paleta mais distinguível.

Histórico, presets e persistência. O simulador mantém um registro das alterações que permite desfazer e refazer (comparando "fotos" do estado antes e depois de cada mudança). O estado é salvo automaticamente no localStorage, e o usuário pode guardar configurações como presets para recarregar depois.

Chave Uso
terraRoxaFieldMap estado atual do talhão
terraRoxaFieldMap:presets configurações salvas pelo usuário

Exportação. O talhão pode ser exportado em vários formatos, todos gerados pelo próprio navegador (sem servidor):

  • JSON — o estado completo, para reabrir depois;
  • CSV — uma planilha das células;
  • GeoJSON — os polígonos das células como uma FeatureCollection;
  • ISOXML — um arquivo no padrão ISO 11783, usado em maquinário agrícola;
  • PNG — uma imagem do mapa, a partir do canvas.

O simulador também importa de volta um arquivo JSON exportado. Vale frisar (ver seção 21) que os dados são simulados: o talhão não representa nenhuma propriedade real e os indicadores são ilustrativos.


17. Jogo — Lavoura em Equilíbrio

A página Jogo (jogo/index.html, com js/jogo.js) traz o mini-game "Lavoura em Equilíbrio", que mostra de um jeito lúdico a tensão entre produzir e cuidar do ambiente. O motor do jogo — laço de animação, pontuação, efeitos, áudio — também escrevi do zero.

Os principais elementos:

  • Pontuação com combo. Acertos seguidos aumentam um multiplicador (até 3×), e erros quebram o combo. Pequenos números e estouros de partículas dão o retorno visual.
  • Dificuldade. O jogador escolhe o nível, e a escolha fica salva.
  • Eventos e estações. O jogo aplica eventos (incluindo climáticos) que mudam o ritmo da partida.
  • Melhorias e problemas. Ao longo do jogo surgem boas práticas a aproveitar e problemas a evitar, cada um com efeito sobre produção e ambiente.
  • Selos, ranking e desafio diário. Conquistas são desbloqueadas, há um ranking local e um desafio do dia, gerado a partir da data por uma semente — todos os jogadores do mesmo dia enfrentam o mesmo desafio.
  • Áudio sob controle. Os efeitos sonoros são sintetizados na Web Audio API e podem ser ligados/desligados; a preferência é lembrada.

O que o jogo guarda:

Chave Uso
terraRoxaJogoBest melhor pontuação
terraRoxaJogoSom som ligado/desligado
terraRoxaJogoSelos conquistas desbloqueadas
terraRoxaJogoRanking ranking local
terraRoxaJogoDesafio progresso do desafio diário
terraRoxaJogoDificuldade dificuldade escolhida
terraRoxaJogoPartidas número de partidas jogadas

18. Glossário

A página Glossário (glossario/index.html, com js/glossario.js) permite consultar 1.200 termos técnicos, divididos em 54 categorias, definidos em js/glossario-data.js. Cada termo é um objeto simples:

{
  id: "agronegocio",
  termo: "Agronegócio",
  categoria: "Geral",
  definicao: "..."
}

Exibir 1.200 itens de uma vez deixaria a página pesada, então a lista é virtualizada: apenas os itens visíveis na tela existem no DOM a cada momento, e o script calcula a altura total e as colunas para que a rolagem continue natural. Sobre essa base há busca, filtro por categoria e paginação.

A busca ignora acentos: o texto digitado e os termos são normalizados (removendo acentuação) antes da comparação, de modo que procurar por "agua" encontra "água". Clicar em um termo abre sua definição em um popup, e o layout muda para uma única coluna no celular.


19. Agrinho

A página Agrinho (agrinho/index.html, com js/agrinho.js) contextualiza o programa que dá nome ao concurso: o que é o Agrinho, sua metodologia, casos de sucesso, quem pode participar, como participar, a relação com os Objetivos de Desenvolvimento Sustentável (ODS) e as etapas do concurso.

As interações da página são ligadas à rolagem e a pequenos widgets, todos feitos à mão:

  • Timeline das etapas. No desktop, a seção de etapas "fixa" enquanto o usuário rola, avançando a linha do tempo conforme a posição da página; no mobile, ela usa um layout simplificado. A animação respeita a opção de reduzir movimento.
  • Slider de casos. Os casos de sucesso passam em um carrossel navegável.
  • Painel das ODS. Clicar em um objetivo destaca o card correspondente.
  • FAQ e um pequeno assistente que monta um texto a partir das escolhas do usuário.

Por tratar de um programa real, esta página tem um cuidado editorial extra: quando uma seção fala do Agrinho, o texto é sobre o Agrinho, sem misturá-lo com o Terra Roxa.


20. Dados salvos no navegador

Não há login nem servidor: tudo o que o site guarda fica no localStorage do próprio navegador, na máquina do usuário, e nada é sincronizado entre dispositivos. Reunindo as chaves citadas ao longo do documento:

Chave Origem Uso
terra-roxa-accessibility accessibility-dock.js preferências de acessibilidade
terra-roxa-course-progress aprendizado.js progresso das trilhas
terra-roxa-course-notes aprendizado.js anotações
terra-roxa-course-seen aprendizado.js trilhas já vistas
terra-roxa-last-course aprendizado.js última trilha aberta
terra-roxa-course-completion-celebrated aprendizado.js controle da comemoração de conclusão
terraRoxaQuizScores quizzes.js melhores pontuações dos quizzes
terraRoxaQuizDrafts quizzes.js rascunhos de quizzes
terra-roxa:analises analise-historico.js histórico de análises (até 24)
terra-roxa-history-seen-count analisar.js contador de histórico visto
terraRoxaFieldMap resultados.js estado do simulador
terraRoxaFieldMap:presets resultados.js presets do simulador
terraRoxaJogoBest jogo.js melhor pontuação
terraRoxaJogoSom jogo.js som ligado/desligado
terraRoxaJogoSelos jogo.js conquistas
terraRoxaJogoRanking jogo.js ranking local
terraRoxaJogoDesafio jogo.js desafio diário
terraRoxaJogoDificuldade jogo.js dificuldade
terraRoxaJogoPartidas jogo.js partidas jogadas

Como reiniciar o estado. Durante os testes, é comum querer voltar tudo ao zero. Isso se faz pelo próprio navegador, em DevTools → Application → Local Storage, apagando as chaves do Terra Roxa. Convém fazer isso depois de testar muitos quizzes ou análises, de mexer no simulador, de validar o ranking do jogo, ou quando o painel de acessibilidade ficar com um estado antigo.


21. Escopo educativo e limitações

Para que ninguém leia mais do que está escrito, vale deixar claro o alcance de cada recurso:

  • A análise visual é uma leitura de cores com finalidade educativa. Ela não é um diagnóstico agronômico e não substitui laboratório, visita técnica ou a avaliação de um profissional. Ela aponta o que um padrão de cor costuma sugerir, não o que a planta realmente tem.
  • O simulador trabalha com dados simulados. Ele não representa uma propriedade real, não usa dados reais de solo ou clima e não calcula recomendações agronômicas. Serve para demonstrar relações entre decisões e estado do sistema.
  • O jogo é uma representação simplificada. Não reproduz manejo, economia ou clima reais.
  • O glossário é material de consulta e pode receber revisão técnica e novos termos.

Esse cuidado é também uma exigência implícita do projeto: os textos devem sempre tratar a análise como educativa, nunca como diagnóstico profissional.


22. Privacidade e segurança

A ausência de servidor tem uma consequência direta e positiva para a privacidade: nada sai do navegador do usuário. Não há login, não há envio de fotos para nenhum lugar, e a imagem analisada é processada localmente e descartada. Históricos, progresso, ranking e preferências vivem apenas no localStorage da máquina.

Dois pontos de atenção decorrem disso, e estão documentados de propósito:

  • Os dados em localStorage podem ser apagados pelo próprio navegador (ao limpar dados de navegação, por exemplo) e não são privados entre usuários do mesmo perfil do navegador. Quem usa o mesmo perfil vê os mesmos dados.
  • Justamente por isso, o simulador não deve receber informações reais e sensíveis: ele é um ambiente de demonstração.

23. Guia de manutenção

Concentrei a maior parte do conteúdo em poucos arquivos, o que torna as atualizações previsíveis. Em qualquer uma delas, vale manter os princípios do projeto: nada de framework ou back-end, nada de CSS/JS embutido no HTML, preservar a acessibilidade e conferir o modo escuro e o mobile depois de cada mudança.

Trilhas de estudo — js/courses.js. Os dados estão em window.TerraRoxaCourses. Para alterar uma trilha, localize seu slug e ajuste título, descrição, introdução, objetivos ou capítulos. Mantenha o slug único, revise o quiz correspondente e teste as páginas Aprender e Quizzes, no desktop e no mobile.

Quizzes — js/quizzes.js. As perguntas dependem do conteúdo das trilhas. Ao editar, confira a alternativa correta e a explicação, e evite respostas ambíguas, alternativas duplicadas ou perguntas que dependam de conteúdo que não existe na trilha.

Análise visual. As faixas de cor ficam em leaf-vision.js; o fluxo de upload e câmera, em detector.js; os textos das condições, em diagnostics-data.js. Ao calibrar as cores, teste com imagens claras, escuras, com fundo branco e com arquivos inválidos, além do caso sem câmera. O texto deve continuar tratando a análise como educativa.

Glossário — js/glossario-data.js. Cada termo é um objeto com id, termo, categoria e definicao. Para adicionar um termo, inclua o objeto mantendo o id único, sem deixar a definição vazia, e teste a busca (inclusive sem acento), o filtro por categoria e a paginação.

Simulador e jogo — js/resultados.js e js/jogo.js. São os arquivos mais extensos e mudanças neles pedem teste manual: no simulador, verifique grade, ferramentas, indicadores, undo/redo, exportação, importação e o estado salvo; no jogo, verifique início de partida, combo, dificuldade, ranking e som. Em ambos, confira o modo escuro e o mobile.

Estilos. Ajustes globais vão em css/style.css; o que é de uma página fica em css/pages/. Ao mexer em um arquivo importante, lembre de atualizar o ?v= no HTML para furar o cache (ver seção 7).


24. Roteiro de testes

O projeto não tem testes automatizados — coerente com a proposta sem ferramentas de build. A verificação é manual, e o roteiro abaixo cobre os pontos principais.

Navegação e estrutura

  • abrir todas as páginas pelo menu e confirmar que carregam, sem erros no console;
  • conferir se o item ativo do cabeçalho corresponde à página atual, em todas elas (inclusive nas subpastas, onde os caminhos relativos são mais sensíveis).

Acessibilidade

  • abrir o painel e ativar, um a um, todos os recursos (fonte, espaçamento, narração, modo escuro, alto contraste, dislexia, sublinhado, reduzir animações);
  • confirmar que as preferências persistem após recarregar a página e que o botão Redefinir zera tudo.

Funcionalidades por página

  • Aprender: abrir uma trilha, avançar o progresso, escrever uma anotação e reabrir para ver se o estado volta;
  • Quizzes: responder um quiz, sair no meio (rascunho salvo) e retomar; finalizar e ver o resultado;
  • Capturar: enviar uma imagem, conferir o resultado e o histórico; testar com a câmera bloqueada (deve cair no upload);
  • Resultados: aplicar uma ferramenta, trocar camada, desfazer/refazer, exportar (JSON e PNG) e recarregar para confirmar o estado salvo;
  • Jogo: jogar um ciclo até a tela de fim, conferir o ranking e trocar a dificuldade;
  • Glossário: buscar um termo com e sem acento, filtrar por categoria, paginar e abrir um termo;
  • Agrinho: passar os casos do slider e rolar a timeline de etapas.

Modo escuro e responsividade

  • repetir os testes acima no modo escuro, observando contraste, ícones e cards;
  • abrir as páginas em larguras pequenas (360–430px), procurando rolagem horizontal, sobreposições e texto cortado — com atenção especial a Aprender, Quizzes, Capturar, Resultados, Glossário e Agrinho.

25. Créditos e fontes

Conteúdos e referências citados no projeto:

A fonte tipográfica OpenDyslexic, usada no recurso de leitura para dislexia, é distribuída sob a licença incluída em public/fonts/OpenDyslexic-LICENSE.txt.


Terra Roxa — projeto desenvolvido para o Concurso Agrinho 2026, categoria Programação Front-End (HTML, CSS e JavaScript).

About

Site educativo estático sobre agricultura sustentável, feito em HTML, CSS e JavaScript puro (sem frameworks ou back-end) para o Concurso Agrinho 2026. Reúne trilhas de estudo, quizzes, análise visual de folhas, simulador de talhão e um mini-game.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors