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
+93
-124
@@ -1,90 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import { motion, type Variants } from "motion/react";
|
||||
import Link from "next/link";
|
||||
import { useReducedMotion } from "@/app/hooks/useReducedMotion";
|
||||
import profilePhoto from "@/public/edev.jpg";
|
||||
import { DrawLine } from "./animations/DrawLine";
|
||||
import { LazyRevealImage } from "./animations/LazyRevealImage";
|
||||
import { textLink } from "./button-styles";
|
||||
import "./conversion.css";
|
||||
import { Reveal } from "./Reveal";
|
||||
import { Section } from "./Section";
|
||||
|
||||
const STORY_DATA = [
|
||||
{
|
||||
label: "Hardware + software",
|
||||
title: "Do sinal físico ao produto digital",
|
||||
label: "Como eu trabalho",
|
||||
title: "Você fala direto com quem desenvolve",
|
||||
content:
|
||||
"Construo a ponte entre dispositivos, protocolos de baixo nível, backend e interface para que o sistema inteiro pareça uma única experiência coerente.",
|
||||
"Você conversa comigo sobre o negócio e acompanha as decisões ao longo da entrega, sem intermediários entre o seu pedido e o sistema.",
|
||||
},
|
||||
{
|
||||
label: "Decisões técnicas",
|
||||
title: "Entrega clara mesmo sob restrição",
|
||||
label: "Sem começar do zero",
|
||||
title: "Aproveito o que você já tem",
|
||||
content:
|
||||
"Avalio o que já existe, identifico dependências e combino prioridades antes de alterar sistemas em uso. Nem todo problema exige começar novamente.",
|
||||
"Antes de mexer em um sistema que já está em uso, vejo o que existe e combino com você o que vem primeiro. Nem todo problema exige começar de novo.",
|
||||
},
|
||||
{
|
||||
label: "Operação",
|
||||
label: "Depois da entrega",
|
||||
title: "Do código ao sistema no ar",
|
||||
content:
|
||||
"Publicação, diagnóstico de falhas, documentação e manutenção entram no planejamento, junto com as funcionalidades.",
|
||||
"Colocar no ar, corrigir falhas, documentar e manter o sistema entram no planejamento desde o começo, junto com as funcionalidades.",
|
||||
},
|
||||
];
|
||||
|
||||
const PROFILE_POINTS = [
|
||||
{
|
||||
title: "Arquitetura pragmática",
|
||||
title: "Solução do tamanho do seu problema",
|
||||
description:
|
||||
"Escolhas guiadas por contexto, operabilidade e impacto real no produto.",
|
||||
"Escolho o que resolve o seu caso, sem complicar além do necessário.",
|
||||
},
|
||||
{
|
||||
title: "Integração profunda",
|
||||
title: "Tudo funcionando junto",
|
||||
description:
|
||||
"Capacidade de atravessar camada física, serviços e interface sem perder consistência.",
|
||||
"A tela, os dados e os equipamentos são ligados para trabalhar como uma coisa só.",
|
||||
},
|
||||
{
|
||||
title: "Responsabilidade técnica",
|
||||
title: "Quem responde pelo projeto",
|
||||
description:
|
||||
"Contato direto com quem define a arquitetura e desenvolve o sistema.",
|
||||
"Você tem contato direto com quem decide a estrutura e desenvolve o sistema.",
|
||||
},
|
||||
];
|
||||
|
||||
/** Atraso (s) de cada cartão: entram em escada, como na vitrine de serviços. */
|
||||
const cardDelay = (index: number) => 0.08 * (index + 1);
|
||||
|
||||
export default function About() {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
|
||||
const staggerContainer: Variants = {
|
||||
hidden: {},
|
||||
visible: {
|
||||
transition: {
|
||||
delayChildren: 0.08,
|
||||
staggerChildren: 0.08,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const cardVariants: Variants = {
|
||||
hidden: shouldReduceMotion
|
||||
? { opacity: 0 }
|
||||
: { opacity: 0, y: 20, clipPath: "inset(100% 0 0 0)" },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
clipPath: "inset(0% 0 0 0)",
|
||||
transition: shouldReduceMotion
|
||||
? { duration: 0.25 }
|
||||
: {
|
||||
duration: 0.8,
|
||||
ease: [0.16, 1, 0.3, 1],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const cardHover = shouldReduceMotion
|
||||
? undefined
|
||||
: {
|
||||
y: -4,
|
||||
boxShadow: "0 18px 40px rgba(10,10,10,0.16)",
|
||||
};
|
||||
|
||||
return (
|
||||
<Section
|
||||
id="about"
|
||||
@@ -93,85 +58,89 @@ export default function About() {
|
||||
description="Sou engenheiro da computação e desenvolvedor de software. Você conversa comigo sobre o negócio e acompanha as decisões técnicas ao longo da entrega."
|
||||
disableChildrenAnimation
|
||||
aside={
|
||||
<div className="mt-sp-4 ds-metric" data-reel="left">
|
||||
<span className="inline-block h-1.5 w-1.5 rounded-full bg-slash" />
|
||||
Base em Garuva, SC | Atendimento remoto
|
||||
<div className="mt-sp-4 ds-metric whitespace-nowrap" data-reel="left">
|
||||
<span className="inline-block h-1.5 w-1.5 shrink-0 rounded-full bg-slash" />
|
||||
Garuva, SC · Atendimento remoto
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<motion.div
|
||||
className="ds-grid-2 items-start"
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, amount: 0.2 }}
|
||||
variants={staggerContainer}
|
||||
>
|
||||
<motion.div
|
||||
className="flex flex-col gap-sp-6"
|
||||
variants={staggerContainer}
|
||||
>
|
||||
{STORY_DATA.map((step) => (
|
||||
<motion.article
|
||||
<div className="ds-grid-2 items-stretch">
|
||||
<div className="flex flex-col gap-sp-6">
|
||||
{STORY_DATA.map((step, index) => (
|
||||
<Reveal
|
||||
key={step.title}
|
||||
className="ds-card"
|
||||
variants={cardVariants}
|
||||
whileHover={cardHover}
|
||||
whileTap={shouldReduceMotion ? undefined : { scale: 0.99 }}
|
||||
transition={{ type: "spring", stiffness: 180, damping: 18 }}
|
||||
y={20}
|
||||
duration={0.8}
|
||||
delay={cardDelay(index)}
|
||||
className="flex flex-1 flex-col"
|
||||
>
|
||||
<div className="ds-kicker">{step.label}</div>
|
||||
<DrawLine delay={0.03} />
|
||||
<h3 className="ds-card-title">{step.title}</h3>
|
||||
<p className="ds-copy" data-reel="right">
|
||||
{step.content}
|
||||
</p>
|
||||
</motion.article>
|
||||
<article className="ds-card cv-press cv-lift flex-1">
|
||||
<div className="ds-kicker">{step.label}</div>
|
||||
<DrawLine delay={0.03} />
|
||||
<h3 className="ds-card-title">{step.title}</h3>
|
||||
<p className="ds-copy" data-reel="right">
|
||||
{step.content}
|
||||
</p>
|
||||
</article>
|
||||
</Reveal>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
<motion.article
|
||||
className="ds-card h-full"
|
||||
variants={cardVariants}
|
||||
whileHover={cardHover}
|
||||
whileTap={shouldReduceMotion ? undefined : { scale: 0.99 }}
|
||||
transition={{ type: "spring", stiffness: 180, damping: 18 }}
|
||||
<Reveal
|
||||
y={20}
|
||||
duration={0.8}
|
||||
delay={cardDelay(STORY_DATA.length)}
|
||||
className="h-full"
|
||||
>
|
||||
<LazyRevealImage
|
||||
src={profilePhoto}
|
||||
alt="Evandro Fonseca Junior, engenheiro da computação e desenvolvedor de software em Garuva, SC"
|
||||
className="mb-sp-6 aspect-square w-full overflow-hidden rounded-[6px] border border-[var(--border)]"
|
||||
imageClassName="object-contain"
|
||||
/>
|
||||
<div className="ds-kicker">Da arquitetura à implementação</div>
|
||||
<DrawLine delay={0.05} />
|
||||
<h3 className="ds-card-title">Uma visão do sistema inteiro</h3>
|
||||
<p className="ds-copy" data-reel="top">
|
||||
Meu trabalho conecta interface, serviços, dados e, quando
|
||||
necessário, equipamentos. Entender essas partes em conjunto ajuda a
|
||||
definir o que construir, o que integrar e o que pode ser
|
||||
aproveitado.
|
||||
</p>
|
||||
<div className="mt-sp-6 space-y-sp-4" data-reel-stagger="bottom">
|
||||
{PROFILE_POINTS.map((point) => (
|
||||
<div
|
||||
key={point.title}
|
||||
className="border-t border-[var(--border)] pt-sp-4"
|
||||
>
|
||||
<div className="text-[12px] font-medium tracking-[0.02em]">
|
||||
{point.title}
|
||||
</div>
|
||||
<p className="ds-copy !mt-sp-2">{point.description}</p>
|
||||
<article className="ds-card cv-press cv-lift h-full">
|
||||
<div className="flex items-center gap-sp-5">
|
||||
<LazyRevealImage
|
||||
src={profilePhoto}
|
||||
alt="Evandro Fonseca Junior, engenheiro da computação e desenvolvedor de software em Garuva, SC"
|
||||
className="aspect-square w-28 shrink-0 overflow-hidden rounded-[6px] border border-[var(--border)] sm:w-32"
|
||||
imageClassName="object-cover"
|
||||
sizes="128px"
|
||||
/>
|
||||
<div className="min-w-0">
|
||||
<div className="ds-kicker">Da ideia ao sistema no ar</div>
|
||||
<h3 className="ds-card-title !mt-sp-2">
|
||||
Uma pessoa cuida do sistema inteiro
|
||||
</h3>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Link
|
||||
href="/curriculo"
|
||||
className={`${textLink} mt-sp-4 text-[var(--ink-80)]`}
|
||||
>
|
||||
Ver trajetória completa
|
||||
</Link>
|
||||
</motion.article>
|
||||
</motion.div>
|
||||
</div>
|
||||
<DrawLine delay={0.05} />
|
||||
<p className="ds-copy" data-reel="top">
|
||||
Cuido da tela que sua equipe usa, dos dados por trás dela e,
|
||||
quando o negócio tem máquinas ou sensores, da ligação deles com o
|
||||
sistema. Ver tudo junto ajuda a decidir o que construir, o que
|
||||
conectar e o que dá para aproveitar.
|
||||
</p>
|
||||
<p className="ds-copy">
|
||||
Desde 2022 desenvolvo sistemas internos, aplicativos e integrações
|
||||
IoT na Apolo Energia.
|
||||
</p>
|
||||
<div className="mt-sp-6 space-y-sp-4" data-reel-stagger="bottom">
|
||||
{PROFILE_POINTS.map((point) => (
|
||||
<div
|
||||
key={point.title}
|
||||
className="border-t border-[var(--border)] pt-sp-4"
|
||||
>
|
||||
<div className="text-[15px] font-medium tracking-[0.02em]">
|
||||
{point.title}
|
||||
</div>
|
||||
<p className="ds-copy !mt-sp-2">{point.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Link
|
||||
href="/curriculo"
|
||||
className={`${textLink} mt-sp-4 text-[var(--ink-80)]`}
|
||||
>
|
||||
Ver trajetória completa
|
||||
</Link>
|
||||
</article>
|
||||
</Reveal>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user