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:
Evandro Fonseca Junior committed 2026-10-14 14:15:25 -03:00
1 parent e80f73d075
commit 10f170abf4
56 files changed
+3099 -906

No files matched your search

+91
View File
@@ -0,0 +1,91 @@
import Link from "next/link";
import { textLink } from "./button-styles";
export interface FaqItem {
question: string;
/** Resposta vazia = pergunta preparada, que ainda não é exibida. */
answer: string;
link?: { href: string; label: string };
}
/**
* Perguntas da home. As quatro primeiras só dizem o que o site já sustenta (contato, rodapé, /ia).
* As três últimas estão preparadas, sem resposta: o dono as responde depois e elas passam a aparecer.
* Nunca escrever aqui prazo, preço, garantia ou política de pagamento que ele não tenha dito.
*/
export const FAQ_ITEMS: FaqItem[] = [
{
question: "Como começa um projeto?",
answer:
"Com uma conversa para entender o problema, sem precisar chegar com a solução definida. Depois dela, você recebe o escopo e a proposta por escrito.",
},
{
question: "Você atende fora de Santa Catarina?",
answer:
"Sim. Minha base é em Garuva, SC, e o atendimento é remoto, para empresas de todo o Brasil.",
},
{
question:
"Dá para continuar um sistema que já existe ou que foi feito com IA?",
answer:
"Sim. Antes de propor qualquer coisa, avalio o que pode ser aproveitado, quais riscos precisam de correção e o que falta para atender usuários em produção. Nem todo problema exige começar de novo.",
link: { href: "/ia", label: "Ver a revisão de app feito com IA" },
},
{
question: "O que preciso ter para começar?",
answer:
"Basta contar o que você quer resolver e, se houver, o prazo que tem em mente. Se já existe um sistema, uma planilha ou um protótipo, mostrar ajuda, mas não é obrigatório.",
},
{ question: "O código e os acessos ficam comigo?", answer: "" },
{ question: "Em nome de quem ficam domínio e hospedagem?", answer: "" },
{ question: "Como funciona o pagamento?", answer: "" },
];
/** Perguntas frequentes da home, antes do contato. Só aparecem as que têm resposta; sem nenhuma, a seção não existe. */
export default function HomeFaq({ items = FAQ_ITEMS }: { items?: FaqItem[] }) {
const answered = items.filter((item) => item.answer.trim() !== "");
if (answered.length === 0) return null;
return (
<section id="faq" aria-labelledby="faq-title" className="ds-section">
<div className="ds-section-shell">
<p className="ds-eyebrow">Dúvidas comuns</p>
<h2
id="faq-title"
className="ds-section-title max-w-[22ch] text-balance"
>
Perguntas frequentes
</h2>
<div className="mt-sp-8 max-w-[860px]">
{answered.map((item) => (
<details
key={item.question}
className="group border-t border-[var(--border)] last:border-b"
>
<summary className="flex min-h-14 cursor-pointer list-none items-center justify-between gap-sp-4 py-sp-4 font-display text-[17px] font-semibold leading-snug text-[var(--ink)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--ink)] [&::-webkit-details-marker]:hidden">
{item.question}
<span
aria-hidden="true"
className="shrink-0 font-mono text-xl leading-none text-[var(--meta)] transition-transform group-open:rotate-45 motion-reduce:transition-none"
>
+
</span>
</summary>
<div className="pb-sp-5">
<p className="ds-copy max-w-[65ch]">{item.answer}</p>
{item.link ? (
<Link
href={item.link.href}
className={`${textLink} mt-sp-2 text-[var(--ink-80)]`}
>
{item.link.label}
</Link>
) : null}
</div>
</details>
))}
</div>
</div>
</section>
);
}