Calendário Legislativo 2026.html
por Luciano Egeno
—
última modificação
18/02/2026 13h38
Calendário Legislativo 2026.html
—
HTML,
35 KB (36328 bytes)
Conteúdo do arquivo
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Calendário Legislativo 2026 - Câmara Municipal de Manhumirim</title>
<style>
@import url("https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700&family=Open+Sans:wght@300;400;600;700&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--azul-escuro: #143a7b;
--azul-medio: #2857a2;
--cor-solene: #ffe88a;
--cor-ordinaria: #b5f5d6;
--cor-feriado: #ffd2d2;
--cor-recesso: #e1e3ea;
--cor-eleicao: #bfe3ff;
}
body {
font-family: "Open Sans", sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 40px 20px;
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: #ffffff;
border-radius: 24px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
overflow: visible;
}
/* CABEÇALHO (TELA) */
.header {
background: linear-gradient(135deg, var(--azul-escuro) 0%, var(--azul-medio) 100%);
color: white;
padding: 20px 32px;
position: relative;
border-radius: 24px 24px 0 0;
}
.header::before {
content: "";
position: absolute;
inset: -40%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.12) 0%, transparent 60%);
opacity: 0.7;
pointer-events: none;
}
.header-inner {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
.header-logo img {
height: 60px;
width: auto;
}
.header-text {
text-align: center;
}
.header-text h1 {
font-family: "Merriweather", serif;
font-size: 28px;
font-weight: 700;
letter-spacing: 1.5px;
}
.header-text .subtitle {
font-size: 13px;
font-weight: 300;
opacity: 0.95;
letter-spacing: 3px;
text-transform: uppercase;
margin-top: 4px;
}
/* CONTROLES */
.controls {
padding: 16px 32px;
background: #f8f9fa;
border-bottom: 1px solid #e1e4e8;
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
justify-content: space-between;
}
.filters {
display: flex;
flex-wrap: wrap;
gap: 8px;
flex: 1;
}
.filter-btn {
padding: 8px 16px;
border: 1px solid #d0d7de;
background: white;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
gap: 6px;
}
.filter-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 10px rgba(15, 23, 42, 0.18);
}
.filter-btn.active {
border-color: var(--azul-escuro);
background: var(--azul-escuro);
color: white;
}
.filter-indicator {
width: 14px;
height: 14px;
border-radius: 4px;
}
.print-btn {
padding: 9px 22px;
background: linear-gradient(135deg, var(--azul-escuro) 0%, var(--azul-medio) 100%);
color: white;
border: none;
border-radius: 999px;
font-size: 13px;
font-weight: 700;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 5px 16px rgba(15, 23, 42, 0.35);
display: inline-flex;
align-items: center;
gap: 8px;
}
.print-btn::before {
content: "🖨️";
font-size: 16px;
}
.print-btn:hover {
transform: translateY(-1px);
box-shadow: 0 7px 22px rgba(15, 23, 42, 0.45);
}
.content-wrapper {
padding: 28px 32px 32px;
}
/* GRID DOS MESES (TELA) - Cards coloridos */
.calendar-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
margin-bottom: 24px;
}
.month {
background: #f6f7fb;
border-radius: 20px;
overflow: hidden;
border: 2px solid #d7d9e5;
box-shadow: 0 10px 26px rgba(15, 23, 42, 0.15);
position: relative;
}
.month.atual {
border-color: var(--azul-escuro);
box-shadow: 0 14px 36px rgba(20, 58, 123, 0.35);
}
.month-header {
background: var(--azul-escuro);
color: white;
padding: 8px 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.month-title {
font-family: "Merriweather", serif;
font-size: 15px;
font-weight: 700;
letter-spacing: 2px;
}
.badge-mes-atual {
font-size: 9px;
font-weight: 700;
padding: 3px 8px;
border-radius: 999px;
background: #f3f4ff;
color: var(--azul-escuro);
border: 1px solid #d0d5f0;
}
.weekdays {
display: grid;
grid-template-columns: repeat(7, 1fr);
padding: 6px 16px 0 16px;
}
.weekday {
text-align: center;
font-weight: 600;
font-size: 9px;
color: #6b7280;
}
.days {
display: grid;
grid-template-columns: repeat(7, 1fr);
padding: 8px 12px 14px 12px;
gap: 6px;
}
.day {
height: 26px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: 600;
border-radius: 999px;
background: white;
color: #111827;
box-shadow: 0 0 0 1px #e5e7eb;
position: relative;
cursor: default;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.day.empty {
background: transparent;
box-shadow: none;
}
.day:not(.empty):hover {
transform: translateY(-1px);
box-shadow: 0 4px 10px rgba(148, 163, 184, 0.65);
z-index: 3;
}
.day.sessao-solene {
background: var(--cor-solene);
box-shadow: 0 0 0 1px #facc15;
}
.day.sessao-ordinaria {
background: var(--cor-ordinaria);
box-shadow: 0 0 0 1px #22c55e;
}
.day.feriado {
background: var(--cor-feriado);
box-shadow: 0 0 0 1px #f97373;
}
.day.recesso {
background: var(--cor-recesso);
box-shadow: 0 0 0 1px #cbd0e1;
}
.day.eleicao {
background: var(--cor-eleicao);
box-shadow: 0 0 0 1px #38bdf8;
}
.day.hoje {
box-shadow: 0 0 0 2px var(--azul-escuro);
background: #ffeef0;
}
.day.hidden {
opacity: 0.25;
filter: grayscale(0.6);
}
.tooltip {
position: fixed;
background: #111827;
color: white;
padding: 8px 12px;
border-radius: 8px;
font-size: 11px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease;
z-index: 10000;
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.6);
}
.tooltip.show {
opacity: 1;
}
.legend {
margin-top: 18px;
padding: 14px 16px;
background: #f9fafb;
border-radius: 14px;
border: 1px solid #e5e7eb;
}
.legend h2 {
font-family: "Merriweather", serif;
font-size: 17px;
margin-bottom: 12px;
color: var(--azul-escuro);
text-align: center;
text-transform: uppercase;
}
.legend-items {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 8px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background: white;
border-radius: 10px;
border: 1px solid #e5e7eb;
}
.legend-color {
width: 24px;
height: 16px;
border-radius: 5px;
}
.legend-item span {
font-size: 11px;
font-weight: 600;
color: #374151;
}
.notes {
margin-top: 14px;
padding: 12px 14px;
background: #fffbeb;
border-left: 4px solid #f59e0b;
border-radius: 10px;
}
.notes h3 {
font-family: "Merriweather", serif;
font-size: 14px;
margin-bottom: 6px;
color: #92400e;
}
.notes ul {
margin-left: 18px;
line-height: 1.5;
}
.notes li {
margin-bottom: 3px;
font-size: 11px;
color: #78350f;
}
.footer {
margin-top: 18px;
padding: 8px;
text-align: center;
background: linear-gradient(135deg, var(--azul-escuro) 0%, var(--azul-medio) 100%);
color: white;
border-radius: 10px;
font-size: 10px;
}
.print-only {
display: none;
}
/* IMPRESSÃO - Modelo colorido igual PDF 2026 */
@media print {
@page {
margin-top: 3cm;
margin-bottom: 2cm;
margin-left: 3cm;
margin-right: 2cm;
size: A4 portrait;
}
body {
background: white;
padding: 0;
margin: 0;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.container {
box-shadow: none;
border-radius: 0;
width: 100%;
max-width: 100%;
}
.header,
.controls,
.footer,
.tooltip {
display: none !important;
}
.print-only {
display: block;
}
.content-wrapper {
padding: 0;
}
.print-header {
text-align: center;
border-bottom: 1px solid #000;
padding: 0 0 4px 0;
margin-bottom: 6px;
}
.print-header img {
height: 32px;
margin-bottom: 2px;
}
.print-header h1 {
font-size: 11px;
font-weight: bold;
margin: 0;
}
.print-header p {
font-size: 7px;
margin: 0.5px 0;
}
.portaria {
margin-top: 4px;
margin-bottom: 6px;
}
.portaria h2 {
font-size: 9px;
font-weight: bold;
text-align: center;
margin-bottom: 6px;
}
.portaria-text {
text-align: justify;
font-size: 7px;
line-height: 1.2;
}
.titulo-calendario-print {
text-align: center;
font-size: 9px;
font-weight: bold;
margin: 6px 0 4px 0;
text-transform: uppercase;
}
/* Calendário colorido na impressão (igual PDF 2026) */
.calendar-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 4px 6px;
margin-bottom: 4px;
}
.month {
border-radius: 6px;
border: 1px solid #b8bfdc;
box-shadow: none;
page-break-inside: avoid;
background: #fafbfc;
}
.month.atual {
border-color: var(--azul-escuro);
border-width: 1.5px;
}
.month-header {
padding: 3px 5px;
background: var(--azul-escuro);
border-radius: 5px 5px 0 0;
}
.month-title {
font-size: 7px;
color: white;
}
.badge-mes-atual {
font-size: 5px;
padding: 1px 3px;
}
.weekdays {
padding: 2px 5px 0 5px;
}
.weekday {
font-size: 5px;
}
.days {
padding: 3px 5px 5px 5px;
gap: 2px;
}
.day {
height: 11px;
font-size: 5px;
border-radius: 999px;
}
/* Mantém as cores na impressão */
.day.sessao-solene {
background: var(--cor-solene) !important;
-webkit-print-color-adjust: exact;
}
.day.sessao-ordinaria {
background: var(--cor-ordinaria) !important;
-webkit-print-color-adjust: exact;
}
.day.feriado {
background: var(--cor-feriado) !important;
-webkit-print-color-adjust: exact;
}
.day.recesso {
background: var(--cor-recesso) !important;
-webkit-print-color-adjust: exact;
}
.day.eleicao {
background: var(--cor-eleicao) !important;
-webkit-print-color-adjust: exact;
}
.day.hoje {
box-shadow: 0 0 0 1px var(--azul-escuro);
}
.legend {
margin-top: 3px;
padding: 4px 6px;
background: white;
border: none;
}
.legend h2 {
font-size: 7px;
margin-bottom: 2px;
}
.legend-items {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 2px;
}
.legend-item {
padding: 1px 3px;
background: transparent;
border: none;
font-size: 6px;
}
.legend-color {
width: 10px;
height: 8px;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.legend-item span {
font-size: 6px;
color: #000;
}
.notes {
margin-top: 3px;
padding: 3px 5px;
background: white;
border-left: 2px solid #f59e0b;
}
.notes h3 {
font-size: 7px;
margin-bottom: 2px;
color: #000;
}
.notes ul {
margin-left: 10px;
}
.notes li {
font-size: 5.5px;
color: #000;
margin-bottom: 1px;
}
.assinaturas {
margin-top: 8px;
page-break-inside: avoid;
}
.assinaturas p {
font-size: 7px;
margin: 2px 0;
}
.assinatura-linha {
margin-top: 12px;
text-align: center;
}
.assinatura-linha .linha {
display: inline-block;
width: 200px;
border-top: 1px solid #000;
margin-bottom: 2px;
}
.assinatura-linha .nome {
font-size: 7px;
font-weight: bold;
text-transform: uppercase;
}
.assinatura-linha .cargo {
font-size: 6px;
}
}
</style>
</head>
<body>
<div class="tooltip" id="tooltip"></div>
<div class="container">
<!-- Cabeçalho (tela) -->
<div class="header">
<div class="header-inner">
<div class="header-logo">
<img src="https://www.manhumirim.mg.leg.br/logo.png" alt="Logo Câmara Municipal de Manhumirim" />
</div>
<div class="header-text">
<h1>CALENDÁRIO LEGISLATIVO</h1>
<div class="subtitle">Ano 2026 · Câmara Municipal de Manhumirim</div>
</div>
</div>
</div>
<!-- Cabeçalho (impressão) -->
<div class="print-only print-header">
<img src="https://www.manhumirim.mg.leg.br/logo.png" alt="Logo" />
<h1>CÂMARA MUNICIPAL DE MANHUMIRIM</h1>
<p>Estado de Minas Gerais</p>
<p>CNPJ: 22.702.369/0001-89</p>
<p>Site: www.manhumirim.mg.leg.br / E-mail: camara@manhumirim.mg.leg.br</p>
<p>E-Democracia: https://edemocracia.manhumirim.mg.leg.br / SAPL: https://sapl.manhumirim.mg.leg.br</p>
</div>
<!-- Portaria (impressão) -->
<div class="print-only portaria">
<h2>PORTARIA Nº ______, de _____ de __________ de 2026.</h2>
<!-- Ementa ajustada: alinhada à direita, em negrito e itálico, com “dois espaços” acima e abaixo -->
<p style="text-align: right; font-style: italic; font-weight: bold; font-size: 8px; margin: 6px 4px;">
"Fixa o Calendário Legislativo da Câmara Municipal de Manhumirim para o ano de 2026".
</p>
<div class="portaria-text">
<p style="margin-bottom: 3px;">
O Presidente da Câmara Municipal de Manhumirim, Minas Gerais, no uso de suas atribuições legais,
etc., e especialmente o disposto no art. 87, § 1º, da Resolução nº 198, de 16 de dezembro de 2000, resolve:
</p>
<p style="margin-bottom: 3px;">
<strong>Art. 1º.</strong> Fica estabelecido o calendário de atividades das Reuniões Ordinárias desta Casa de Leis
para a Sessão Legislativa de 2026, conforme calendário em anexo, ressalvadas as convocações extraordinárias.
</p>
<p style="margin-bottom: 3px; margin-left: 10px;">
<strong>Parágrafo único.</strong> Eventuais alterações no calendário serão efetuadas por meio de portaria
assinada pelo presidente ou pelos Membros da Mesa Diretora.
</p>
<p style="margin-bottom: 3px;">
<strong>Art. 2º.</strong> Esta portaria entra em vigor na data de sua publicação.
</p>
<p style="margin-bottom: 3px;">
<strong>Art. 3º.</strong> Revogam-se as disposições em contrário.
</p>
<p style="text-align: right; margin-right: 4px;">Publique-se. Registre-se.</p>
<p style="text-align: right; margin-right: 4px; margin-bottom: 6px;">
Manhumirim, Gabinete do Presidente, em _____ de __________ de 2026.
</p>
</div>
</div>
<!-- Controles -->
<div class="controls">
<div class="filters">
<button class="filter-btn" data-filter="all">Todos os eventos</button>
<button class="filter-btn" data-filter="sessao-solene">
<span class="filter-indicator" style="background: var(--cor-solene);"></span>
Sessões Solenes
</button>
<button class="filter-btn" data-filter="sessao-ordinaria">
<span class="filter-indicator" style="background: var(--cor-ordinaria);"></span>
Sessões Ordinárias
</button>
<button class="filter-btn" data-filter="feriado">
<span class="filter-indicator" style="background: var(--cor-feriado);"></span>
Feriados
</button>
<button class="filter-btn" data-filter="recesso">
<span class="filter-indicator" style="background: var(--cor-recesso);"></span>
Recessos
</button>
<button class="filter-btn" data-filter="eleicao">
<span class="filter-indicator" style="background: var(--cor-eleicao);"></span>
Eleições
</button>
</div>
<button class="print-btn" onclick="window.print()">Imprimir Calendário</button>
</div>
<div class="content-wrapper">
<h2 class="print-only titulo-calendario-print">
CALENDÁRIO LEGISLATIVO ANO 2026
</h2>
<div class="calendar-grid" id="calendar"></div>
<div class="legend">
<h2>Legenda</h2>
<div class="legend-items">
<div class="legend-item">
<div class="legend-color" style="background: var(--cor-solene);"></div>
<span>Sessões Solenes</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: var(--cor-ordinaria);"></div>
<span>Sessões Ordinárias da Câmara Municipal</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: var(--cor-feriado);"></div>
<span>Feriados Nacionais, Estaduais ou Municipais</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: var(--cor-recesso);"></div>
<span>Recessos</span>
</div>
<div class="legend-item">
<div class="legend-color" style="background: var(--cor-eleicao);"></div>
<span>Eleições 2026</span>
</div>
</div>
</div>
<div class="notes">
<h3>Observações Importantes</h3>
<ul>
<li><strong>Recesso Legislativo 2025/2026:</strong> 18 de dezembro de 2025 a 04 de fevereiro de 2026</li>
<li><strong>Recesso Legislativo 2026/2027:</strong> 17 de dezembro de 2026 a 04 de fevereiro de 2027</li>
<li><strong>Copa do Mundo 2026:</strong> 11 de junho a 19 de julho de 2026</li>
<li><strong>Eleições 2026:</strong> 1º turno em 04 de outubro e 2º turno em 25 de outubro de 2026</li>
<li><strong>Eleição da Mesa Diretora Biênio 2027/2028:</strong> 17 de dezembro de 2026</li>
<li><strong>Julho 2026:</strong> Regimentalmente, apenas duas Sessões Ordinárias</li>
</ul>
</div>
<!-- Assinatura (impressão) -->
<div class="print-only assinaturas">
<p>Manhumirim, _____ de __________ de 2026.</p>
<div class="assinatura-linha">
<div class="linha"></div>
<div class="nome">Alexandre de Jesus Nascimento</div>
<div class="cargo">Vereador Presidente</div>
</div>
</div>
<div class="footer">
Câmara Municipal de Manhumirim · Estado de Minas Gerais · Ano Legislativo de 2026
</div>
</div>
</div>
<script>
const eventos = {
"2026-01-01": { tipo: "feriado", nome: "Confraternização Universal" },
...(() => {
const r = {};
for (let d = 1; d <= 31; d++) {
r[`2026-01-${String(d).padStart(2, "0")}`] ??= {
tipo: "recesso",
nome: "Recesso Legislativo",
};
}
["02", "03", "04"].forEach((d) => {
r[`2026-02-${d}`] = { tipo: "recesso", nome: "Recesso Legislativo" };
});
return r;
})(),
"2026-02-05": { tipo: "sessao-solene", nome: "Sessão Solene de Início do Ano Legislativo" },
"2026-02-12": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-02-16": { tipo: "feriado", nome: "Segunda de Carnaval" },
"2026-02-17": { tipo: "feriado", nome: "Carnaval" },
"2026-02-18": { tipo: "recesso", nome: "Quarta-feira de Cinzas (Ponto Facultativo)" },
"2026-02-19": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-03-05": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-03-12": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-03-16": { tipo: "feriado", nome: "Dia da Cidade" },
"2026-03-19": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-04-03": { tipo: "feriado", nome: "Sexta-feira Santa" },
"2026-04-09": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-04-16": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-04-21": { tipo: "feriado", nome: "Tiradentes" },
"2026-04-23": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-05-01": { tipo: "feriado", nome: "Dia do Trabalho" },
"2026-05-07": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-05-13": { tipo: "feriado", nome: "Dia dos Sacramentinos de Nossa Senhora" },
"2026-05-14": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-05-21": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-06-04": { tipo: "feriado", nome: "Corpus Christi" },
"2026-06-11": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-06-18": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-06-25": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-07-02": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-07-09": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-08-06": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-08-13": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-08-20": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-09-04": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-09-07": { tipo: "feriado", nome: "Independência do Brasil" },
"2026-09-11": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-09-14": { tipo: "feriado", nome: "Padroeiro da Cidade - Senhor Bom Jesus" },
"2026-09-18": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-10-02": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-10-04": { tipo: "eleicao", nome: "1º Turno das Eleições 2026" },
"2026-10-09": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-10-12": { tipo: "feriado", nome: "Nossa Senhora Aparecida (Padroeira do Brasil)" },
"2026-10-16": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-10-25": { tipo: "eleicao", nome: "2º Turno das Eleições 2026" },
"2026-10-28": { tipo: "feriado", nome: "Dia do Servidor Público" },
"2026-11-02": { tipo: "feriado", nome: "Finados" },
"2026-11-05": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-11-12": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-11-15": { tipo: "feriado", nome: "Proclamação da República" },
"2026-11-19": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-11-20": { tipo: "feriado", nome: "Dia da Consciência Negra" },
"2026-12-03": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-12-10": { tipo: "sessao-ordinaria", nome: "Sessão Ordinária" },
"2026-12-17": {
tipo: "sessao-solene",
nome: "Sessão Solene de Encerramento do Ano Legislativo e Eleição da Mesa Diretora 2027/2028",
},
};
["18", "19", "20", "21", "22", "23", "24", "26", "27", "28", "29", "30", "31"].forEach((d) => {
const key = `2026-12-${d}`;
if (!eventos[key]) eventos[key] = { tipo: "recesso", nome: "Recesso Legislativo" };
});
eventos["2026-12-24"] = { tipo: "recesso", nome: "Véspera de Natal (Recesso Legislativo)" };
eventos["2026-12-25"] = { tipo: "feriado", nome: "Natal" };
eventos["2026-12-31"] = { tipo: "recesso", nome: "Véspera de Ano Novo (Recesso Legislativo)" };
const mesesNomes = [
"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho",
"Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro",
];
const diasSemana = ["D", "S", "T", "Q", "Q", "S", "S"];
const hoje = new Date();
const anoAlvo = 2026;
const mesAtualNum = hoje.getFullYear() === anoAlvo ? hoje.getMonth() : null;
const diaAtualNum = hoje.getFullYear() === anoAlvo ? hoje.getDate() : null;
function diasNoMes(ano, mes) {
return new Date(ano, mes + 1, 0).getDate();
}
function primeiroDiaSemana(ano, mes) {
return new Date(ano, mes, 1).getDay();
}
function chaveData(ano, mes, dia) {
return `${ano}-${String(mes + 1).padStart(2, "0")}-${String(dia).padStart(2, "0")}`;
}
const tooltipEl = document.getElementById("tooltip");
let diaTooltipAtual = null;
function mostrarTooltip(ev, texto) {
tooltipEl.textContent = texto;
tooltipEl.classList.add("show");
moverTooltip(ev);
}
function esconderTooltip() {
tooltipEl.classList.remove("show");
diaTooltipAtual = null;
}
function moverTooltip(ev) {
const rect = tooltipEl.getBoundingClientRect();
let left = ev.clientX + 12;
let top = ev.clientY - rect.height - 10;
if (left + rect.width > window.innerWidth) left = ev.clientX - rect.width - 12;
if (top < 0) top = ev.clientY + 16;
tooltipEl.style.left = left + "px";
tooltipEl.style.top = top + "px";
}
function montarCalendario() {
const grid = document.getElementById("calendar");
for (let m = 0; m < 12; m++) {
const mesDiv = document.createElement("div");
mesDiv.className = "month";
if (m === mesAtualNum) mesDiv.classList.add("atual");
const header = document.createElement("div");
header.className = "month-header";
const titulo = document.createElement("div");
titulo.className = "month-title";
titulo.textContent = mesesNomes[m].toUpperCase();
header.appendChild(titulo);
if (m === mesAtualNum) {
const badge = document.createElement("div");
badge.className = "badge-mes-atual";
badge.textContent = "MÊS ATUAL";
header.appendChild(badge);
}
mesDiv.appendChild(header);
const cab = document.createElement("div");
cab.className = "weekdays";
diasSemana.forEach((dn) => {
const d = document.createElement("div");
d.className = "weekday";
d.textContent = dn;
cab.appendChild(d);
});
mesDiv.appendChild(cab);
const diasDiv = document.createElement("div");
diasDiv.className = "days";
const primeiro = primeiroDiaSemana(anoAlvo, m);
const totDias = diasNoMes(anoAlvo, m);
for (let i = 0; i < primeiro; i++) {
const vazio = document.createElement("div");
vazio.className = "day empty";
diasDiv.appendChild(vazio);
}
for (let d = 1; d <= totDias; d++) {
const diaDiv = document.createElement("div");
diaDiv.className = "day";
diaDiv.textContent = d;
const chave = chaveData(anoAlvo, m, d);
if (eventos[chave]) {
const ev = eventos[chave];
diaDiv.classList.add(ev.tipo);
diaDiv.dataset.tipo = ev.tipo;
diaDiv.dataset.nome = ev.nome;
diaDiv.addEventListener("mouseenter", (e) => {
diaTooltipAtual = diaDiv;
mostrarTooltip(e, ev.nome);
});
diaDiv.addEventListener("mousemove", (e) => {
if (diaTooltipAtual === diaDiv) moverTooltip(e);
});
diaDiv.addEventListener("mouseleave", () => {
if (diaTooltipAtual === diaDiv) esconderTooltip();
});
}
if (m === mesAtualNum && d === diaAtualNum) {
diaDiv.classList.add("hoje");
}
diasDiv.appendChild(diaDiv);
}
mesDiv.appendChild(diasDiv);
grid.appendChild(mesDiv);
}
}
function configurarFiltros() {
const botoes = document.querySelectorAll(".filter-btn");
botoes.forEach((btn) => {
btn.addEventListener("click", () => {
const filtro = btn.dataset.filter;
botoes.forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
const dias = document.querySelectorAll(".day:not(.empty)");
if (filtro === "all") {
dias.forEach((d) => d.classList.remove("hidden"));
} else {
dias.forEach((d) => {
if (!d.dataset.tipo) return;
d.classList.toggle("hidden", d.dataset.tipo !== filtro);
});
}
});
});
botoes[0].classList.add("active");
}
document.addEventListener("DOMContentLoaded", () => {
montarCalendario();
configurarFiltros();
});
</script>
</body>
</html>