"use client"; import { motion, type Variants } from "motion/react"; import dynamic from "next/dynamic"; import { useEffect, useState } from "react"; import { shouldLoadHeroScene } from "@/app/lib/should-load-hero-scene"; import { CV_URL } from "@/lib/site-navigation"; import { buildWhatsAppUrl } from "@/lib/whatsapp"; import { ControlRoomGlobe } from "./cinematic/ControlRoomGlobe"; import MagneticButton from "./cinematic/MagneticButton"; import { ParticleBuildText } from "./cinematic/ParticleBuildText"; import { TelemetryStrip } from "./cinematic/TelemetryStrip"; const HeroScene = dynamic(() => import("./cinematic/HeroScene"), { ssr: false, }); type HeroSceneVariant = | "command" | "launch" | "rescue" | "signal" | "diagnostic" | "portrait"; type HeroVariant = { id: string; weight: number; scene: HeroSceneVariant; layout: "default" | "visual-first" | "split" | "report" | "portrait"; status: string; chip: string; eyebrow: string; headline: string; subtitle: string; cta: string; whatsappMessage: string; sideLabel: string; sideTitle: string; sideText: string; points: string[]; proof: Array<{ label: string; value: string }>; }; const SOCIAL_LINKS = [ { href: "https://github.com/evandrodevbr", label: "GitHub", icon: ( ), }, { href: "https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/", label: "LinkedIn", icon: ( ), }, { href: "mailto:evandrofonsecajunior@gmail.com", label: "Email", icon: ( <> ), stroke: true, }, ]; const HERO_VARIANTS: HeroVariant[] = [ { id: "command-center", weight: 22, scene: "command", layout: "default", status: "Disponível para novas oportunidades", chip: "Garuva · Joinville · Curitiba · Remoto", eyebrow: "Evandro Fonseca Junior | Engenheiro da Computação e Desenvolvedor de Software", headline: "Engenharia de software para sistemas que precisam operar de verdade.", subtitle: "Profissional disponível para oportunidades CLT e PJ em Garuva, Joinville, Norte de Santa Catarina e Curitiba; também atuo em consultoria para produtos, integrações e sistemas críticos.", cta: "Conversar sobre uma oportunidade", whatsappMessage: "Olá! Quero conversar sobre uma oportunidade profissional em engenharia de software.", sideLabel: "Contato profissional direto", sideTitle: "Procurando um engenheiro da computação para o seu time?", sideText: "Vamos conversar sobre o contexto técnico, o desafio da vaga e como posso contribuir da arquitetura à entrega.", points: [ "Engenharia full-stack com base em sistemas e integrações.", "Next.js, TypeScript, Rust, IoT e arquitetura de software.", "Disponível para times do Norte de SC, Curitiba e atuação remota.", ], proof: [ { label: "Operação", value: "Fluxo pensado para discovery, build, deploy e sustentação.", }, { label: "Clareza", value: "Menos ruído entre produto, engenharia e decisão técnica.", }, { label: "Resultado", value: "Base pronta para operar, evoluir e receber próximo ciclo.", }, ], }, { id: "launch-sequence", weight: 18, scene: "launch", layout: "visual-first", status: "Launch sequence ready", chip: "Discovery → build → deploy", eyebrow: "MVP, produto e entrega em produção", headline: "Tire seu MVP do plano e coloque em produção com base técnica real.", subtitle: "Transformo escopo solto em sequência de lançamento: o que validar, o que construir primeiro e como publicar sem criar uma dívida técnica logo no início.", cta: "Lançar meu MVP", whatsappMessage: "Olá! Quero lançar um MVP com uma base técnica segura. Podemos conversar?", sideLabel: "Sequência de lançamento", sideTitle: "Do primeiro corte ao deploy.", sideText: "A conversa define prioridade, risco e o menor caminho confiável para colocar a primeira versão no ar.", points: [ "Recorte de MVP sem inflar escopo.", "Entrega incremental com critério de produção.", "Deploy e continuidade pensados desde o início.", ], proof: [ { label: "01", value: "Diagnóstico do objetivo e gargalo principal." }, { label: "02", value: "Plano de construção com risco visível." }, { label: "03", value: "Publicação e próximo ciclo sem perder contexto." }, ], }, { id: "rescue-split", weight: 16, scene: "rescue", layout: "split", status: "Rescue mode available", chip: "Legado, instabilidade e projeto travado", eyebrow: "Rescue técnico para sistemas que precisam voltar a andar", headline: "Código confuso, entrega travada ou sistema instável? Vamos organizar.", subtitle: "Entro no ponto onde o projeto parou: leio o fluxo real, separo sintoma de causa e transformo caos técnico em plano executável.", cta: "Destravar meu projeto", whatsappMessage: "Olá! Tenho um projeto travado ou instável e quero destravar. Podemos conversar?", sideLabel: "Antes / depois técnico", sideTitle: "Do caos operacional para uma rota clara.", sideText: "O primeiro objetivo não é reescrever tudo. É encontrar o menor corte seguro que devolve controle e previsibilidade.", points: [ "Leitura rápida de fluxo, risco e acoplamento.", "Priorização do que destrava sem reescrever tudo.", "Correções com critério para não trocar um bug por outro.", ], proof: [ { label: "Antes", value: "Backlog confuso, bugs recorrentes e pouca previsibilidade.", }, { label: "Intervenção", value: "Mapa de risco, cortes pequenos e decisão técnica clara.", }, { label: "Depois", value: "Entrega volta a andar com menos improviso." }, ], }, { id: "iot-signal-map", weight: 15, scene: "signal", layout: "default", status: "Signal map active", chip: "Hardware + software + operação", eyebrow: "Produtos conectados, telemetria e integrações críticas", headline: "Conecte dispositivo, backend e interface em uma operação confiável.", subtitle: "Atuo na fronteira que costuma quebrar primeiro: sinal físico, API, painel, dados e rotina operacional funcionando como um único produto.", cta: "Conectar meu produto", whatsappMessage: "Olá! Quero conectar hardware, software e operação em um produto confiável. Podemos conversar?", sideLabel: "Mapa de sinais", sideTitle: "Dados, comandos e painel no mesmo fluxo.", sideText: "A conversa identifica fontes de dados, contratos, pontos de falha e o caminho para transformar integração em produto.", points: [ "Contratos claros entre dispositivo, API e interface.", "Telemetria e dashboards com contexto operacional.", "Base pronta para automação, IA ou analytics.", ], proof: [ { label: "Entrada", value: "Sensores, dispositivos, eventos ou sistemas externos.", }, { label: "Meio", value: "APIs, WebSockets, filas, banco e observabilidade.", }, { label: "Saída", value: "Painel, operação, alerta e decisão de produto.", }, ], }, { id: "diagnostic-report", weight: 15, scene: "diagnostic", layout: "report", status: "Diagnostic report open", chip: "Arquitetura antes de mais código", eyebrow: "Diagnóstico técnico para decidir melhor", headline: "Antes de escrever mais código, descubra o próximo passo certo.", subtitle: "Quando a base cresce sem clareza, mais features podem piorar o problema. Eu ajudo a mapear risco, arquitetura e prioridades antes da próxima decisão cara.", cta: "Agendar diagnóstico", whatsappMessage: "Olá! Quero um diagnóstico técnico para decidir o próximo passo do meu sistema. Podemos conversar?", sideLabel: "Relatório técnico", sideTitle: "Risco, arquitetura e rota de ação.", sideText: "Ideal para produto que precisa escalar, migrar, estabilizar ou parar de acumular retrabalho técnico.", points: [ "Mapa claro dos gargalos e dependências.", "Trade-offs traduzidos para decisão de negócio.", "Plano de transição sem promessa mágica.", ], proof: [ { label: "Risco", value: "O que pode quebrar, atrasar ou custar caro." }, { label: "Arquitetura", value: "Onde simplificar, separar ou estabilizar primeiro.", }, { label: "Ação", value: "Próximo corte de implementação com critério." }, ], }, { id: "cinematic-portrait", weight: 14, scene: "portrait", layout: "portrait", status: "Direct technical partner", chip: "Conversa direta com quem implementa", eyebrow: "Engenharia sênior, ownership e execução", headline: "Um parceiro técnico para transformar complexidade em entrega.", subtitle: "Você não precisa apenas de tela bonita ou código isolado. Precisa de alguém que entenda contexto, escolha o corte certo e acompanhe até o sistema operar.", cta: "Falar com Evandro", whatsappMessage: "Olá Evandro! Quero conversar sobre um projeto e entender como podemos colocar esse sistema no ar.", sideLabel: "Founder-led engineering", sideTitle: "Menos repasse, mais ownership.", sideText: "A conversa é comigo: contexto técnico, prioridade, risco e caminho de entrega sem perder informação entre camadas.", points: [ "Atendimento consultivo com leitura técnica real.", "Do produto ao backend sem perder contexto.", "Execução com critério, não só código por demanda.", ], proof: [ { label: "Perfil", value: "Engenharia full-stack com base em sistemas e integrações.", }, { label: "Postura", value: "Clareza, autonomia e decisão técnica pragmática.", }, { label: "Acesso", value: "WhatsApp direto para conversa técnica inicial.", }, ], }, ]; const LAYOUT_CLASSES: Record = { default: "grid grid-cols-[minmax(0,1fr)] items-start gap-sp-8 lg:grid-cols-[minmax(0,1.1fr)_minmax(340px,0.9fr)] lg:gap-sp-10", "visual-first": "grid grid-cols-[minmax(0,1fr)] items-start gap-sp-8 lg:grid-cols-[minmax(340px,0.9fr)_minmax(0,1.1fr)] lg:gap-sp-10", split: "grid grid-cols-[minmax(0,1fr)] items-stretch gap-sp-8 lg:grid-cols-2 lg:gap-sp-10", report: "grid grid-cols-[minmax(0,1fr)] items-start gap-sp-8 lg:grid-cols-[minmax(360px,0.85fr)_minmax(0,1.15fr)] lg:gap-sp-10", portrait: "grid grid-cols-[minmax(0,1fr)] items-center gap-sp-8 lg:grid-cols-[minmax(0,1fr)_minmax(320px,0.72fr)] lg:gap-sp-10", }; function getGreeting(message: string) { const hour = new Date().getHours(); if (hour >= 8 && hour < 12) return `Bom dia! ${message}`; if (hour >= 13 && hour < 18) return `Boa tarde! ${message}`; return message; } function SideVisual({ variant, shouldReduceMotion, }: { variant: HeroVariant; shouldReduceMotion: boolean; }) { if (variant.scene === "command") { return (
{/* Partículas decorativas atrás da cena: o h1 real permanece o conteúdo acessível */} {/* autoRotate off em reduced-motion: globo vira âncora estática */}
); } if (variant.scene === "launch") { return (
{variant.proof.map((item, index) => (
0{index + 1}
{item.label}

{item.value}

))}
); } if (variant.scene === "rescue") { return (
Antes

Bugs recorrentes, escopo nebuloso e medo de mexer.

Depois

Rota clara, cortes menores e entrega voltando a andar.

); } if (variant.scene === "signal") { return (
); } if (variant.scene === "diagnostic") { return (
Risk report Actionable
{variant.proof.map((item) => (
{item.label} mapped
))}
); } if (variant.scene === "portrait") { return (
EFJ
Engenharia com contato direto
); } return (
{["deploy pipeline", "api health", "production ready"].map((item) => (
{item} ok
))}
); } export default function Hero() { const variant = HERO_VARIANTS[0]; const [shouldReduceMotion, setShouldReduceMotion] = useState(false); const [shouldRenderHeroScene, setShouldRenderHeroScene] = useState(false); useEffect(() => { const reducedMotion = window.matchMedia( "(prefers-reduced-motion: reduce)", ).matches; const coarsePointer = window.matchMedia("(pointer: coarse)").matches; setShouldReduceMotion(reducedMotion); if ( !shouldLoadHeroScene({ reducedMotion, coarsePointer, width: window.innerWidth, }) ) { return; } const timer = window.setTimeout(() => setShouldRenderHeroScene(true), 1500); return () => window.clearTimeout(timer); }, []); const handleWhatsAppClick = () => { window.open( buildWhatsAppUrl(getGreeting(variant.whatsappMessage)), "_blank", "noopener,noreferrer", ); }; const heroContainer: Variants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.1, delayChildren: 0.3 }, }, }; const easeOut: [number, number, number, number] = [0.16, 1, 0.3, 1]; const heroItem: Variants = { hidden: shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 40, filter: "blur(10px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)", transition: { duration: 1, ease: easeOut }, }, }; const heroItemSlow: Variants = { hidden: shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 60, filter: "blur(12px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)", transition: { duration: 1.2, ease: easeOut }, }, }; const contentOrder = variant.layout === "visual-first" || variant.layout === "report" ? "lg:order-2" : ""; const panelOrder = variant.layout === "visual-first" || variant.layout === "report" ? "lg:order-1" : ""; return (
{shouldRenderHeroScene && }
{/* pt >= altura do header fixo (52px): conteúdo do hero nunca nasce sob a barra */}
{variant.status}
{variant.chip}
{variant.eyebrow} {variant.headline} {variant.subtitle} {variant.points.map((point, i) => ( {point} ))} {variant.cta} Ver casos selecionados Download CV
Garuva, SC / Brasil
Next.js, Tauri, Rust, Node.js
{SOCIAL_LINKS.map((link) => ( ))}
{variant.sideLabel}

{variant.sideTitle}

{variant.sideText}

{variant.proof.map((item, index) => (
{item.label}

{item.value}

))}
{shouldReduceMotion ? (
); }