feat(home): posicionamento com prova, menu sem recarregar e WhatsApp em todo o site
H1 'Sites e sistemas que trazem pedidos pelo WhatsApp e tiram sua operação da planilha.'; HeroWork maior com a SEV; menu Cases, Serviços, Como trabalho, Sobre e IA com next/link e pré-carregamento no hover; menu do celular em tela cheia; WhatsApp flutuante e no rodapé com a mensagem da rota; rodapé em todas as páginas; FAQ da home; /ia como oferta de revisão de app feito com IA; formulário com noscript, validação do mailto e plano B do pop-up; cartões sem foco indevido; sem a fonte Monument.
This commit is contained in:
1 parent
e80f73d075
commit
10f170abf4
56 files changed
+3099
-906
No files matched your search
+38
-30
@@ -1,18 +1,41 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Geist_Mono, Space_Grotesk } from "next/font/google";
|
||||
import localFont from "next/font/local";
|
||||
import type { ReactNode } from "react";
|
||||
import { safeJsonLd } from "@/lib/jsonld";
|
||||
import { buildPersonJsonLd, buildWebSiteJsonLd } from "@/lib/seo";
|
||||
import { siteUrl } from "@/lib/site-content";
|
||||
import {
|
||||
caseStudies,
|
||||
serviceHubLinks,
|
||||
servicePages,
|
||||
siteUrl,
|
||||
} from "@/lib/site-content";
|
||||
import type { WhatsAppContexts } from "@/lib/whatsapp";
|
||||
import CinematicOverlays from "./components/cinematic/CinematicOverlays";
|
||||
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).
|
||||
import "./components/showcase/showcase.css";
|
||||
|
||||
const defaultTitle = "Sistemas sob medida para empresas | Evandro.dev.br";
|
||||
const titleSuffix = " | Evandro.dev.br";
|
||||
/** Título da home: o `title.default` não passa pelo template, então leva o sufixo. Com ele, no máximo 60 caracteres. */
|
||||
const defaultTitle = `Sites e sistemas em Joinville e SC${titleSuffix}`;
|
||||
const seoDescription =
|
||||
"Sistemas web, aplicativos e integrações sob medida, do negócio à produção, com Evandro Fonseca Junior. Base em Santa Catarina, atendimento remoto.";
|
||||
"Sites com pedido pelo WhatsApp e sistemas que tiram sua operação da planilha. Base em Garuva, SC; atendimento em Joinville e remoto em todo o Brasil.";
|
||||
|
||||
/** Para o WhatsApp falar do serviço ou do case da página aberta: só nomes, sem o conteúdo pesado das páginas. */
|
||||
const whatsAppContexts: WhatsAppContexts = {
|
||||
services: Object.fromEntries(
|
||||
servicePages.map((service) => [service.slug, service.navLabel]),
|
||||
),
|
||||
cases: Object.fromEntries(
|
||||
caseStudies.map((caseStudy) => [caseStudy.id, caseStudy.title]),
|
||||
),
|
||||
};
|
||||
|
||||
const spaceGrotesk = Space_Grotesk({
|
||||
subsets: ["latin"],
|
||||
@@ -28,27 +51,10 @@ const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
});
|
||||
|
||||
const monumentExtended = localFont({
|
||||
src: [
|
||||
{
|
||||
path: "../public/fonts/MonumentExtended-Regular.otf",
|
||||
weight: "400",
|
||||
style: "normal",
|
||||
},
|
||||
{
|
||||
path: "../public/fonts/MonumentExtended-Ultrabold.otf",
|
||||
weight: "800",
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
display: "swap",
|
||||
variable: "--font-monument-extended",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: defaultTitle,
|
||||
template: "%s | Evandro Fonseca Junior",
|
||||
template: `%s${titleSuffix}`,
|
||||
},
|
||||
description: seoDescription,
|
||||
authors: [{ name: "Evandro Fonseca Junior" }],
|
||||
@@ -57,9 +63,6 @@ export const metadata: Metadata = {
|
||||
applicationName: "Evandro.dev.br",
|
||||
category: "Technology",
|
||||
metadataBase: new URL(siteUrl),
|
||||
alternates: {
|
||||
canonical: "/",
|
||||
},
|
||||
formatDetection: {
|
||||
email: false,
|
||||
address: false,
|
||||
@@ -77,7 +80,7 @@ export const metadata: Metadata = {
|
||||
url: "/opengraph-image",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Evandro.dev.br | Sistemas sob medida para empresas",
|
||||
alt: "Evandro.dev.br | Sites e sistemas para empresas",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -89,7 +92,7 @@ export const metadata: Metadata = {
|
||||
images: [
|
||||
{
|
||||
url: "/opengraph-image",
|
||||
alt: "Evandro.dev.br | Sistemas sob medida para empresas",
|
||||
alt: "Evandro.dev.br | Sites e sistemas para empresas",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -126,14 +129,14 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
return (
|
||||
<html
|
||||
lang="pt-BR"
|
||||
className={`${spaceGrotesk.variable} ${geistMono.variable} ${monumentExtended.variable}`}
|
||||
className={`${spaceGrotesk.variable} ${geistMono.variable}`}
|
||||
>
|
||||
<head>
|
||||
{/* Set arrival policy before native restoration and client-side layout changes. */}
|
||||
<style id="arrival-scroll-policy">{`html { scroll-behavior: auto !important; }`}</style>
|
||||
{/* Sem JavaScript as animações de entrada (opacity:0 inline vindo do servidor e palavras de título em CSS) não rodam: tudo precisa aparecer. */}
|
||||
<noscript>
|
||||
<style>{`[style*="opacity:0"],[style*="clip-path"]{opacity:1!important;transform:none!important;clip-path:none!important}.text-reveal-word{opacity:1!important;transform:none!important}`}</style>
|
||||
<style>{`[style*="opacity:0"],[style*="clip-path"]{opacity:1!important;transform:none!important;clip-path:none!important}.text-reveal-word{opacity:1!important;transform:none!important}.js-only{display:none!important}`}</style>
|
||||
</noscript>
|
||||
<script>{`
|
||||
addEventListener("load", () => {
|
||||
@@ -161,11 +164,16 @@ export default function RootLayout({ children }: Readonly<RootLayoutProps>) {
|
||||
</a>
|
||||
{/* Aviso de cookies logo depois do "pular": fica cedo na ordem do Tab, ainda que fixo no rodapé da tela. */}
|
||||
<GoogleAnalytics />
|
||||
<Header />
|
||||
<Header whatsAppContexts={whatsAppContexts} />
|
||||
<CinematicOverlays />
|
||||
<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">
|
||||
<Footer serviceLinks={serviceHubLinks} />
|
||||
</div>
|
||||
<FloatingWhatsApp contexts={whatsAppContexts} />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user