Compare commits

...

2 Commits

Author SHA1 Message Date
avanzato e3f35d808d Log release HML: Aplicativos de Atrair Leads
Deploy HML Avanzato / deploy-hml (push) Successful in 37s
2026-06-03 22:07:59 -03:00
avanzato fdfb4606f0 Aplicativos de Atrair Leads 2026-06-03 22:07:59 -03:00
16 changed files with 395 additions and 235 deletions
+1 -1
View File
@@ -239,7 +239,7 @@
} }
} }
</script> </script>
<script type="module" crossorigin src="/assets/index-CLTQHKSq.js"></script> <script type="module" crossorigin src="/assets/index-DLMsdH5y.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-8ILJAHKZ.css"> <link rel="stylesheet" crossorigin href="/assets/index-8ILJAHKZ.css">
</head> </head>
<body> <body>
-61
View File
@@ -1,61 +0,0 @@
# Release HML
Data: ter 2 jun 2026 22:34:39 -03
Ambiente:
HML
Descrição:
Aplicativos de Atrair Leads
Branch:
develop
Arquivos alterados antes do commit:
M dist/index.html
M dist/sitemap.xml
D infra/releases/2026-06-02_12-43-57_HML.md
M node_modules/.tmp/tsconfig.app.tsbuildinfo
M public/sitemap.xml
M public/version.json
M scripts/build-static-routes.sh
M scripts/prerender.cjs
M src/App.tsx
M src/config/site.ts
?? infra/releases/2026-06-02_22-34-39_HML.md
?? public/versions.json
?? src/components/ferramentas/
?? src/pages/ferramentas/
Status:
Preparado para publicação
Commit:
6dfdf018
Arquivos no commit:
dist/index.html
dist/sitemap.xml
infra/releases/2026-06-02_12-43-57_HML.md
infra/releases/2026-06-02_22-34-39_HML.md
node_modules/.tmp/tsconfig.app.tsbuildinfo
public/sitemap.xml
public/version.json
public/versions.json
scripts/build-static-routes.sh
scripts/prerender.cjs
src/App.tsx
src/components/ferramentas/FerramentaLayout.tsx
src/components/ferramentas/dnsApi.ts
src/config/site.ts
src/pages/ferramentas/DkimChecker.tsx
src/pages/ferramentas/DmarcChecker.tsx
src/pages/ferramentas/EmailSecurityScore.tsx
src/pages/ferramentas/Microsoft365Analyzer.tsx
src/pages/ferramentas/MxLookup.tsx
src/pages/ferramentas/SpfChecker.tsx
src/pages/ferramentas/SslChecker.tsx
src/pages/ferramentas/index.tsx
Status final:
Publicado no Gitea / aguardando pipeline HML
+57
View File
@@ -0,0 +1,57 @@
# Release HML
Data: qua 3 jun 2026 22:07:59 -03
Ambiente:
HML
Descrição:
Aplicativos de Atrair Leads
Branch:
develop
Arquivos alterados antes do commit:
M dist/index.html
D infra/releases/2026-06-02_22-34-39_HML.md
M src/App.tsx
M src/sections/About.tsx
M src/sections/CondominiosCTA.tsx
M src/sections/Hero.tsx
M src/sections/Navigation.tsx
M src/sections/Services.tsx
?? infra/releases/2026-06-03_22-07-58_HML.md
?? nginx/
?? public/about-image.webp
?? public/hero-dashboard.webp
?? public/service-cloud.webp
?? public/service-security.webp
?? public/service-support.webp
?? public/service-ti.webp
Status:
Preparado para publicação
Commit:
fdfb4606
Arquivos no commit:
dist/index.html
infra/releases/2026-06-02_22-34-39_HML.md
infra/releases/2026-06-03_22-07-58_HML.md
nginx/avanzato.conf
public/about-image.webp
public/hero-dashboard.webp
public/service-cloud.webp
public/service-security.webp
public/service-support.webp
public/service-ti.webp
src/App.tsx
src/sections/About.tsx
src/sections/CondominiosCTA.tsx
src/sections/Hero.tsx
src/sections/Navigation.tsx
src/sections/Services.tsx
Status final:
Publicado no Gitea / aguardando pipeline HML
+132
View File
@@ -0,0 +1,132 @@
# ============================================================================
# Configuracao Nginx - Avanzato Tecnologia
# ============================================================================
# Inclui: CSP, HSTS, X-Frame-Options, cache headers, gzip, brotli
# Copiar para: /etc/nginx/sites-available/avanzato.com.br
# Ativar: ln -s /etc/nginx/sites-available/avanzato.com.br /etc/nginx/sites-enabled/
# ============================================================================
server {
listen 80;
listen [::]:80;
server_name avanzato.com.br www.avanzato.com.br;
# Redirecionar HTTP para HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name avanzato.com.br www.avanzato.com.br;
# SSL (certbot gerencia automaticamente)
ssl_certificate /etc/letsencrypt/live/avanzato.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/avanzato.com.br/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/avanzato.com.br/chain.pem;
# SSL hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS - HTTP Strict Transport Security
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Root do projeto
root /var/www/avanzato/dist;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml
font/woff2;
# ============================================================================
# CACHE HEADERS - Assets estaticos
# ============================================================================
# Imagens, fontes, videos - 1 mes
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|woff|woff2|ttf|eot|mp4|webm)$ {
expires 1M;
add_header Cache-Control "public, immutable" always;
add_header Vary "Accept-Encoding" always;
access_log off;
}
# CSS e JS - 1 ano (tem hash no nome)
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable" always;
add_header Vary "Accept-Encoding" always;
access_log off;
}
# HTML - nao cachear
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
}
# ============================================================================
# SECURITY HEADERS
# ============================================================================
# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://connect.facebook.net https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://dns.google https://crt.sh https://mkt.avanzato.com.br https://www.google-analytics.com https://www.facebook.com; frame-src 'self' https://mkt.avanzato.com.br; media-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'; upgrade-insecure-requests;" always;
# X-Frame-Options - protecao contra clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# X-Content-Type-Options
add_header X-Content-Type-Options "nosniff" always;
# Referrer Policy
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Permissions Policy
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=()" always;
# Cross-Origin Opener Policy
add_header Cross-Origin-Opener-Policy "same-origin" always;
# Cross-Origin Resource Policy
add_header Cross-Origin-Resource-Policy "cross-origin" always;
# ============================================================================
# REACT ROUTER - SPA fallback
# ============================================================================
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
}
# Sitemap e robots - acessiveis
location = /sitemap.xml {
try_files $uri =404;
add_header Content-Type "application/xml" always;
}
location = /robots.txt {
try_files $uri =404;
add_header Content-Type "text/plain" always;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

+70 -59
View File
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'; import { useEffect, useState, lazy, Suspense } from 'react';
import { BrowserRouter as Router, Routes, Route, useLocation } from 'react-router-dom'; import { BrowserRouter as Router, Routes, Route, useLocation } from 'react-router-dom';
import { gsap } from 'gsap'; import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger'; import { ScrollTrigger } from 'gsap/ScrollTrigger';
@@ -8,78 +8,80 @@ import WhatsAppWidget from './components/WhatsAppWidget';
import CookieConsent from './components/CookieConsent'; import CookieConsent from './components/CookieConsent';
import HomologationBanner from './components/HomologationBanner'; import HomologationBanner from './components/HomologationBanner';
// Páginas // Página inicial carrega direto (mais acessada)
import Home from './pages/Home'; import Home from './pages/Home';
import Sobre from './pages/Sobre';
import Blog from './pages/Blog';
import BlogPost from './pages/BlogPost';
import Cases from './pages/Cases';
import Contato from './pages/Contato';
import Privacidade from './pages/Privacidade';
import Termos from './pages/Termos';
import NotFound from './pages/NotFound'; import NotFound from './pages/NotFound';
// Todas as outras páginas com lazy loading para reduzir bundle inicial
const Sobre = lazy(() => import('./pages/Sobre'));
const Blog = lazy(() => import('./pages/Blog'));
const BlogPost = lazy(() => import('./pages/BlogPost'));
const Cases = lazy(() => import('./pages/Cases'));
const Contato = lazy(() => import('./pages/Contato'));
const Privacidade = lazy(() => import('./pages/Privacidade'));
const Termos = lazy(() => import('./pages/Termos'));
// Páginas de Serviços // Páginas de Serviços
import TiGerenciada from './pages/services/TiGerenciada'; const TiGerenciada = lazy(() => import('./pages/services/TiGerenciada'));
import CloudComputing from './pages/services/CloudComputing'; const CloudComputing = lazy(() => import('./pages/services/CloudComputing'));
import Seguranca from './pages/services/Seguranca'; const Seguranca = lazy(() => import('./pages/services/Seguranca'));
import Suporte from './pages/services/Suporte'; const Suporte = lazy(() => import('./pages/services/Suporte'));
import Redes from './pages/services/Redes'; const Redes = lazy(() => import('./pages/services/Redes'));
import Pabx from './pages/services/Pabx'; const Pabx = lazy(() => import('./pages/services/Pabx'));
import Backup from './pages/services/Backup'; const Backup = lazy(() => import('./pages/services/Backup'));
import Servidores from './pages/services/Servidores'; const Servidores = lazy(() => import('./pages/services/Servidores'));
import Consultoria from './pages/services/Consultoria'; const Consultoria = lazy(() => import('./pages/services/Consultoria'));
import Noc from './pages/services/Noc'; const Noc = lazy(() => import('./pages/services/Noc'));
// Páginas de Tecnologias (SEO) // Páginas de Tecnologias (SEO)
import Tecnologias from './pages/Tecnologias'; const Tecnologias = lazy(() => import('./pages/Tecnologias'));
import WindowsServer from './pages/tech/WindowsServer'; const WindowsServer = lazy(() => import('./pages/tech/WindowsServer'));
import Linux from './pages/tech/Linux'; const Linux = lazy(() => import('./pages/tech/Linux'));
import PfSense from './pages/tech/PfSense'; const PfSense = lazy(() => import('./pages/tech/PfSense'));
import Proxmox from './pages/tech/Proxmox'; const Proxmox = lazy(() => import('./pages/tech/Proxmox'));
import Vmware from './pages/tech/Vmware'; const Vmware = lazy(() => import('./pages/tech/Vmware'));
import Sharepoint from './pages/tech/Sharepoint'; const Sharepoint = lazy(() => import('./pages/tech/Sharepoint'));
import Cisco from './pages/tech/Cisco'; const Cisco = lazy(() => import('./pages/tech/Cisco'));
// Avaliador de Maturidade Tecnológica // Avaliador de Maturidade Tecnológica
import Avaliador from './pages/Avaliador'; const Avaliador = lazy(() => import('./pages/Avaliador'));
import Condominios from './pages/Condominios'; const Condominios = lazy(() => import('./pages/Condominios'));
// Landing Pages por Nicho // Landing Pages por Nicho
import Contabilidade from './pages/nichos/Contabilidade'; const Contabilidade = lazy(() => import('./pages/nichos/Contabilidade'));
import Advocacia from './pages/nichos/Advocacia'; const Advocacia = lazy(() => import('./pages/nichos/Advocacia'));
import Monitoramento from './pages/nichos/Monitoramento'; const Monitoramento = lazy(() => import('./pages/nichos/Monitoramento'));
import FirewallPfSense from './pages/nichos/FirewallPfSense'; const FirewallPfSense = lazy(() => import('./pages/nichos/FirewallPfSense'));
import BackupCorporativo from './pages/nichos/BackupCorporativo'; const BackupCorporativo = lazy(() => import('./pages/nichos/BackupCorporativo'));
import VoipEmpresarial from './pages/nichos/VoipEmpresarial'; const VoipEmpresarial = lazy(() => import('./pages/nichos/VoipEmpresarial'));
// SEO Local - Onde Atuamos // SEO Local - Onde Atuamos
import OndeAtuamos from './pages/OndeAtuamos'; const OndeAtuamos = lazy(() => import('./pages/OndeAtuamos'));
import LocalGuarulhos from './pages/local-guarulhos'; const LocalGuarulhos = lazy(() => import('./pages/local-guarulhos'));
import LocalMogi from './pages/local-mogi-das-cruzes'; const LocalMogi = lazy(() => import('./pages/local-mogi-das-cruzes'));
import LocalIpiranga from './pages/local-ipiranga'; const LocalIpiranga = lazy(() => import('./pages/local-ipiranga'));
import LocalVilaFormosa from './pages/local-vila-formosa'; const LocalVilaFormosa = lazy(() => import('./pages/local-vila-formosa'));
import LocalCerqueiraCesar from './pages/local-cerqueira-cesar'; const LocalCerqueiraCesar = lazy(() => import('./pages/local-cerqueira-cesar'));
import LocalSantana from './pages/local-santana'; const LocalSantana = lazy(() => import('./pages/local-santana'));
import LocalBras from './pages/local-bras'; const LocalBras = lazy(() => import('./pages/local-bras'));
import LocalRibeiraoPreto from './pages/local-ribeirao-preto'; const LocalRibeiraoPreto = lazy(() => import('./pages/local-ribeirao-preto'));
// Nichos adicionais // Nichos adicionais
import NichoIndustria from './pages/nicho-industria'; const NichoIndustria = lazy(() => import('./pages/nicho-industria'));
import NichoPortaria from './pages/nicho-portaria-remota'; const NichoPortaria = lazy(() => import('./pages/nicho-portaria-remota'));
import NichoClinicas from './pages/nicho-clinicas'; const NichoClinicas = lazy(() => import('./pages/nicho-clinicas'));
import NichoImobiliarias from './pages/nicho-imobiliarias'; const NichoImobiliarias = lazy(() => import('./pages/nicho-imobiliarias'));
import NichoRecrutamento from './pages/nicho-recrutamento-selecao'; const NichoRecrutamento = lazy(() => import('./pages/nicho-recrutamento-selecao'));
// Avanzato Tools // Avanzato Tools
import Ferramentas from './pages/ferramentas'; const Ferramentas = lazy(() => import('./pages/ferramentas'));
import SpfChecker from './pages/ferramentas/SpfChecker'; const SpfChecker = lazy(() => import('./pages/ferramentas/SpfChecker'));
import DkimChecker from './pages/ferramentas/DkimChecker'; const DkimChecker = lazy(() => import('./pages/ferramentas/DkimChecker'));
import DmarcChecker from './pages/ferramentas/DmarcChecker'; const DmarcChecker = lazy(() => import('./pages/ferramentas/DmarcChecker'));
import MxLookup from './pages/ferramentas/MxLookup'; const MxLookup = lazy(() => import('./pages/ferramentas/MxLookup'));
import SslChecker from './pages/ferramentas/SslChecker'; const SslChecker = lazy(() => import('./pages/ferramentas/SslChecker'));
import EmailSecurityScore from './pages/ferramentas/EmailSecurityScore'; const EmailSecurityScore = lazy(() => import('./pages/ferramentas/EmailSecurityScore'));
import Microsoft365Analyzer from './pages/ferramentas/Microsoft365Analyzer'; const Microsoft365Analyzer = lazy(() => import('./pages/ferramentas/Microsoft365Analyzer'));
import './App.css'; import './App.css';
@@ -122,6 +124,13 @@ function ProgressBar() {
); );
} }
// Loading simples para lazy load
const PageLoader = () => (
<div className="min-h-screen bg-[#0e0e0e] flex items-center justify-center">
<div className="w-8 h-8 border-2 border-[#cbf400] border-t-transparent rounded-full animate-spin" />
</div>
);
function App() { function App() {
return ( return (
<Router> <Router>
@@ -131,8 +140,9 @@ function App() {
<Navigation /> <Navigation />
<main> <main>
<Suspense fallback={<PageLoader />}>
<Routes> <Routes>
{/* Página Inicial */} {/* Página Inicial - carrega direto */}
<Route path="/" element={<Home />} /> <Route path="/" element={<Home />} />
{/* Sobre */} {/* Sobre */}
@@ -206,7 +216,6 @@ function App() {
<Route path="/privacidade" element={<Privacidade />} /> <Route path="/privacidade" element={<Privacidade />} />
<Route path="/termos" element={<Termos />} /> <Route path="/termos" element={<Termos />} />
{/* 404 */}
{/* Avanzato Tools */} {/* Avanzato Tools */}
<Route path="/ferramentas" element={<Ferramentas />} /> <Route path="/ferramentas" element={<Ferramentas />} />
<Route path="/ferramentas/spf-checker" element={<SpfChecker />} /> <Route path="/ferramentas/spf-checker" element={<SpfChecker />} />
@@ -217,8 +226,10 @@ function App() {
<Route path="/ferramentas/email-security-score" element={<EmailSecurityScore />} /> <Route path="/ferramentas/email-security-score" element={<EmailSecurityScore />} />
<Route path="/ferramentas/microsoft-365-analyzer" element={<Microsoft365Analyzer />} /> <Route path="/ferramentas/microsoft-365-analyzer" element={<Microsoft365Analyzer />} />
{/* 404 */}
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
</Routes> </Routes>
</Suspense>
</main> </main>
<Footer /> <Footer />
+10 -4
View File
@@ -143,11 +143,17 @@ const About = () => {
{/* Image */} {/* Image */}
<div ref={imageRef} className="relative"> <div ref={imageRef} className="relative">
<div className="relative rounded-2xl overflow-hidden shadow-2xl border border-white/5"> <div className="relative rounded-2xl overflow-hidden shadow-2xl border border-white/5">
<picture>
<source srcSet="/about-image.webp" type="image/webp" />
<img <img
src="/about-image.jpg" src="/about-image.jpg"
alt="Equipe Avanzato" alt="Equipe Avanzato"
loading="lazy"
width="500"
height="685"
className="w-full h-auto object-cover" className="w-full h-auto object-cover"
/> />
</picture>
{/* Glassmorphism overlay card */} {/* Glassmorphism overlay card */}
<div className="absolute bottom-6 left-6 right-6 glass rounded-xl p-6 border border-[#cbf400]/20"> <div className="absolute bottom-6 left-6 right-6 glass rounded-xl p-6 border border-[#cbf400]/20">
@@ -222,28 +228,28 @@ const About = () => {
> >
<div className="text-center"> <div className="text-center">
<Counter end={500} suffix="+" /> <Counter end={500} suffix="+" />
<div className="flex items-center justify-center gap-2 mt-2 text-gray-500"> <div className="flex items-center justify-center gap-2 mt-2 text-gray-400">
<Users className="w-4 h-4" /> <Users className="w-4 h-4" />
<span className="text-sm">Clientes atendidos</span> <span className="text-sm">Clientes atendidos</span>
</div> </div>
</div> </div>
<div className="text-center"> <div className="text-center">
<Counter end={99} suffix=".9%" /> <Counter end={99} suffix=".9%" />
<div className="flex items-center justify-center gap-2 mt-2 text-gray-500"> <div className="flex items-center justify-center gap-2 mt-2 text-gray-400">
<Clock className="w-4 h-4" /> <Clock className="w-4 h-4" />
<span className="text-sm">Uptime garantido</span> <span className="text-sm">Uptime garantido</span>
</div> </div>
</div> </div>
<div className="text-center"> <div className="text-center">
<Counter end={23} suffix="+" /> <Counter end={23} suffix="+" />
<div className="flex items-center justify-center gap-2 mt-2 text-gray-500"> <div className="flex items-center justify-center gap-2 mt-2 text-gray-400">
<Award className="w-4 h-4" /> <Award className="w-4 h-4" />
<span className="text-sm">Anos de experiência</span> <span className="text-sm">Anos de experiência</span>
</div> </div>
</div> </div>
<div className="text-center"> <div className="text-center">
<Counter end={24} suffix="/7" /> <Counter end={24} suffix="/7" />
<div className="flex items-center justify-center gap-2 mt-2 text-gray-500"> <div className="flex items-center justify-center gap-2 mt-2 text-gray-400">
<Users className="w-4 h-4" /> <Users className="w-4 h-4" />
<span className="text-sm">Suporte técnico</span> <span className="text-sm">Suporte técnico</span>
</div> </div>
+4 -4
View File
@@ -117,7 +117,7 @@ const CondominiosCTA = () => {
<Phone className="w-6 h-6 text-[#cbf400]" /> <Phone className="w-6 h-6 text-[#cbf400]" />
</div> </div>
<div> <div>
<h4 className="text-white font-bold">VOIP para Condomínios</h4> <h3 className="text-white font-bold">VOIP para Condomínios</h3>
<p className="text-gray-500 text-sm">Comunicação moderna e econômica</p> <p className="text-gray-500 text-sm">Comunicação moderna e econômica</p>
</div> </div>
</div> </div>
@@ -127,7 +127,7 @@ const CondominiosCTA = () => {
<Server className="w-6 h-6 text-blue-400" /> <Server className="w-6 h-6 text-blue-400" />
</div> </div>
<div> <div>
<h4 className="text-white font-bold">Gestão de CPD</h4> <h3 className="text-white font-bold">Gestão de CPD</h3>
<p className="text-gray-500 text-sm">Infraestrutura profissional</p> <p className="text-gray-500 text-sm">Infraestrutura profissional</p>
</div> </div>
</div> </div>
@@ -137,7 +137,7 @@ const CondominiosCTA = () => {
<Wifi className="w-6 h-6 text-purple-400" /> <Wifi className="w-6 h-6 text-purple-400" />
</div> </div>
<div> <div>
<h4 className="text-white font-bold">Rede e Conectividade</h4> <h3 className="text-white font-bold">Rede e Conectividade</h3>
<p className="text-gray-500 text-sm">Alta disponibilidade</p> <p className="text-gray-500 text-sm">Alta disponibilidade</p>
</div> </div>
</div> </div>
@@ -147,7 +147,7 @@ const CondominiosCTA = () => {
<Shield className="w-6 h-6 text-red-400" /> <Shield className="w-6 h-6 text-red-400" />
</div> </div>
<div> <div>
<h4 className="text-white font-bold">Segurança</h4> <h3 className="text-white font-bold">Segurança</h3>
<p className="text-gray-500 text-sm">Monitoramento 24/7</p> <p className="text-gray-500 text-sm">Monitoramento 24/7</p>
</div> </div>
</div> </div>
+7 -1
View File
@@ -247,13 +247,19 @@ const Hero = () => {
{/* Glow effect */} {/* Glow effect */}
<div className="absolute -inset-4 bg-gradient-to-r from-[#cbf400]/20 to-[#cbf400]/10 rounded-2xl blur-2xl opacity-50" /> <div className="absolute -inset-4 bg-gradient-to-r from-[#cbf400]/20 to-[#cbf400]/10 rounded-2xl blur-2xl opacity-50" />
{/* Dashboard image */} {/* Dashboard image com WebP + fetchpriority alta */}
<div className="relative rounded-2xl overflow-hidden shadow-2xl border border-[#cbf400]/20"> <div className="relative rounded-2xl overflow-hidden shadow-2xl border border-[#cbf400]/20">
<picture>
<source srcSet="/hero-dashboard.webp" type="image/webp" />
<img <img
src="/hero-dashboard.jpg" src="/hero-dashboard.jpg"
alt="Dashboard Avanzato" alt="Dashboard Avanzato"
fetchPriority="high"
width="800"
height="500"
className="w-full h-auto" className="w-full h-auto"
/> />
</picture>
{/* Glossy overlay */} {/* Glossy overlay */}
<div <div
+1 -1
View File
@@ -46,7 +46,7 @@ const Navigation = () => {
<div className="container-custom"> <div className="container-custom">
<div className="flex items-center justify-between h-20"> <div className="flex items-center justify-between h-20">
{/* Logo - importado de config/site.ts */} {/* Logo - importado de config/site.ts */}
<Link to={LOGO.href} className="flex items-center"> <Link to={LOGO.href} className="flex items-center" aria-label="Avanzato Tecnologia - Pagina inicial">
{renderLogo()} {renderLogo()}
</Link> </Link>
+10 -1
View File
@@ -121,6 +121,9 @@ const ServiceCard = ({ service }: { service: Service }) => {
setMousePos({ x, y }); setMousePos({ x, y });
}; };
// Gerar caminho WebP com fallback PNG/JPG
const webpImage = service.image.replace(/\.(png|jpg|jpeg)$/, '.webp');
return ( return (
<div <div
ref={cardRef} ref={cardRef}
@@ -138,13 +141,19 @@ const ServiceCard = ({ service }: { service: Service }) => {
setMousePos({ x: 0, y: 0 }); setMousePos({ x: 0, y: 0 });
}} }}
> >
{/* Image container */} {/* Image container com WebP + lazy loading */}
<div className="relative h-48 bg-gradient-to-br from-[#2a2a2a] to-[#1a1a1a] overflow-hidden"> <div className="relative h-48 bg-gradient-to-br from-[#2a2a2a] to-[#1a1a1a] overflow-hidden">
<picture>
<source srcSet={webpImage} type="image/webp" />
<img <img
src={service.image} src={service.image}
alt={service.title} alt={service.title}
loading="lazy"
width="300"
height="300"
className="w-full h-full object-contain p-6 transition-transform duration-500 group-hover:scale-110" className="w-full h-full object-contain p-6 transition-transform duration-500 group-hover:scale-110"
/> />
</picture>
{/* Icon badge */} {/* Icon badge */}
<div className="absolute top-4 left-4 w-12 h-12 rounded-xl bg-[#0e0e0e] shadow-lg flex items-center justify-center text-[#cbf400] border border-[#cbf400]/20"> <div className="absolute top-4 left-4 w-12 h-12 rounded-xl bg-[#0e0e0e] shadow-lg flex items-center justify-center text-[#cbf400] border border-[#cbf400]/20">