<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Radiadores São José — Especialistas em reparo, solda e limpeza de radiadores e sistemas de ar-condicionado em Piedade-SP. Atendimento profissional e orçamento rápido." />
<meta name="keywords" content="radiadores, arrefecimento, oficina mecanica, solda de aluminio, Piedade SP, ar-condicionado automotivo" />
<title>Radiadores São José | Piedade-SP</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;600;700&family=Roboto:wght@300;400;500&display=swap" rel="stylesheet" />
<style>
/* ==========================================================================
1. DESIGN TOKENS & ARQUITETURA DE VARIÁVEIS
========================================================================== */
:root {
--red: #C0392B;
--red-dark: #922B21;
--amber: #E8A020;
--steel: #1C1C1E;
--graphite: #2A2A2E;
--mid: #3A3A3E;
--muted: #6B6B70;
--light: #ECECEC;
--white: #FFFFFF;
--success: #2ECC71;
--error: #E74C3C;
--radius: 4px;
--max-width: 1140px;
--transition-fast: 0.25s ease;
--transition-smooth: 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* ==========================================================================
2. RESET DE PROPRIEDADES NATIVAS
========================================================================== */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
-webkit-text-size-adjust: 100%;
}
body {
font-family: 'Roboto', sans-serif;
background-color: var(--steel);
color: var(--light);
font-size: 1rem;
line-height: 1.65;
overflow-x: hidden;
padding-top: 40px;
/* Espaço para o banner superior fixo */
}
/* ==========================================================================
ANÚNCIO SUPERIOR / TOP BANNER
========================================================================== */
.top-banner {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 101;
background: linear-gradient(135deg, #922B21, #C0392B, #E8A020);
color: var(--white);
text-align: center;
padding: 10px 1rem;
font-family: 'Oswald', sans-serif;
font-size: 0.92rem;
letter-spacing: 0.05em;
text-transform: uppercase;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
gap: 0.75rem;
transition: opacity var(--transition-fast);
}
.top-banner:hover {
opacity: 0.95;
}
.top-banner span {
background-color: rgba(0, 0, 0, 0.25);
padding: 2px 8px;
border-radius: 3px;
font-size: 0.8rem;
}
.class-imagem-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
max-width: 100%;
height: auto;
padding: 20px;
box-sizing: border-box;
border-radius: 12px;
}
a {
color: inherit;
text-decoration: none;
}
ul,
ol {
list-style: none;
}
button {
font-family: inherit;
background: none;
border: none;
cursor: pointer;
}
address {
font-style: normal;
}
/* Escopo de acessibilidade para leitores de tela */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* ==========================================================================
3. ESTILOS UTILITÁRIOS COMPARTILHADOS
========================================================================== */
.container {
width: 100%;
max-width: var(--max-width);
margin-inline: auto;
padding-inline: 1.5rem;
}
.section-label {
display: inline-block;
font-family: 'Oswald', sans-serif;
font-size: 0.75rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--amber);
margin-bottom: 0.75rem;
}
.section-title {
font-family: 'Oswald', sans-serif;
font-size: clamp(1.8rem, 4vw, 2.8rem);
font-weight: 700;
color: var(--white);
line-height: 1.1;
margin-bottom: 1.25rem;
}
.divider {
width: 48px;
height: 3px;
background-color: var(--red);
margin-bottom: 1.5rem;
}
.divider-center {
margin-inline: auto;
}
/* ==========================================================================
4. COMPONENTE: HEADER & NAVEGAÇÃO
========================================================================== */
.site-header {
position: fixed;
top: 40px;
/* Ajustado para ficar abaixo do banner superior */
left: 0;
right: 0;
z-index: 100;
background-color: rgba(28, 28, 30, 0.95);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border-bottom: 2px solid var(--red);
}
.nav-inner {
display: flex;
align-items: center;
justify-content: space-between;
height: 64px;
}
.nav-logo {
display: flex;
align-items: center;
gap: 0.6rem;
}
.nav-logo svg {
width: 36px;
height: 36px;
flex-shrink: 0;
}
.nav-logo-text {
display: flex;
flex-direction: column;
line-height: 1.1;
}
.nav-logo-text strong {
font-family: 'Oswald', sans-serif;
font-size: 1.15rem;
font-weight: 700;
color: var(--white);
letter-spacing: 0.04em;
}
.nav-logo-text span {
font-size: 0.7rem;
color: var(--amber);
letter-spacing: 0.15em;
text-transform: uppercase;
}
nav ul {
display: flex;
gap: 2rem;
}
nav a {
font-family: 'Oswald', sans-serif;
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--light);
transition: color var(--transition-fast);
position: relative;
padding-bottom: 4px;
}
nav a::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background-color: var(--red);
transition: width var(--transition-fast);
}
nav a:hover {
color: var(--white);
}
nav a:hover::after {
width: 100%;
}
.nav-toggle {
display: none;
flex-direction: column;
gap: 5px;
padding: 4px;
}
.nav-toggle span {
display: block;
width: 24px;
height: 2px;
background-color: var(--light);
transition: transform var(--transition-fast), opacity var(--transition-fast);
}
.nav-toggle.active span:nth-child(1) {
transform: translateY(7px) rotate(45deg);
}
.nav-toggle.active span:nth-child(2) {
opacity: 0;
}
.nav-toggle.active span:nth-child(3) {
transform: translateY(-7px) rotate(-45deg);
}
/* ==========================================================================
5. COMPONENTE: HERO SECTION
========================================================================== */
.hero {
position: relative;
min-height: 100svh;
display: flex;
align-items: center;
overflow: hidden;
background-color: var(--steel);
}
.hero-bg {
position: absolute;
inset: 0;
background: radial-gradient(ellipse 70% 60% at 70% 50%, rgba(192, 57, 43, 0.15) 0%, transparent 70%), repeating-linear-gradient(90deg, transparent, transparent 60px, rgba(255, 255, 255, 0.015) 60px, rgba(255, 255, 255, 0.015) 61px), repeating-linear-gradient(0deg, transparent, transparent 60px, rgba(255, 255, 255, 0.015) 60px, rgba(255, 255, 255, 0.015) 61px);
}
.hero-content {
position: relative;
z-index: 1;
padding-block: 7rem 4rem;
display: grid;
grid-template-columns: 1fr 1fr;
align-items: center;
gap: 3rem;
}
.hero-eyebrow {
font-family: 'Oswald', sans-serif;
font-size: 0.78rem;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--amber);
margin-bottom: 1rem;
}
.hero-heading {
font-family: 'Oswald', sans-serif;
font-size: clamp(2.5rem, 6vw, 4rem);
font-weight: 700;
color: var(--white);
line-height: 1.05;
margin-bottom: 1.5rem;
}
.hero-heading em {
font-style: normal;
color: var(--red);
}
.hero-sub {
font-weight: 300;
font-size: 1.1rem;
color: #AEAEB2;
max-width: 480px;
margin-bottom: 2.5rem;
}
.hero-cta {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.85rem 2rem;
background-color: var(--red);
color: var(--white);
font-family: 'Oswald', sans-serif;
font-size: 1rem;
letter-spacing: 0.08em;
text-transform: uppercase;
border: 2px solid var(--red);
border-radius: var(--radius);
transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
.hero-cta:hover {
background-color: transparent;
color: var(--white);
border-color: var(--white);
}
.hero-visual {
display: flex;
justify-content: center;
align-items: center;
}
.radiator-wrap {
position: relative;
width: 280px;
height: 280px;
}
.radiator-glow {
position: absolute;
inset: -20px;
border-radius: 50%;
background: radial-gradient(circle, rgba(192, 57, 43, 0.35) 0%, transparent 70%);
animation: pulse-animation 3s ease-in-out infinite;
}
.radiator-svg {
width: 100%;
height: 100%;
animation: float-animation 4s ease-in-out infinite;
}
@keyframes pulse-animation {
0%,
100% {
opacity: 0.5;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1.05);
}
}
@keyframes float-animation {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
/* ==========================================================================
6. SEÇÃO: SOBRE NÓS
========================================================================== */
.sobre {
padding-block: 6rem;
background-color: var(--graphite);
}
.sobre-galeria {
margin-bottom: 3rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.25rem;
}
.sobre-foto {
border-radius: var(--radius);
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.35);
background-color: var(--steel);
display: flex;
align-items: center;
justify-content: center;
}
.sobre-foto img {
width: 100%;
max-height: 320px;
object-fit: contain;
filter: saturate(0.95) contrast(1.05);
}
.sobre-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: center;
}
.sobre-text p {
color: #AEAEB2;
margin-bottom: 1.25rem;
}
.sobre-text p:last-of-type {
margin-bottom: 0;
}
.sobre-stats {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1.5rem;
}
.stat-card {
background-color: var(--mid);
border: 1px solid rgba(255, 255, 255, 0.06);
border-top: 3px solid var(--red);
padding: 1.75rem 1.5rem;
border-radius: var(--radius);
}
.stat-number {
font-family: 'Oswald', sans-serif;
font-size: 2.5rem;
font-weight: 700;
color: var(--amber);
line-height: 1;
margin-bottom: 0.5rem;
}
.stat-label {
font-size: 0.85rem;
color: #AEAEB2;
letter-spacing: 0.05em;
}
/* ==========================================================================
7. SEÇÃO: SERVIÇOS TÉCNICOS
========================================================================== */
.servicos {
padding-block: 6rem;
background-color: var(--steel);
}
.servicos-header {
text-align: center;
max-width: 600px;
margin-inline: auto;
margin-bottom: 4rem;
}
.section-subtitle {
color: #AEAEB2;
font-size: 0.95rem;
}
.servicos-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
}
.service-card {
background-color: var(--graphite);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: var(--radius);
padding: 2.25rem 1.75rem;
transition: transform var(--transition-fast), border-color var(--transition-fast);
position: relative;
overflow: hidden;
}
.service-card::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 3px;
background-color: var(--red);
transform: scaleX(0);
transform-origin: left;
transition: transform var(--transition-fast);
}
.service-card:hover {
transform: translateY(-4px);
border-color: rgba(192, 57, 43, 0.4);
}
.service-card:hover::before {
transform: scaleX(1);
}
.service-icon {
width: 52px;
height: 52px;
background-color: rgba(192, 57, 43, 0.15);
border-radius: var(--radius);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.5rem;
}
.service-icon svg {
width: 28px;
height: 28px;
stroke: var(--red);
}
.service-title {
font-family: 'Oswald', sans-serif;
font-size: 1.25rem;
font-weight: 600;
color: var(--white);
margin-bottom: 0.75rem;
}
.service-desc {
font-size: 0.92rem;
color: #AEAEB2;
line-height: 1.6;
}
/* ==========================================================================
8. SEÇÃO: HORÁRIO & FLUXO DE ATENDIMENTO
========================================================================== */
.horario {
padding-block: 6rem;
background-color: var(--graphite);
}
.horario-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4rem;
align-items: center;
}
.horario-subtext {
color: #AEAEB2;
font-size: 1rem;
margin-bottom: 2rem;
}
.badge-open {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.4rem 1rem;
background-color: rgba(62, 62, 66, 0.5);
border: 1px solid var(--muted);
border-radius: 999px;
font-size: 0.8rem;
font-family: 'Oswald', sans-serif;
letter-spacing: 0.08em;
text-transform: uppercase;
transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.badge-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--muted);
}
.badge-open.active-true {
color: var(--success);
background-color: rgba(39, 174, 96, 0.1);
border-color: rgba(39, 174, 96, 0.3);
}
.badge-open.active-true .badge-dot {
background-color: var(--success);
animation: blink-animation 1.5s ease infinite;
}
.badge-open.active-false {
color: var(--error);
background-color: rgba(231, 76, 60, 0.1);
border-color: rgba(231, 76, 60, 0.3);
}
.badge-open.active-false .badge-dot {
background-color: var(--error);
animation: none;
}
@keyframes blink-animation {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.4;
}
}
.horario-table {
width: 100%;
border-collapse: collapse;
}
.horario-table tr {
border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
.horario-table tr:last-child {
border-bottom: none;
}
.horario-table th,
.horario-table td {
padding: 1rem 0;
font-size: 0.95rem;
color: #AEAEB2;
text-align: left;
}
.horario-table th {
font-weight: 500;
color: var(--white);
padding-right: 2rem;
}
.horario-table .closed {
color: var(--muted);
font-style: italic;
}
.horario-note {
margin-top: 1.5rem;
padding: 1rem 1.25rem;
background-color: rgba(232, 160, 32, 0.06);
border-left: 3px solid var(--amber);
border-radius: 0 var(--radius) var(--radius) 0;
font-size: 0.88rem;
color: #AEAEB2;
}
.feriado-alert {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin-bottom: 1.5rem;
padding: 1rem 1.25rem;
background-color: rgba(231, 76, 60, 0.1);
border: 1px solid rgba(231, 76, 60, 0.3);
border-left: 3px solid var(--error);
border-radius: 0 var(--radius) var(--radius) 0;
font-size: 0.92rem;
color: var(--white);
}
.feriado-alert[hidden] {
display: none;
}
.feriado-alert.is-facultativo {
background-color: rgba(232, 160, 32, 0.08);
border-color: rgba(232, 160, 32, 0.3);
border-left-color: var(--amber);
}
.feriado-alert strong {
display: block;
font-family: 'Oswald', sans-serif;
letter-spacing: 0.06em;
text-transform: uppercase;
margin-bottom: 0.15rem;
}
.feriados-proximos {
margin-top: 2rem;
}
.feriados-proximos h3 {
font-family: 'Oswald', sans-serif;
font-size: 0.85rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--amber);
margin-bottom: 0.25rem;
}
.feriados-proximos .tag-escopo {
display: inline-block;
margin-left: 0.5rem;
padding: 0.1rem 0.5rem;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 999px;
font-size: 0.68rem;
letter-spacing: 0.06em;
text-transform: uppercase;
font-style: normal;
color: #AEAEB2;
}
.feriados-proximos td.closed {
text-align: right;
white-space: nowrap;
}
/* ==========================================================================
9. SEÇÃO: LOCALIZAÇÃO E MAPA (IFRAME)
========================================================================== */
.localizacao {
padding-block: 6rem;
background-color: var(--steel);
}
.localizacao-header {
margin-bottom: 3rem;
}
.localizacao-grid {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 2.5rem;
align-items: start;
}
.localizacao-info {
background-color: var(--graphite);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: var(--radius);
padding: 2rem;
}
.info-item {
display: flex;
gap: 1rem;
margin-bottom: 1.75rem;
}
.info-item:last-child {
margin-bottom: 0;
}
.info-icon {
width: 44px;
height: 44px;
background-color: rgba(192, 57, 43, 0.15);
border-radius: var(--radius);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.info-icon svg {
width: 22px;
height: 22px;
stroke: var(--red);
}
.info-text strong {
display: block;
font-family: 'Oswald', sans-serif;
font-size: 0.8rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--amber);
margin-bottom: 0.35rem;
}
.info-text p,
.info-text a {
font-size: 0.95rem;
color: #AEAEB2;
transition: color var(--transition-fast);
}
.info-text a:hover {
color: var(--white);
}
.map-wrap {
border-radius: var(--radius);
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08);
height: 400px;
}
.map-wrap iframe {
width: 100%;
height: 100%;
border: none;
filter: grayscale(20%) invert(8%);
}
/* ==========================================================================
10. SEÇÃO: REDES SOCIAIS E ENGAJAMENTO
========================================================================== */
.redes {
padding-block: 5rem;
background-color: var(--graphite);
text-align: center;
}
.redes-sub {
color: #AEAEB2;
max-width: 520px;
margin-inline: auto;
font-size: 0.98rem;
}
.redes-btns {
display: flex;
justify-content: center;
gap: 1.25rem;
flex-wrap: wrap;
margin-top: 2.5rem;
}
.social-btn {
display: inline-flex;
align-items: center;
gap: 0.75rem;
padding: 0.9rem 2.25rem;
font-family: 'Oswald', sans-serif;
font-size: 1rem;
letter-spacing: 0.06em;
text-transform: uppercase;
border-radius: var(--radius);
transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.social-btn svg {
width: 20px;
height: 20px;
}
.btn-instagram {
background: linear-gradient(135deg, #E1306C, #F77737, #FCAF45);
color: var(--white);
}
.btn-facebook {
background-color: #1877F2;
color: var(--white);
}
.social-btn:hover {
opacity: 0.9;
transform: translateY(-2px);
}
/* ==========================================================================
11. COMPONENTE: FOOTER INSTITUCIONAL
========================================================================== */
.site-footer {
background-color: #111113;
border-top: 2px solid var(--red);
padding: 2.5rem 0;
text-align: center;
}
.site-footer p {
font-size: 0.85rem;
color: var(--muted);
}
.site-footer strong {
color: var(--white);
}
/* ==========================================================================
12. REGRAS DE RESPONSIVIDADE E ADAPTAÇÃO (MEDIA QUERIES)
========================================================================== */
@media (max-width: 960px) {
.hero-content {
grid-template-columns: 1fr;
text-align: center;
padding-block: 6rem 3rem;
}
.hero-visual {
display: none;
}
.hero-sub {
margin-inline: auto;
}
.sobre-galeria {
grid-template-columns: 1fr 1fr;
}
.sobre-grid,
.horario-inner,
.localizacao-grid {
grid-template-columns: 1fr;
gap: 3rem;
}
.sobre-stats {
order: -1;
}
}
@media (max-width: 640px) {
.nav-inner {
height: 60px;
}
.nav-toggle {
display: flex;
}
nav ul {
display: none;
flex-direction: column;
position: fixed;
inset: 60px 0 0 0;
background-color: var(--steel);
padding: 2.5rem 1.5rem;
gap: 2rem;
z-index: 99;
overflow-y: auto;
}
nav ul.open {
display: flex;
}
nav a {
font-size: 1.25rem;
display: block;
}
.redes-btns {
flex-direction: column;
align-items: stretch;
}
.social-btn {
justify-content: center;
}
.sobre-galeria {
grid-template-columns: 1fr;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
.radiator-glow,
.radiator-svg,
.badge-open.active-true .badge-dot {
animation: none !important;
}
}
</style>
</head>
<body>
<!-- ANÚNCIO SUPERIOR / BANNER DE DIVULGAÇÃO DO LIVRO -->
<a href="https://a.co/d/0h5szaLb" target="_blank" rel="noopener noreferrer" class="top-banner" aria-label="Comprar livro Engenharia de Software na Amazon">
<span>Lançamento</span>
<strong>Livro Engenharia de Software — Garanta o seu exemplar na Amazon! 🚀</strong>
</a>
<header class="site-header">
<div class="container nav-inner">
<a href="#inicio" class="nav-logo" aria-label="Radiadores São José — Página inicial">
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
<rect x="2" y="8" width="4" height="20" rx="1" fill="#C0392B" />
<rect x="8" y="5" width="4" height="26" rx="1" fill="#E8A020" />
<rect x="14" y="8" width="4" height="20" rx="1" fill="#C0392B" />
<rect x="20" y="5" width="4" height="26" rx="1" fill="#E8A020" />
<rect x="26" y="8" width="4" height="20" rx="1" fill="#C0392B" />
<rect x="2" y="6" width="32" height="3" rx="1" fill="#ECECEC" />
<rect x="2" y="27" width="32" height="3" rx="1" fill="#ECECEC" />
</svg>
<div class="nav-logo-text">
<strong>Radiadores São José</strong>
<span>Piedade · SP</span>
</div>
</a>
<nav aria-label="Menu principal">
<button type="button" class="nav-toggle" id="js-nav-toggle" aria-label="Abrir menu" aria-expanded="false" aria-controls="nav-menu">
<span></span><span></span><span></span>
</button>
<ul id="nav-menu">
<li><a href="#sobre">Sobre</a></li>
<li><a href="#servicos">Serviços</a></li>
<li><a href="#horario">Horário</a></li>
<li><a href="#localizacao">Localização</a></li>
<li><a href="#contato">Contato</a></li>
</ul>
</nav>
</div>
</header>
<main id="main-content">
<section class="hero" id="inicio" aria-label="Apresentação da Oficina">
<div class="hero-bg" aria-hidden="true"></div>
<div class="container">
<div class="hero-content">
<div class="hero-text">
<p class="hero-eyebrow">Especialistas em Arrefecimento · Piedade-SP</p>
<h1 class="hero-heading">
Seu motor<br />
<em>sempre frio,</em><br /> seu carro<br />sempre na estrada.
</h1>
<p class="hero-sub">
Reparo, solda e limpeza de radiadores com precisão e rapidez. Atendemos veículos de passeio, utilitários e linhas pesadas.
</p>
<a href="#servicos" class="hero-cta">
Ver serviços
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M5 12h14M12 5l7 7-7 7" />
</svg>
</a>
</div>
<div class="hero-visual" aria-hidden="true">
<div class="radiator-wrap">
<div class="radiator-glow"></div>
<svg class="radiator-svg" viewBox="0 0 260 260" fill="none" xmlns="http://www.w3.org/2000/svg" focusable="false">
<rect x="30" y="50" width="200" height="160" rx="6" fill="#2A2A2E" stroke="#3A3A3E" stroke-width="2" />
<rect x="48" y="65" width="20" height="130" rx="3" fill="#C0392B" opacity="0.9" />
<rect x="78" y="58" width="20" height="144" rx="3" fill="#E8A020" opacity="0.85" />
<rect x="108" y="65" width="20" height="130" rx="3" fill="#C0392B" opacity="0.9" />
<rect x="138" y="58" width="20" height="144" rx="3" fill="#E8A020" opacity="0.85" />
<rect x="168" y="65" width="20" height="130" rx="3" fill="#C0392B" opacity="0.9" />
<rect x="198" y="58" width="20" height="144" rx="3" fill="#E8A020" opacity="0.7" />
<rect x="30" y="48" width="200" height="16" rx="4" fill="#1C1C1E" stroke="#3A3A3E" stroke-width="1.5" />
<rect x="30" y="196" width="200" height="16" rx="4" fill="#1C1C1E" stroke="#3A3A3E" stroke-width="1.5" />
<circle cx="50" cy="38" r="8" fill="#3A3A3E" stroke="#C0392B" stroke-width="2" />
<circle cx="210" cy="38" r="8" fill="#3A3A3E" stroke="#C0392B" stroke-width="2" />
<circle cx="50" cy="222" r="8" fill="#3A3A3E" stroke="#C0392B" stroke-width="2" />
<circle cx="210" cy="222" r="8" fill="#3A3A3E" stroke="#C0392B" stroke-width="2" />
<path d="M 80 240 Q 90 232 100 240 Q 110 248 120 240 Q 130 232 140 240" stroke="#E8A020" stroke-width="2" fill="none" stroke-linecap="round" opacity="0.6" />
<path d="M 100 252 Q 110 244 120 252 Q 130 260 140 252 Q 150 244 160 252" stroke="#C0392B" stroke-width="2" fill="none" stroke-linecap="round" opacity="0.4" />
</svg>
</div>
</div>
</div>
</div>
</section>
<section class="sobre" id="sobre" aria-labelledby="sobre-titulo">
<div class="container">
<div class="sobre-galeria" aria-label="Galeria de fotos da oficina">
<figure class="sobre-foto">
<img src="https://scontent-gru2-1.xx.fbcdn.net/v/t39.30808-6/476230593_3795257997403965_3277230059403823941_n.jpg?stp=dst-jpg_tt6&cstp=mx2048x1536&ctp=s2048x1536&_nc_cat=111&ccb=1-7&_nc_sid=833d8c&_nc_eui2=AeEm5rB2WU4y10hh9UgA9ojBTKf81832IjpMp_zXzfYiOvELz7e8wZogpQQtAeI7hlNjmUSZR2uXjSyAABYLD46y&_nc_ohc=EWQT8LjvkZkQ7kNvwHmrVhL&_nc_oc=AdpzLk3hI60RTy56GX3FWrnaRxKgMEchxTWu2MkLJuaSW5Ziyq6vZbO0Oi6AqmQt_3aPlb4caAIYGn2dxS3KtOaj&_nc_zt=23&_nc_ht=scontent-gru2-1.xx&_nc_gid=XHBhpMcct5EofQmSGmkecA&_nc_ss=7b2a8&oh=00_AQQ9xa4CpGpSNH5qnzRGQxAI7qqh9FV5VLwpgHIHPG-CaA&oe=6AEDF6C9 "
alt="Fachada e área de atendimento da oficina Radiadores São José em Piedade-SP" loading="lazy" />
</figure>
<figure class="sobre-foto">
<img src="https://scontent-gru1-2.xx.fbcdn.net/v/t39.30808-6/475803383_3789314564664975_3250263739315324764_n.jpg?stp=dst-jpg_tt6&cstp=mx2048x1536&ctp=s2048x1536&_nc_cat=108&ccb=1-7&_nc_sid=833d8c&_nc_eui2=AeFALF-4b2YhaPOvqxjvo8N2luAO6rLA3eSW4A7qssDd5KUIxCPPN_EW2lYaO3IbiIkCAJTLVZbvl3PNOio9DVMD&_nc_ohc=l1PBfYuzq0IQ7kNvwHJDABv&_nc_oc=AdqcIMt5SoRqJTR49bPFvvPF3d4zIpU3G7frmOD6S8KeFqZzbP-fKJU5Wvsn4lbJxepNwPpdhR94xbI1Gbi-x5TT&_nc_zt=23&_nc_ht=scontent-gru1-2.xx&_nc_gid=Ok-TcTOH_BUiWFEPEBsb8w&_nc_ss=7b2a8&oh=00_AQQ1DHb0djOiCckDIcjtHg00fWYC88dhwoAmQYD8QmLvGg&oe=6AEDF530"
alt="Carro da oficina Radiadores São José em Piedade-SP" loading="lazy" />
</figure>
<figure class="sobre-foto">
<img src="https://scontent-gru1-1.xx.fbcdn.net/v/t39.30808-6/470683870_3757874757808956_2229542935994204590_n.jpg?stp=dst-jpg_tt6&cstp=mx1032x464&ctp=s1032x464&_nc_cat=110&ccb=1-7&_nc_sid=833d8c&_nc_eui2=AeHgN4WeU7bnDmVd-KZSssLF1yBdoDy648bXIF2gPLrjxk7qYjBGyIRU7cP2tEl2LFVrINohWSl1_61ydQPAqVZg&_nc_ohc=R_aVb2NSZw0Q7kNvwESHQ6_&_nc_oc=AdrdifI4yDyhtzDosHhgB6wPK4FGAJXmucmKjULVjHA5PZSHQW3lryQw56THvH6YWb_odl4zEWdLRHnfaNa7zudZ&_nc_zt=23&_nc_ht=scontent-gru1-1.xx&_nc_gid=UbCKw76ndm04p_ny_FjcRQ&_nc_ss=7b2a8&oh=00_AQTbxYDydjgBIOz_J4mvGzKs1OJa9bK2ugr9r6stqcsOtA&oe=6AEDFDF9"
alt="Carro de cliente na oficina Radiadores São José em Piedade-SP" loading="lazy" />
</figure>
</div>
</div>
<div class="container sobre-grid">
<div class="sobre-text">
<span class="section-label">Quem somos</span>
<h2 class="section-title" id="sobre-titulo">Tradição e especialidade em radiadores</h2>
<div class="divider" aria-hidden="true"></div>
<p>
A <strong>Radiadores São José</strong> é uma oficina altamente especializada em sistemas de arrefecimento automotivo, localizada em Piedade-SP. Com anos de atuação consistente no mercado regional, somos a escolha de confiança para
motoristas e frotas corporativas que demandam diagnósticos precisos e resoluções ágeis.
</p>
<p>
Nossa infraestrutura técnica permite atender desde veículos leves de passeio até utilitários e caminhões pesados, priorizando a transparência e a qualidade dos componentes utilizados.
</p>
</div>
<ul class="sobre-stats" aria-label="Destaques da oficina">
<li class="stat-card">
<div class="stat-number">Desde 1979</div>
<div class="stat-label">Anos de experiência no setor automotivo</div>
</li>
<li class="stat-card">
<div class="stat-number">100%</div>
<div class="stat-label">Comprometimento com a qualidade do serviço</div>
</li>
<li class="stat-card">
<div class="stat-number">5×</div>
<div class="stat-label">Dias na semana à disposição do cliente</div>
</li>
<li class="stat-card">
<div class="stat-number">✓</div>
<div class="stat-label">Orçamento rápido e estruturado</div>
</li>
</ul>
</div>
</section>
<section class="servicos" id="servicos" aria-labelledby="servicos-titulo">
<div class="container">
<header class="servicos-header">
<span class="section-label">O que fazemos</span>
<h2 class="section-title" id="servicos-titulo">Nossos serviços</h2>
<div class="divider divider-center" aria-hidden="true"></div>
<p class="section-subtitle">
Especialistas em sistemas de arrefecimento e ar-condicionado, cuidamos do seu radiador do diagnóstico à entrega.
</p>
</header>
<div class="servicos-grid">
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" />
</svg>
</div>
<h3 class="service-title">Reparo de Radiadores</h3>
<p class="service-desc">
Identificamos e corrigimos vazamentos, entupimentos e deformidades estruturais no componente, restabelecendo a performance térmica nominal.
</p>
</article>
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z" />
</svg>
</div>
<h3 class="service-title">Solda Especializada</h3>
<p class="service-desc">
Soldagem técnica de alta precisão em ligas de alumínio e cobre, garantindo estanqueidade total e resistência mecânica a altas pressões.
</p>
</article>
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z" />
</svg>
</div>
<h3 class="service-title">Limpeza Interna</h3>
<p class="service-desc">
Desobstrução química e mecânica interna das galerias (colmeias), eliminando depósitos minerais e oxidações que bloqueiam o fluxo de fluído.
</p>
</article>
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="1 4 1 10 7 10" />
<polyline points="23 20 23 14 17 14" />
<path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15" />
</svg>
</div>
<h3 class="service-title">Troca de Colmeia</h3>
<p class="service-desc">
Substituição completa do núcleo dissipador avariado por blocos novos de alto rendimento, prolongando a vida útil do conjunto estrutural.
</p>
</article>
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="12" />
<line x1="12" y1="16" x2="12.01" y2="16" />
</svg>
</div>
<h3 class="service-title">Diagnóstico do Sistema</h3>
<p class="service-desc">
Análise rigorosa do circuito: integridade de mangueiras, tampas, caixas plásticas, estanqueidade do bloco e atuação do eletroventilador.
</p>
</article>
<article class="service-card">
<div class="service-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="1" y="3" width="15" height="13" />
<polygon points="16 8 20 8 23 11 23 16 16 16 16 8" />
<circle cx="5.5" cy="18.5" r="2.5" />
<circle cx="18.5" cy="18.5" r="2.5" />
</svg>
</div>
<h3 class="service-title">Ar-condicionado</h3>
<p class="service-desc">
Manutenção corretiva e preventiva de sistemas de climatização para frotas leves, utilitários pesados, ônibus e maquinários agrícolas.
</p>
</article>
</div>
</div>
</section>
<section class="horario" id="horario" aria-labelledby="horario-titulo">
<div class="container horario-inner">
<div>
<span class="section-label">Quando atendemos</span>
<h2 class="section-title" id="horario-titulo">Horário de<br />funcionamento</h2>
<div class="divider" aria-hidden="true"></div>
<p class="horario-subtext">
Oferecemos suporte operacional de segunda a sexta-feira para garantir o menor tempo de parada para o seu veículo.
</p>
<div class="badge-open" id="js-status-badge" aria-live="polite">
<span class="badge-dot" aria-hidden="true"></span>
<span id="status-text">Verificando disponibilidade de atendimento…</span>
</div>
</div>
<div>
<div class="feriado-alert" id="holiday-alert" role="status" aria-live="polite" hidden></div>
<table class="horario-table" aria-label="Tabela detalhada de horários de funcionamento">
<thead class="sr-only">
<tr>
<th scope="col">Dia da semana</th>
<th scope="col">Horário de atendimento</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Segunda-feira</th>
<td>08:00 – 18:00</td>
</tr>
<tr>
<th scope="row">Terça-feira</th>
<td>08:00 – 18:00</td>
</tr>
<tr>
<th scope="row">Quarta-feira</th>
<td>08:00 – 18:00</td>
</tr>
<tr>
<th scope="row">Quinta-feira</th>
<td>08:00 – 18:00</td>
</tr>
<tr>
<th scope="row">Sexta-feira</th>
<td>08:00 – 18:00</td>
</tr>
<tr>
<th scope="row">Sábado</th>
<td class="closed">Fechado</td>
</tr>
<tr>
<th scope="row">Domingo</th>
<td class="closed">Fechado</td>
</tr>
</tbody>
</table>
<div class="feriados-proximos" id="upcoming-holidays" hidden>
<h3>Próximos feriados (fechado)</h3>
<table class="horario-table" aria-label="Próximos feriados em que a oficina estará fechada">
<tbody id="upcoming-holidays-body"></tbody>
</table>
</div>
<aside class="horario-note" aria-label="Observação sobre feriados">
<strong>Informativo:</strong> Não abrimos aos sábados, domingos e feriados nacionais, estaduais (SP) e municipais (Piedade-SP). Em pontos facultativos (Carnaval, Corpus Christi), confirme o atendimento pelo WhatsApp.
</aside>
</div>
</div>
</section>
<section class="localizacao" id="localizacao" aria-labelledby="loc-titulo">
<div class="container">
<header class="localizacao-header">
<span class="section-label">Onde estamos</span>
<h2 class="section-title" id="loc-titulo">Localização da Oficina</h2>
<div class="divider" aria-hidden="true"></div>
</header>
<div class="localizacao-grid">
<address class="localizacao-info" aria-label="Informações de contato e endereço">
<div class="info-item">
<div class="info-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" />
<circle cx="12" cy="10" r="3" />
</svg>
</div>
<div class="info-text">
<strong>Endereço Oficial</strong>
<p>
Av. Raymundo Nonato Leite, nº 451, Centro.<br />
Piedade–SP, CEP 18170-007
</p>
</div>
</div>
<div class="info-item">
<div class="info-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" />
</svg>
</div>
<div class="info-text">
<strong>Contato Telefônico / WhatsApp</strong>
<p><a href="https://wa.me/5515998042715" target="_blank" rel="noopener noreferrer" title="Contatar via WhatsApp">(15) 99804-2715</a></p>
</div>
</div>
<div class="info-item">
<div class="info-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />
</svg>
</div>
<div class="info-text">
<strong>Canais Digitais</strong>
<p>
<a href="https://www.instagram.com/radiadoressaojosepiedade/" target="_blank" rel="noopener noreferrer">Instagram</a>
·
<a href="https://www.facebook.com/radiadoressaojosepiedadesp/" target="_blank" rel="noopener noreferrer">Facebook</a>
</p>
</div>
</div>
</address>
<div class="map-wrap">
<iframe src="https://maps.google.com/maps?q=Radiadores+S%C3%A3o+Jos%C3%A9+Piedade+SP&output=embed" loading="lazy" title="Mapa interativo de localização da oficina Radiadores São José" allowfullscreen></iframe>
</div>
</div>
</div>
</section>
<section class="redes" id="contato" aria-labelledby="contato-titulo">
<div class="container">
<span class="section-label">Siga e compartilhe</span>
<h2 class="section-title" id="contato-titulo">Canais de Atendimento e Redes</h2>
<div class="divider divider-center" aria-hidden="true"></div>
<p class="redes-sub">
Acompanhe relatórios de serviços executados, dicas essenciais de prevenção térmica e novidades operacionais diretas de nossa oficina.
</p>
<div class="redes-btns">
<a href="https://www.instagram.com/radiadoressaojosepiedade/" target="_blank" rel="noopener noreferrer" class="social-btn btn-instagram" aria-label="Acessar perfil corporativo no Instagram (Abre em nova aba)">
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm6.406-11.845a1.44 1.44 0 1 0 0 2.881 1.44 1.44 0 0 0 0-2.881z" />
</svg> Instagram
</a>
<a href="https://www.facebook.com/radiadoressaojosepiedadesp/" target="_blank" rel="noopener noreferrer" class="social-btn btn-facebook" aria-label="Acessar página institucional no Facebook (Abre em nova aba)">
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" />
</svg> Facebook
</a>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container">
<p>
© <span id="current-year">2026</span> <strong>Radiadores São José</strong> — Piedade-SP. Telefone: (15) 99804-2715. Todos os direitos reservados.
</p>
</div>
</footer>
<script>
document.addEventListener('DOMContentLoaded', () => {
initCurrentYear();
initTimeVerification();
initMobileMenu();
});
function initCurrentYear() {
const yearElement = document.getElementById('current-year');
if (yearElement) {
yearElement.textContent = new Date().getFullYear();
}
}
/* ==========================================================================
CALENDÁRIO DE FERIADOS — Brasil, Estado de São Paulo e Piedade-SP
========================================================================== */
const HOLIDAY_TIMEZONE = 'America/Sao_Paulo';
// Pontos facultativos (Carnaval, Corpus Christi) não são feriado por lei.
// Troque para true se a oficina também fecha nesses dias.
const CLOSE_ON_OPTIONAL_DAYS = false;
const FIXED_HOLIDAYS = [
{ month: 1, day: 1, name: 'Confraternização Universal', scope: 'nacional' },
{ month: 4, day: 21, name: 'Tiradentes', scope: 'nacional' },
{ month: 5, day: 1, name: 'Dia do Trabalhador', scope: 'nacional' },
{ month: 9, day: 7, name: 'Independência do Brasil', scope: 'nacional' },
{ month: 10, day: 12, name: 'Nossa Senhora Aparecida', scope: 'nacional' },
{ month: 11, day: 2, name: 'Finados', scope: 'nacional' },
{ month: 11, day: 15, name: 'Proclamação da República', scope: 'nacional' },
{ month: 11, day: 20, name: 'Consciência Negra', scope: 'nacional' },
{ month: 12, day: 25, name: 'Natal', scope: 'nacional' },
{ month: 7, day: 9, name: 'Revolução Constitucionalista', scope: 'estadual' },
{ month: 5, day: 20, name: 'Aniversário de Piedade', scope: 'municipal' }
];
const SCOPE_LABELS = {
nacional: 'Nacional',
estadual: 'Estadual (SP)',
municipal: 'Municipal (Piedade)',
facultativo: 'Ponto facultativo'
};
const WEEKDAY_NAMES = ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'];
const MONTH_NAMES = ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'];
// Domingo de Páscoa (algoritmo de Meeus/Jones/Butcher)
function calculateEaster(year) {
const a = year % 19;
const b = Math.floor(year / 100);
const c = year % 100;
const d = Math.floor(b / 4);
const e = b % 4;
const f = Math.floor((b + 8) / 25);
const g = Math.floor((b - f + 1) / 3);
const h = (19 * a + b - d - g + 15) % 30;
const i = Math.floor(c / 4);
const k = c % 4;
const l = (32 + 2 * e + 2 * i - h - k) % 7;
const m = Math.floor((a + 11 * h + 22 * l) / 451);
const month = Math.floor((h + l - 7 * m + 114) / 31);
const day = ((h + l - 7 * m + 114) % 31) + 1;
return { month, day };
}
function addDays(year, month, day, offset) {
const date = new Date(Date.UTC(year, month - 1, day + offset));
return { month: date.getUTCMonth() + 1, day: date.getUTCDate() };
}
function buildDateKey(year, month, day) {
return year + '-' + String(month).padStart(2, '0') + '-' + String(day).padStart(2, '0');
}
const holidayCache = {};
function getHolidaysForYear(year) {
if (holidayCache[year]) return holidayCache[year];
const holidays = {};
FIXED_HOLIDAYS.forEach(h => {
holidays[buildDateKey(year, h.month, h.day)] = { name: h.name, scope: h.scope };
});
const easter = calculateEaster(year);
const movable = [
{ offset: -48, name: 'Carnaval (segunda-feira)', scope: 'facultativo' },
{ offset: -47, name: 'Carnaval (terça-feira)', scope: 'facultativo' },
{ offset: -2, name: 'Sexta-feira Santa', scope: 'nacional' },
{ offset: 60, name: 'Corpus Christi', scope: 'facultativo' }
];
movable.forEach(m => {
const d = addDays(year, easter.month, easter.day, m.offset);
holidays[buildDateKey(year, d.month, d.day)] = { name: m.name, scope: m.scope };
});
holidayCache[year] = holidays;
return holidays;
}
function getHolidayFor(year, month, day) {
return getHolidaysForYear(year)[buildDateKey(year, month, day)] || null;
}
function isClosingHoliday(holiday) {
if (!holiday) return false;
return holiday.scope !== 'facultativo' || CLOSE_ON_OPTIONAL_DAYS;
}
// Data/hora atual no fuso de São Paulo, independente do fuso do visitante
function getSaoPauloNow() {
const parts = new Intl.DateTimeFormat('en-US', {
timeZone: HOLIDAY_TIMEZONE,
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: false
}).formatToParts(new Date());
const values = {};
parts.forEach(p => { values[p.type] = parseInt(p.value, 10); });
const year = values.year;
const month = values.month;
const day = values.day;
const hour = values.hour === 24 ? 0 : values.hour;
const weekday = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
return { year, month, day, weekday, minutes: hour * 60 + values.minute };
}
function formatDatePt(year, month, day) {
const weekday = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
const capitalized = WEEKDAY_NAMES[weekday].charAt(0).toUpperCase() + WEEKDAY_NAMES[weekday].slice(1);
return capitalized + ', ' + day + ' de ' + MONTH_NAMES[month - 1];
}
function findUpcomingClosingHolidays(now, limit) {
const results = [];
for (let offset = 1; offset <= 400 && results.length < limit; offset++) {
const d = addDays(now.year, now.month, now.day, offset);
const year = new Date(Date.UTC(now.year, now.month - 1, now.day + offset)).getUTCFullYear();
const holiday = getHolidayFor(year, d.month, d.day);
const weekday = new Date(Date.UTC(year, d.month - 1, d.day)).getUTCDay();
if (isClosingHoliday(holiday) && weekday >= 1 && weekday <= 5) {
results.push({ year, month: d.month, day: d.day, holiday });
}
}
return results;
}
function renderHolidayAlert(now, todayHoliday) {
const alertBox = document.getElementById('holiday-alert');
if (!alertBox) return;
let tomorrowHoliday = null;
const t = addDays(now.year, now.month, now.day, 1);
const tomorrowYear = new Date(Date.UTC(now.year, now.month - 1, now.day + 1)).getUTCFullYear();
tomorrowHoliday = getHolidayFor(tomorrowYear, t.month, t.day);
let title = '';
let message = '';
let isOptional = false;
if (todayHoliday && isClosingHoliday(todayHoliday)) {
title = 'Fechado hoje — Feriado';
message = todayHoliday.name + ' (' + SCOPE_LABELS[todayHoliday.scope] + '). Retornamos no próximo dia útil. Faça seu orçamento via WhatsApp.';
} else if (todayHoliday) {
isOptional = true;
title = 'Hoje é ponto facultativo';
message = todayHoliday.name + '. Confirme o atendimento pelo WhatsApp antes de vir.';
} else if (tomorrowHoliday && isClosingHoliday(tomorrowHoliday)) {
title = 'Aviso: amanhã estaremos fechados';
message = 'Feriado de ' + tomorrowHoliday.name + ' (' + SCOPE_LABELS[tomorrowHoliday.scope] + ').';
} else if (tomorrowHoliday) {
isOptional = true;
title = 'Amanhã é ponto facultativo';
message = tomorrowHoliday.name + '. Confirme o atendimento pelo WhatsApp.';
}
if (!title) {
alertBox.hidden = true;
return;
}
alertBox.classList.toggle('is-facultativo', isOptional);
alertBox.textContent = '';
const strong = document.createElement('strong');
strong.textContent = title;
const text = document.createElement('span');
text.textContent = message;
const wrapper = document.createElement('div');
wrapper.appendChild(strong);
wrapper.appendChild(text);
alertBox.appendChild(wrapper);
alertBox.hidden = false;
}
function renderUpcomingHolidays(now) {
const container = document.getElementById('upcoming-holidays');
const body = document.getElementById('upcoming-holidays-body');
if (!container || !body) return;
const upcoming = findUpcomingClosingHolidays(now, 5);
body.textContent = '';
if (upcoming.length === 0) {
container.hidden = true;
return;
}
upcoming.forEach(item => {
const row = document.createElement('tr');
const th = document.createElement('th');
th.scope = 'row';
th.textContent = formatDatePt(item.year, item.month, item.day);
const holidayName = document.createElement('div');
holidayName.style.fontWeight = '400';
holidayName.style.fontSize = '0.82rem';
holidayName.style.color = '#AEAEB2';
holidayName.textContent = item.holiday.name;
const tag = document.createElement('span');
tag.className = 'tag-escopo';
tag.textContent = SCOPE_LABELS[item.holiday.scope];
holidayName.appendChild(tag);
th.appendChild(holidayName);
const td = document.createElement('td');
td.className = 'closed';
td.textContent = 'Fechado';
row.appendChild(th);
row.appendChild(td);
body.appendChild(row);
});
container.hidden = false;
}
function initTimeVerification() {
const statusText = document.getElementById('status-text');
const badgeElement = document.getElementById('js-status-badge');
if (!statusText || !badgeElement) return;
const now = getSaoPauloNow();
const todayHoliday = getHolidayFor(now.year, now.month, now.day);
const closedByHoliday = isClosingHoliday(todayHoliday);
let isShopOpen = false;
let closedMessage = 'Fechado no momento — Faça seu orçamento via WhatsApp';
if (closedByHoliday) {
closedMessage = 'Fechado hoje — Feriado de ' + todayHoliday.name;
} else if (now.weekday >= 1 && now.weekday <= 5) {
const openingTime = 8 * 60;
const closingTime = 18 * 60;
if (now.minutes >= openingTime && now.minutes < closingTime) {
isShopOpen = true;
}
}
if (isShopOpen) {
statusText.textContent = 'Aberto agora — Visite nossa oficina';
badgeElement.classList.remove('active-false');
badgeElement.classList.add('active-true');
} else {
statusText.textContent = closedMessage;
badgeElement.classList.remove('active-true');
badgeElement.classList.add('active-false');
}
renderHolidayAlert(now, todayHoliday);
renderUpcomingHolidays(now);
}
function initMobileMenu() {
const navToggle = document.getElementById('js-nav-toggle');
const navMenu = document.getElementById('nav-menu');
if (!navToggle || !navMenu) return;
navToggle.addEventListener('click', () => {
const isMenuExpanded = navToggle.getAttribute('aria-expanded') === 'true';
navToggle.setAttribute('aria-expanded', String(!isMenuExpanded));
navToggle.setAttribute('aria-label', isMenuExpanded ? 'Abrir menu' : 'Fechar menu');
navToggle.classList.toggle('active');
navMenu.classList.toggle('open');
});
const navigationLinks = navMenu.querySelectorAll('a');
navigationLinks.forEach(link => {
link.addEventListener('click', () => {
navToggle.setAttribute('aria-expanded', 'false');
navToggle.setAttribute('aria-label', 'Abrir menu');
navToggle.classList.remove('active');
navMenu.classList.remove('open');
});
});
}
</script>
</body>
</html>
Deixe um comentário