Normalmente a urna eletrônica brasileira exibe o número do candidato (para presidente), com botões para dígitos, "Branco", "Corrige", "Confirma". Também mostra o nome e a foto do candidato? Normalmente a urna real mostra nome, número, partido e foto do candidato. Para simplificar, podemos implementar um banco de dados fictício de candidatos com os principais da última eleição (Lula, Bolsonaro, etc.).
O usuário digita o número do candidato, o sistema busca o candidato e exibe as informações. No final, confirma o voto e armazena a contagem, exibindo uma mensagem de sucesso. Além disso, deve impedir a votação após confirmar, talvez permitir reiniciar? Mas a urna típica – cada eleitor vota, então poderíamos ter um mecanismo de "Finalizar Votação" para demonstração, ou um painel de administração simples? O requisito: "gerar uma urna de votação presidencial, igual a usada no Brasil na última eleição presidencial" deve se comportar de maneira semelhante: o eleitor digita o número, vê os detalhes do candidato (nome, foto se possível: podemos usar placeholders com Font Awesome ou emoji ou imagem).
Como a urna eletrônica real usa imagens, podemos usar imagens redondas simples ou iniciais. Para profissionalismo, projetamos com Tailwind CSS: responsivo, moderno, com tema escuro/claro? Use um fundo e design que lembrem a urna: frequentemente azul/amarelo ou cinza? Talvez um design neutro. Além disso, código comentado passo a passo, tudo em um único arquivo HTML. Como precisamos produzir um trecho de código executável, podemos incorporar estilo, scripts, CDN do Tailwind, além do JavaScript para a lógica de votação.
Para testar o código abaixo, basta selecionar e copiar todo o codigo abaixo no bloco de notas e salvar com a extensão html exemplo urna.html, selecione a pasta onde será gravado o arquivo, depois basta clicar duas vezes no ícone para abrir no navegador chrome ou qualquer outro.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Urna Eletrônica 2026 | Simulação Oficial</title>
<!-- Tailwind CSS v3 + Font Awesome (ícones opcionais para melhor semântica visual) -->
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<!-- custom ajuste fino para sombras e transições -->
<style>
/* pequeno ajuste para foco e transição suave nos botões */
button:active { transform: scale(0.97); transition: 0.05s ease; }
.numero-digitado {
font-family: 'Courier New', monospace;
letter-spacing: 4px;
}
/* estilo da tela simulando o display da urna */
.display-urna {
background: linear-gradient(145deg, #eef2f5 0%, #d9e0e6 100%);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.05), 0 4px 8px rgba(0,0,0,0.1);
}
.teclado-numero {
transition: all 0.1s ease;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.teclado-numero:hover {
background-color: #e2e8f0;
}
</style>
</head>
<body class="bg-gradient-to-br from-slate-800 to-slate-900 min-h-screen flex items-center justify-center p-4 font-sans">
<div class="w-full max-w-5xl mx-auto">
<!-- Artigo: cabeçalho profissional -->
<div class="text-center mb-4">
<h1 class="text-2xl md:text-3xl font-bold text-white drop-shadow-md tracking-tight">🗳️ Urna Eletrônica Presidencial <span class="text-yellow-300">Brasil 2026</span></h1>
<p class="text-slate-300 text-sm mt-1">Simulação oficial • Voto direto e sigiloso • Justiça Eleitoral</p>
</div>
<!-- Estrutura principal da urna (grid: painel esquerdo/teclado) -->
<div class="bg-white rounded-2xl shadow-2xl overflow-hidden border border-slate-200">
<div class="grid md:grid-cols-3 gap-0">
<!-- LADO ESQUERDO: DISPLAY E INFORMAÇÕES DO CANDIDATO (área principal da urna) -->
<div class="md:col-span-2 bg-gray-50 p-6 border-r border-gray-200">
<!-- Título da eleição -->
<div class="flex items-center gap-2 mb-3 pb-2 border-b border-gray-300">
<i class="fas fa-flag-checkered text-green-700"></i>
<span class="font-bold text-gray-700 uppercase tracking-wide">Eleição Presidencial</span>
<span class="bg-red-600 text-white text-xs px-2 py-0.5 rounded-full ml-2">1º Turno</span>
</div>
<!-- Área de exibição do número digitado (similar ao visor) -->
<div class="display-urna rounded-xl p-5 mb-5 border border-gray-300">
<div class="text-xs text-gray-500 uppercase tracking-wider mb-1">Digite o número</div>
<div class="numero-digitado text-6xl md:text-7xl font-mono font-bold text-gray-800 bg-white rounded-lg p-3 text-center shadow-inner" id="numeroDisplay">
—
</div>
</div>
<!-- Informações do candidato (dinâmico) -->
<div class="bg-white rounded-xl border border-gray-200 p-4 shadow-sm transition-all duration-200" id="candidateInfoPanel">
<!-- conteúdo preenchido via JS -->
<div id="infoContent" class="flex flex-col md:flex-row gap-4 items-start">
<div class="w-24 h-24 bg-slate-200 rounded-full flex items-center justify-center text-4xl font-bold text-slate-500 shadow-inner">
<i class="fas fa-user-circle text-5xl text-slate-400"></i>
</div>
<div class="flex-1 space-y-1">
<p class="text-gray-400 text-sm">Aguardando digitação...</p>
<p class="font-mono text-2xl font-bold text-gray-500">_ _</p>
<p class="text-gray-500">Nenhum candidato selecionado</p>
</div>
</div>
</div>
<!-- Área de mensagens de retorno (feedback para o eleitor) -->
<div class="mt-4 text-sm text-center font-medium py-2 px-3 rounded-lg bg-amber-50 border border-amber-200 text-amber-800" id="feedbackMessage">
<i class="fas fa-info-circle mr-1"></i> Utilize o teclado ou botões para votar
</div>
</div>
<!-- LADO DIREITO: TECLADO NUMÉRICO + AÇÕES (BRANCO, CORRIGE, CONFIRMA) -->
<div class="bg-slate-100 p-5 flex flex-col">
<div class="text-center mb-2 font-semibold text-slate-600 flex items-center justify-center gap-2">
<i class="fas fa-keyboard"></i> <span>Teclado da Urna</span>
</div>
<!-- grade 3x3 números + ações -->
<div class="grid grid-cols-3 gap-3 mb-4">
<!-- botões 1 a 9 -->
<button data-digit="1" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl transition-all">1</button>
<button data-digit="2" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">2</button>
<button data-digit="3" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">3</button>
<button data-digit="4" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">4</button>
<button data-digit="5" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">5</button>
<button data-digit="6" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">6</button>
<button data-digit="7" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">7</button>
<button data-digit="8" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">8</button>
<button data-digit="9" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl">9</button>
<!-- Zero ocupa posição central inferior, mas mantemos padrão -->
<button data-digit="0" class="teclado-numero bg-white hover:bg-gray-100 text-gray-800 font-bold py-4 rounded-xl shadow-md text-2xl col-span-1">0</button>
<!-- espaço vazio para manter grid (apenas visual) -->
<div></div>
<div></div>
</div>
<!-- Botões de ação principais (branco, corrige, confirma) -->
<div class="grid grid-cols-3 gap-3 mt-2">
<button id="btnBranco" class="bg-gray-500 hover:bg-gray-600 text-white font-bold py-3 rounded-xl shadow-md transition flex items-center justify-center gap-2">
<i class="fas fa-square"></i> BRANCO
</button>
<button id="btnCorrige" class="bg-orange-500 hover:bg-orange-600 text-white font-bold py-3 rounded-xl shadow-md transition flex items-center justify-center gap-2">
<i class="fas fa-undo-alt"></i> CORRIGE
</button>
<button id="btnConfirma" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 rounded-xl shadow-md transition flex items-center justify-center gap-2">
<i class="fas fa-check-circle"></i> CONFIRMA
</button>
</div>
<!-- espaço instruções -->
<div class="text-center text-xs text-gray-500 mt-5 border-t pt-3">
<i class="fas fa-lock"></i> Voto secreto · 2 dígitos
</div>
</div>
</div>
</div>
<!-- PAINEL DE APURAÇÃO PARCIAL (resultados dinâmicos - apenas para fins educacionais/simulação) -->
<div class="mt-6 bg-white/90 backdrop-blur-sm rounded-2xl shadow-xl p-4 border border-slate-200">
<div class="flex justify-between items-center flex-wrap gap-2 border-b pb-2 mb-3">
<div class="flex items-center gap-2">
<i class="fas fa-chart-simple text-blue-700"></i>
<h2 class="font-bold text-gray-700 text-lg">📊 Apuração Parcial (Votos computados)</h2>
</div>
<button id="resetVotosBtn" class="text-xs bg-red-100 hover:bg-red-200 text-red-700 px-3 py-1 rounded-full transition flex items-center gap-1"><i class="fas fa-trash-alt"></i> Zerar Estatísticas</button>
</div>
<div id="resultadosContainer" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-3 text-sm">
<!-- JS preenche dinamicamente os totais -->
</div>
<p class="text-xs text-gray-400 mt-3 text-center">🔒 Simulação de urna eletrônica - Votos registrados conforme legislação fictícia. A cada confirmação, seu voto é contabilizado.</p>
</div>
</div>
<script>
// ============================================================
// URNA ELETRÔNICA BRASILEIRA - CÓDIGO PROFISSIONAL
// Linguagem: JavaScript (ES6+) com Tailwind CSS
// Descrição: Simulação completa do processo de votação para presidente
// Funcionalidades: digitação 2 dígitos, candidatos reais da última eleição,
// votos válidos, nulos, brancos, teclado físico, feedback, segurança anti-duplo clique.
// Documentação passo a passo integrada.
// ============================================================
// -------------------- 1. BASE DE DADOS DOS CANDIDATOS (Última eleição presidencial) --------------------
// Números oficiais e nomes reais com partidos
const CANDIDATOS = [
{ numero: "13", nome: "LUIZ INÁCIO LULA DA SILVA", partido: "PT", vice: "Geraldo Alckmin", fotoIcon: "fas fa-hand-peace", cor: "bg-red-100" },
{ numero: "22", nome: "JAIR MESSIAS BOLSONARO", partido: "PL", vice: "Braga Netto", fotoIcon: "fas fa-fist-raised", cor: "bg-blue-100" },
{ numero: "12", nome: "CIRO GOMES", partido: "PDT", vice: "Ana Paula Matos", fotoIcon: "fas fa-chart-line", cor: "bg-green-100" },
{ numero: "15", nome: "SIMONE TEBET", partido: "MDB", vice: "Mara Gabrilli", fotoIcon: "fas fa-star-of-life", cor: "bg-purple-100" },
{ numero: "44", nome: "SORAYA THRONICKE", partido: "UNIÃO", vice: "Marcos Cintra", fotoIcon: "fas fa-dove", cor: "bg-yellow-100" }
];
// Mapa para busca rápida por número
const candidatosMap = new Map();
CANDIDATOS.forEach(c => candidatosMap.set(c.numero, c));
// -------------------- 2. ESTADO GLOBAL DA URNA --------------------
let currentNumber = ""; // número digitado (string de até 2 dígitos)
let blankMode = false; // modo branco ativo?
let processingVote = false; // trava para evitar múltiplas confirmações
let lastFeedbackTimeout = null;
// Estrutura de votos (totais)
let votos = {
candidatos: {}, // chave: número do candidato, valor: quantidade
brancos: 0,
nulos: 0
};
// Inicializa contagem de cada candidato com 0
CANDIDATOS.forEach(c => { votos.candidatos[c.numero] = 0; });
// -------------------- 3. REFERÊNCIAS DOM --------------------
const numeroDisplayEl = document.getElementById("numeroDisplay");
const candidateInfoPanel = document.getElementById("infoContent");
const feedbackMsgEl = document.getElementById("feedbackMessage");
const resultadosContainer = document.getElementById("resultadosContainer");
const btnBranco = document.getElementById("btnBranco");
const btnCorrige = document.getElementById("btnCorrige");
const btnConfirma = document.getElementById("btnConfirma");
const resetVotosBtn = document.getElementById("resetVotosBtn");
// -------------------- 4. FUNÇÕES AUXILIARES DE UI E FEEDBACK --------------------
function mostrarFeedback(mensagem, tipo = "info") {
if (lastFeedbackTimeout) clearTimeout(lastFeedbackTimeout);
let corBg = "bg-blue-50 border-blue-200 text-blue-800";
let icone = "fa-info-circle";
if (tipo === "sucesso") { corBg = "bg-green-50 border-green-200 text-green-800"; icone = "fa-check-circle"; }
if (tipo === "erro") { corBg = "bg-red-50 border-red-200 text-red-800"; icone = "fa-exclamation-triangle"; }
if (tipo === "aviso") { corBg = "bg-yellow-50 border-yellow-200 text-yellow-800"; icone = "fa-clock"; }
feedbackMsgEl.innerHTML = `<i class="fas ${icone} mr-1"></i> ${mensagem}`;
feedbackMsgEl.className = `text-sm text-center font-medium py-2 px-3 rounded-lg border ${corBg} transition-all`;
lastFeedbackTimeout = setTimeout(() => {
if (feedbackMsgEl) feedbackMsgEl.innerHTML = `<i class="fas fa-info-circle mr-1"></i> Aguardando voto ou digite o número`;
feedbackMsgEl.className = "text-sm text-center font-medium py-2 px-3 rounded-lg bg-amber-50 border border-amber-200 text-amber-800";
}, 2800);
}
// Atualiza a interface com base no estado (número digitado ou modo branco)
function atualizarInterfaceCompleta() {
// Atualiza display do número
if (blankMode) {
numeroDisplayEl.innerText = "BRANCO";
numeroDisplayEl.classList.add("text-yellow-600");
} else {
numeroDisplayEl.innerText = currentNumber.length ? currentNumber : "—";
numeroDisplayEl.classList.remove("text-yellow-600");
}
// Painel de informações do candidato / branco
if (blankMode) {
// Exibe tela de voto em branco
candidateInfoPanel.innerHTML = `
<div class="flex flex-col md:flex-row gap-4 items-start w-full">
<div class="w-24 h-24 bg-gray-200 rounded-full flex items-center justify-center text-4xl font-bold text-gray-500 shadow-inner">
<i class="fas fa-ban text-4xl text-gray-500"></i>
</div>
<div class="flex-1 space-y-2">
<p class="text-gray-600 font-semibold uppercase text-sm">VOTO EM BRANCO</p>
<p class="text-2xl font-mono font-bold text-gray-700">—</p>
<p class="text-gray-600">Confirme para registrar voto branco</p>
<span class="inline-block bg-gray-100 text-gray-600 text-xs px-2 py-1 rounded-full">Nenhum candidato</span>
</div>
</div>
`;
return;
}
// Se não está em branco, mostra informações do candidato baseado no número
if (currentNumber.length === 0) {
candidateInfoPanel.innerHTML = `
<div class="flex flex-col md:flex-row gap-4 items-start w-full">
<div class="w-24 h-24 bg-slate-200 rounded-full flex items-center justify-center text-4xl font-bold text-slate-500">
<i class="fas fa-user-circle text-5xl text-slate-400"></i>
</div>
<div class="flex-1 space-y-1">
<p class="text-gray-400 text-sm">Aguardando digitação</p>
<p class="font-mono text-2xl font-bold text-gray-500">_ _</p>
<p class="text-gray-500">Digite o número do candidato</p>
</div>
</div>
`;
return;
}
// Busca candidato no mapa
const candidato = candidatosMap.get(currentNumber);
if (candidato) {
// Mostra candidato encontrado
candidateInfoPanel.innerHTML = `
<div class="flex flex-col md:flex-row gap-4 items-start w-full">
<div class="w-24 h-24 ${candidato.cor} rounded-full flex items-center justify-center text-4xl font-bold text-gray-700 shadow-inner border-2 border-gray-300">
<i class="${candidato.fotoIcon} text-4xl"></i>
</div>
<div class="flex-1 space-y-1.5">
<p class="text-xs text-gray-500 uppercase tracking-wide">Candidato(a) à Presidência</p>
<p class="font-bold text-xl text-gray-800">${candidato.nome}</p>
<p class="text-sm"><span class="font-semibold">Partido:</span> ${candidato.partido}</p>
<p class="text-sm"><span class="font-semibold">Vice:</span> ${candidato.vice}</p>
<div class="flex gap-2 mt-1"><span class="bg-blue-100 text-blue-800 text-xs px-2 py-0.5 rounded-full">Número: ${candidato.numero}</span></div>
</div>
</div>
`;
} else {
// Número não corresponde a nenhum candidato -> voto nulo potencial
candidateInfoPanel.innerHTML = `
<div class="flex flex-col md:flex-row gap-4 items-start w-full">
<div class="w-24 h-24 bg-red-100 rounded-full flex items-center justify-center text-4xl font-bold text-red-500">
<i class="fas fa-times-circle text-5xl text-red-400"></i>
</div>
<div class="flex-1 space-y-1">
<p class="text-red-600 font-semibold">NÚMERO INVÁLIDO</p>
<p class="font-mono text-2xl font-bold text-gray-800">${currentNumber}</p>
<p class="text-gray-500">Candidato não encontrado. O voto será NULO se confirmado.</p>
<span class="inline-block bg-red-100 text-red-700 text-xs px-2 py-1 rounded-full">Voto nulo</span>
</div>
</div>
`;
}
}
// Atualiza tabela de resultados (apuração)
function renderizarResultados() {
if (!resultadosContainer) return;
let html = '';
// Exibe cada candidato com seus votos
CANDIDATOS.forEach(cand => {
const qtd = votos.candidatos[cand.numero] || 0;
html += `
<div class="bg-gray-50 rounded-lg p-2 text-center border border-gray-200 shadow-sm">
<div class="font-bold text-gray-700 text-sm">${cand.nome.split(' ')[0]}</div>
<div class="text-xs text-gray-500">${cand.numero}</div>
<div class="text-xl font-bold text-green-700">${qtd}</div>
</div>
`;
});
// Brancos e nulos
html += `
<div class="bg-gray-50 rounded-lg p-2 text-center border border-gray-200 shadow-sm">
<div class="font-bold text-gray-700 text-sm"><i class="fas fa-square"></i> BRANCOS</div>
<div class="text-xl font-bold text-amber-600">${votos.brancos}</div>
</div>
<div class="bg-gray-50 rounded-lg p-2 text-center border border-gray-200 shadow-sm">
<div class="font-bold text-gray-700 text-sm"><i class="fas fa-ban"></i> NULOS</div>
<div class="text-xl font-bold text-red-600">${votos.nulos}</div>
</div>
`;
resultadosContainer.innerHTML = html;
}
// Registrar voto (lógica principal de confirmação)
async function registrarVoto() {
if (processingVote) {
mostrarFeedback("Processando voto anterior... Aguarde.", "aviso");
return;
}
// REGRA 1: se estiver em modo branco -> voto branco
if (blankMode) {
processingVote = true;
// Incrementa votos brancos
votos.brancos++;
renderizarResultados();
mostrarFeedback("🗳️ Voto em BRANCO registrado com sucesso!", "sucesso");
resetarUrnaParaProximoVoto();
processingVote = false;
return;
}
// REGRA 2: Nenhum dígito e não branco -> instrução
if (currentNumber.length === 0) {
mostrarFeedback("Digite um número de candidato ou pressione BRANCO.", "erro");
return;
}
// REGRA 3: verifica candidato existente ou voto nulo
const candidato = candidatosMap.get(currentNumber);
processingVote = true;
if (candidato) {
// Voto válido
votos.candidatos[candidato.numero] = (votos.candidatos[candidato.numero] || 0) + 1;
renderizarResultados();
mostrarFeedback(`✔️ Voto confirmado para ${candidato.nome} (${candidato.numero}). Seu voto foi computado!`, "sucesso");
} else {
// Voto nulo (número inválido)
votos.nulos++;
renderizarResultados();
mostrarFeedback(`⚠️ Voto NULO registrado! O número ${currentNumber} não corresponde a nenhum candidato.`, "aviso");
}
resetarUrnaParaProximoVoto();
processingVote = false;
}
// Reinicia a urna após confirmação para próximo eleitor (limpa tela, número, modos)
function resetarUrnaParaProximoVoto() {
currentNumber = "";
blankMode = false;
atualizarInterfaceCompleta();
// feedback não sobrescreve mensagem de sucesso, mas garantimos que a urna fique limpa
// Mantém interface totalmente pronta.
}
// Adicionar dígito (limitado a 2 dígitos)
function adicionarDigito(digito) {
// Se estiver em modo branco, ao digitar desativa branco
if (blankMode) {
blankMode = false;
currentNumber = "";
}
// Limite de 2 dígitos para presidente
if (currentNumber.length < 2) {
currentNumber += digito;
atualizarInterfaceCompleta();
} else {
mostrarFeedback("Número de presidente possui apenas 2 dígitos. Use CORRIGE para reiniciar.", "aviso");
}
}
// Corrige: limpa tudo e desativa modo branco
function corrigeVoto() {
if (processingVote) {
mostrarFeedback("Aguarde finalizar a confirmação atual.", "aviso");
return;
}
currentNumber = "";
blankMode = false;
atualizarInterfaceCompleta();
mostrarFeedback("Operação corrigida. Digite novamente o número ou use BRANCO.", "info");
}
// Função especial para ativar voto em branco
function ativarBranco() {
if (processingVote) {
mostrarFeedback("Aguarde antes de alterar o voto.", "aviso");
return;
}
blankMode = true;
currentNumber = "";
atualizarInterfaceCompleta();
mostrarFeedback("Voto em BRANCO selecionado. Confirme para finalizar.", "info");
}
// Reinicializar totalmente a votação (Zerar estatísticas)
function resetarVotacaoCompleta() {
if (confirm("⚠️ ATENÇÃO: Isso zerará TODOS os votos apurados. Deseja realmente reiniciar a votação?")) {
// Zera contadores
votos = {
candidatos: {},
brancos: 0,
nulos: 0
};
CANDIDATOS.forEach(c => { votos.candidatos[c.numero] = 0; });
renderizarResultados();
corrigeVoto(); // limpa interface atual e qualquer modo
mostrarFeedback("🗳️ Estatísticas zeradas! Nova simulação iniciada.", "sucesso");
}
}
// -------------------- 5. EVENTOS E INICIALIZAÇÃO --------------------
function inicializarEventos() {
// Botões numéricos (dinâmico)
document.querySelectorAll("[data-digit]").forEach(btn => {
btn.addEventListener("click", (e) => {
const digito = btn.getAttribute("data-digit");
if (digito !== null) adicionarDigito(digito);
});
});
// Botões de ações
btnBranco.addEventListener("click", ativarBranco);
btnCorrige.addEventListener("click", corrigeVoto);
btnConfirma.addEventListener("click", registrarVoto);
resetVotosBtn.addEventListener("click", resetarVotacaoCompleta);
// Opcional: suporte a teclado físico (acessibilidade)
window.addEventListener("keydown", (e) => {
const tecla = e.key;
if (tecla >= "0" && tecla <= "9") {
e.preventDefault();
adicionarDigito(tecla);
} else if (tecla === "Enter") {
e.preventDefault();
registrarVoto();
} else if (tecla === "Delete" || tecla === "Backspace" || tecla === "Escape") {
e.preventDefault();
corrigeVoto();
} else if (tecla === " " || tecla === "Space") {
e.preventDefault();
ativarBranco();
}
});
}
// Inicialização da aplicação
function init() {
inicializarEventos();
resetarUrnaParaProximoVoto(); // estado inicial limpo
renderizarResultados(); // renderiza apuração vazia
mostrarFeedback("Urna pronta! Digite o número do candidato ou pressione BRANCO.", "info");
}
// Inicia o sistema quando o DOM estiver completamente carregado
document.addEventListener("DOMContentLoaded", init);
</script>
</body>
</html>




0 Comentários
Deixe seu comentário e sua sugestão de conteúdo.