feat(home): ofertas que vendem o título, WhatsApp no hero e menu do celular acessível

Três ofertas (site que traz pedidos pelo WhatsApp, sistema para tirar a operação da planilha, revisão de sistema existente) com miniatura e formulário com o tipo escolhido; botão principal do hero abre o WhatsApp; moldura da SEV no hero do celular; menu fecha ao navegar, Esc, foco preso incluindo a barra de cookies e espaço para ela; CinematicHome como componente de servidor com ilha cliente; /ia com H1 de oferta e cartão do que você recebe; botão flutuante em aside com transform; AVIF antes de WebP; copy sem repetir contato direto.
This commit is contained in:
Evandro Fonseca Junior committed 2026-10-14 17:01:36 -03:00
1 parent de6af74a0c
commit f8545cd442
44 files changed
+2286 -571

No files matched your search

+8 -17
View File
@@ -11,14 +11,14 @@ import {
} from "@/lib/site-content";
import type { WhatsAppContexts } from "@/lib/whatsapp";
import CinematicOverlays from "./components/cinematic/CinematicOverlays";
import { FRAGMENT_NAV_BOOT_SCRIPT } from "./components/cinematic/fragment-nav";
import FloatingWhatsApp from "./components/FloatingWhatsApp";
import Footer from "./components/Footer";
import GoogleAnalytics from "./components/GoogleAnalytics";
import { Header } from "./components/Header";
import "./globals.css";
// O CSS da vitrine (molduras de navegador e de celular, vitrine animada) vem uma vez só, aqui, depois do global.
// Importado por cada componente que o usa, ele era pré-carregado pelos links do menu em páginas que não o usam
// (aviso de CSS pré-carregado e não usado).
// As molduras de navegador e de celular (o hero e os cases também as usam) vêm uma vez só, aqui, depois do global.
// O CSS só da vitrine e da janela ampliada (reel-list, pinned-reel e lightbox) viaja com os componentes deles.
import "./components/showcase/showcase.css";
const titleSuffix = " | Evandro.dev.br";
@@ -48,6 +48,8 @@ const geistMono = Geist_Mono({
subsets: ["latin"],
weight: ["400", "500", "600"],
display: "swap",
// só rótulos pequenos e kickers: não disputa a rede com a fonte do título, o arquivo é baixado quando o texto usa
preload: false,
variable: "--font-geist-mono",
});
@@ -143,18 +145,7 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
const sheet = document.getElementById("arrival-scroll-policy")?.sheet;
if (sheet) sheet.disabled = true;
}, { once: true });
if (location.pathname === "/") {
const navigation = performance.getEntriesByType("navigation")[0];
if (navigation?.type !== "back_forward") {
history.scrollRestoration = "manual";
if (navigation?.type === "reload" && location.hash) {
history.replaceState(history.state, "", location.pathname + location.search);
}
addEventListener("pagehide", () => {
history.scrollRestoration = "auto";
}, { once: true });
}
}
${FRAGMENT_NAV_BOOT_SCRIPT}
`}</script>
</head>
<body>
@@ -169,8 +160,8 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
<div id="main-content" tabIndex={-1}>
{children}
</div>
{/* Rodapé de todas as páginas; z-10 o mantém acima das cenas da home (relative z-0). */}
<div className="relative z-10">
{/* Rodapé de todas as páginas; z-10 o mantém acima das cenas da home (relative z-0). O id deixa o menu do celular torná-lo inerte. */}
<div id="site-footer" className="relative z-10">
<Footer serviceLinks={serviceHubLinks} />
</div>
<FloatingWhatsApp contexts={whatsAppContexts} />