Files
portifolio-evandrodevbr/app/components/ClientStrip.tsx
T
Evandro Fonseca Junior 9e2d65a926 fix(home): oferta leva ao formulário, ofertas logo depois da vitrine
O botão das ofertas rola até o contato com o tipo marcado e não quebra mais as âncoras; ofertas com o que você recebe e primeiro passo, logo depois da vitrine; bloco de IA fora da home; cartão largo da SEV no hero do celular; separador da faixa de clientes só entre itens; favicon de 13 para 1,8 KB; pré-carregamento só no hover e nunca de /#... fora da home; X do menu e cabeçalho opaco; WhatsApp com "o case"; /ia com 3 passos e modelo de relatório ilustrativo; Sobre alinhado ao currículo; CSP Report-Only com os domínios do Ads.
2026-10-14 19:14:47 -03:00

84 lines
2.9 KiB
TypeScript

import HoverPrefetchLink from "./HoverPrefetchLink";
export type ClientLink = { id: string; name: string };
/**
* Faixa "Já entregue para" do hero: só projetos de cliente (lib/proof.ts), cada um levando ao próprio case, e na
* mesma linha os anos de experiência (calculados em app/page.tsx). Sem clientes e sem anos, nada é desenhado.
* Os links têm 44 px de altura de toque; a rota só é pré-carregada quando a pessoa chega no link.
*
* O ponto separador vem ANTES de cada item, menos do primeiro, e só aparece ENTRE itens da mesma linha. Cada item
* (menos o primeiro) tem 16 px de margem negativa (`-ml-4`), que cobrem os 16 px de respiro (`pr-4`) do item
* anterior, e é nesses 16 px que o ponto (`w-4`) fica. Quando a lista quebra e um item abre a linha seguinte, o
* ponto dele cai na margem à esquerda da lista e o `overflow-x: clip` o esconde: nenhuma linha termina nem começa
* com "·". O recuo de 4 px da lista (`-ml-1 pl-1`) só dá espaço ao contorno de foco do primeiro link (2 px de
* contorno e 2 px de afastamento); o ponto, centrado na margem, fica 6 px além dele.
*/
export default function ClientStrip({
clients = [],
years,
className = "",
}: {
clients?: ClientLink[];
/** Anos de experiência, na mesma linha dos clientes. */
years?: number;
className?: string;
}) {
if (clients.length === 0 && !years) return null;
const items = [
...clients.map((client) => ({
key: client.id,
node: (
<HoverPrefetchLink
href={`/cases/${client.id}`}
className="inline-flex min-h-11 items-center font-medium text-[#f4f2ed] no-underline underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--slash)]"
>
{client.name}
</HoverPrefetchLink>
),
})),
...(years
? [
{
key: "years",
node: (
<p>
<span className="font-semibold text-[var(--slash)]">
{years}
</span>{" "}
anos de experiência
</p>
),
},
]
: []),
];
return (
<div
className={`flex flex-wrap items-center gap-x-sp-3 gap-y-sp-1 font-display text-[15px] leading-6 text-[rgba(244,242,237,.64)] ${className}`.trim()}
>
{clients.length > 0 && <p>Já entregue para:</p>}
<ul className="-ml-1 flex flex-wrap items-center overflow-x-clip pl-1">
{items.map((item, index) => (
<li
key={item.key}
className={`flex items-center pr-4${index > 0 ? " -ml-4" : ""}`}
>
{index > 0 && (
<span
aria-hidden="true"
className="w-4 shrink-0 text-center text-[rgba(244,242,237,.4)]"
>
·
</span>
)}
{item.node}
</li>
))}
</ul>
</div>
);
}