- titulo fluido (clamp ate 88px) com destaque em 'sob medida', eyebrow mono, seta no CTA e brilho de fundo - numeros reais na hero (anos de experiencia, projetos publicados, demos online) calculados em app/page.tsx a partir dos dados do portfolio - remove o opacity:0 inicial do motion: o texto nasce visivel; a entrada anima so a posicao (CSS) - HeroSystem monta a cena Three.js via requestIdleCallback (timeout 2,5s), depois de pintar e hidratar o essencial - capas decorativas (sem captura) escondidas no celular Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
139 lines
6.0 KiB
TypeScript
139 lines
6.0 KiB
TypeScript
import Link from "next/link";
|
|
import HeroSystem from "./cinematic/HeroSystem";
|
|
|
|
const SOCIAL_LINKS = [
|
|
{
|
|
href: "https://github.com/evandrodevbr",
|
|
label: "GitHub",
|
|
},
|
|
{
|
|
href: "https://www.linkedin.com/in/evandro-fonseca-junior-0969aa1b0/",
|
|
label: "LinkedIn",
|
|
},
|
|
{
|
|
href: "mailto:[email protected]",
|
|
label: "Email",
|
|
},
|
|
];
|
|
|
|
/** Números reais, calculados em app/page.tsx a partir de public/portfolio-data.json (nada digitado à mão). */
|
|
export type HeroStats = {
|
|
years?: number;
|
|
projects?: number;
|
|
demos?: number;
|
|
};
|
|
|
|
function statItems(stats?: HeroStats) {
|
|
if (!stats) return [];
|
|
return [
|
|
stats.years ? [String(stats.years), "anos de experiência"] : null,
|
|
stats.projects ? [String(stats.projects), "projetos publicados"] : null,
|
|
stats.demos ? [String(stats.demos), "com demonstração online"] : null,
|
|
].filter((item): item is [string, string] => item !== null);
|
|
}
|
|
|
|
export default function Hero({ stats }: { stats?: HeroStats }) {
|
|
const items = statItems(stats);
|
|
|
|
return (
|
|
<section
|
|
id="home"
|
|
className="relative w-full overflow-hidden bg-[var(--ink)] font-display text-[#f4f2ed]"
|
|
>
|
|
<div className="hero-glow" aria-hidden="true" />
|
|
{/* Sem opacity:0 inicial: o título já vem visível no HTML (LCP). A entrada anima só a posição, em CSS. */}
|
|
<div className="hero-rise relative mx-auto grid w-full max-w-[max(1400px,var(--shell))] grid-cols-1 items-center gap-sp-8 px-sp-6 pt-[calc(var(--site-header-height)+32px)] pb-sp-10 lg:grid-cols-[minmax(0,53fr)_minmax(0,47fr)] lg:gap-sp-8 lg:px-sp-12 lg:pb-sp-16">
|
|
<div className="min-w-0">
|
|
<p className="mb-sp-5 flex items-center gap-sp-3 font-mono text-[11px] uppercase leading-[1.5] tracking-[0.14em] text-[rgba(244,242,237,.72)] sm:text-[12px]">
|
|
<span aria-hidden="true" className="h-2 w-2 bg-[var(--slash)]" />
|
|
Evandro Fonseca Junior · Engenharia de software
|
|
</p>
|
|
<h1 className="max-w-[12.5em] text-balance text-[clamp(34px,1.6rem+2.4vw,88px)] font-semibold leading-[1.04] tracking-[-0.045em]">
|
|
Sistemas <span className="text-[var(--slash)]">sob medida</span> para
|
|
operações que não cabem em soluções prontas.
|
|
</h1>
|
|
<p className="mt-sp-5 max-w-[34em] text-[clamp(16px,0.95rem+0.4vw,22px)] leading-[1.55] text-[rgba(244,242,237,.8)]">
|
|
Projeto e desenvolvo sistemas web, aplicativos e integrações, do
|
|
entendimento do negócio à arquitetura e à entrega em produção.
|
|
</p>
|
|
|
|
<div className="mt-sp-6 flex flex-col gap-sp-3 sm:flex-row sm:flex-wrap sm:items-center">
|
|
<Link
|
|
href="/#contact"
|
|
className="group inline-flex min-h-12 items-center justify-center gap-sp-3 bg-[var(--slash)] px-sp-4 py-sp-3 text-center text-[15px] font-semibold leading-6 text-[var(--ink)] no-underline transition-colors hover:bg-[#d9ff40] motion-reduce:transition-none sm:px-sp-6 sm:text-[16px]"
|
|
>
|
|
Conversar sobre meu projeto
|
|
<svg
|
|
aria-hidden="true"
|
|
viewBox="0 0 16 16"
|
|
className="h-4 w-4 transition-transform group-hover:translate-x-1 motion-reduce:transition-none"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
>
|
|
<path d="M2 8h11M9 3.5 13.5 8 9 12.5" />
|
|
</svg>
|
|
</Link>
|
|
<Link
|
|
href="/cases"
|
|
className="inline-flex min-h-12 items-center justify-center border border-white/12 px-sp-5 py-sp-3 text-center text-[15px] font-medium leading-6 text-[#f4f2ed] no-underline transition-colors hover:border-white/40 motion-reduce:transition-none sm:text-[16px]"
|
|
>
|
|
Ver projetos entregues
|
|
</Link>
|
|
</div>
|
|
<p className="mt-sp-3 text-[13px] leading-[1.5] text-[rgba(244,242,237,.64)]">
|
|
Santa Catarina · Atendimento remoto
|
|
</p>
|
|
</div>
|
|
<div className="min-w-0 lg:col-start-2 lg:row-start-1 lg:row-span-2">
|
|
<HeroSystem />
|
|
</div>
|
|
<div className="min-w-0 lg:col-start-1 lg:row-start-2">
|
|
{items.length > 0 && (
|
|
<dl className="mb-sp-6 flex flex-wrap gap-x-sp-8 gap-y-sp-4 border-t border-white/10 pt-sp-5">
|
|
{items.map(([value, label]) => (
|
|
<div key={label} className="flex flex-col-reverse">
|
|
<dt className="text-[13px] leading-[1.4] text-[rgba(244,242,237,.64)]">
|
|
{label}
|
|
</dt>
|
|
<dd className="font-mono text-[clamp(26px,1.2rem+0.9vw,40px)] font-semibold leading-none tracking-[-0.03em] text-[var(--slash)]">
|
|
{value}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
)}
|
|
<ul className="flex flex-wrap gap-x-sp-5 gap-y-sp-2 text-[14px] leading-[1.5] text-[rgba(244,242,237,.8)]">
|
|
{["Sistemas web", "Aplicativos", "Integrações"].map((service) => (
|
|
<li key={service} className="flex items-center gap-sp-2">
|
|
<span
|
|
aria-hidden="true"
|
|
className="h-1 w-1 bg-[var(--slash)]"
|
|
/>
|
|
{service}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<div className="mt-sp-2 flex flex-wrap gap-x-sp-5">
|
|
{SOCIAL_LINKS.map((link) => (
|
|
<a
|
|
key={link.label}
|
|
href={link.href}
|
|
target={link.href.startsWith("http") ? "_blank" : undefined}
|
|
rel={
|
|
link.href.startsWith("http")
|
|
? "noopener noreferrer"
|
|
: undefined
|
|
}
|
|
className="inline-flex min-h-11 items-center text-[13px] text-[rgba(244,242,237,.64)] no-underline underline-offset-4 hover:text-[#f4f2ed] hover:underline"
|
|
>
|
|
{link.label}
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|