Cards da tela de Projetos: o card não encolhe

AgentPack · medido em Chromium real (Playwright), 12 projetos com o conteúdo exato do print de 1920×919 · 21/10/2026

Resumo: não são dois bugs — é um. Os filhos do card são flex items sem min-w-0, então em flexbox o min-width default é auto: o item nunca encolhe abaixo do próprio conteúdo. A descrição com URL (string sem espaços) empurra o card 28–82px para fora da sua track, por cima do card vizinho. O 3 pontinhos e o botão “Conectar agente” saem com ele.

Os números antes

Cards estourando a track

10 / 12
no viewport 1920 (o do seu print) — 29 a 83px cada

Px invadindo o vizinho

3 787 px
soma de todos os cards a 1920 · 1 953 px a 1280
ViewportCards que estouramPx de invasãoBotão fora do card
1920 × 919 o do print10 / 12 (29–83px)3 787 px10 / 12
1536 × 9190 / 120 px0 / 12
1366 × 9199 / 12360 px9 / 12
1280 × 91910 / 121 953 px10 / 12

Quem invade quem pixel scan, elementFromPoint

ElementoOndeAté quantos px invadem
BUTTON.ui-btn “Conectar agente”rodapé do card500 px
A.relative.z-10 link de contagem “0 páginas”linha do manifesto139 px
BUTTON.flex.h-7.w-7 3 pontinhoscanto sup. dir.123 px

Por que o 3 pontinhos não abre o mesmo bug

O 3 pontinhos usa opacity-0 group-hover:opacity-100, e o group é o <article>. Como o botão sai do card e cai sobre o card vizinho, o ponteiro que o dono move até os 3 pontinhos está na verdade sobre o card vizinho → o card de origem perde o hover → o botão fica invisível exatamente no instante do clique.

E o clique que sobra vai para o link esticado (::after do <Link>, inset-0, cobre o card inteiro) — que navega para o projeto em vez de abrir o menu.

Medido: com o ponteiro no canto superior direito do card (onde a pessoa espera os 3 pontinhos), o elementFromPoint devolve o <a> do link esticado em 12/12 cards.

// caso patológico, medido SEM o fix
i=10  fora=+33px  topoEhMeuBotao=FALSE  caiuNoCard='Auditoria'   // soterrado pelo vizinho

// MESMO card, COM o fix
i=10  fora=-17px  topoEhMeuBotao=TRUE   caiuNoCard='Nommand — Docs Ecossistema'

A correção 3 palavras

min-w-0 nos três containers flex do ProjectCard — o do topo, o do manifesto e o do rodapé. É literalmente o que o SkillCard (que funciona) já faz e o ProjectCard não faz.
// frontend/src/features/projects/components/ProjectCard.tsx
- <div className="flex items-start gap-2.5">
+ <div className="flex min-w-0 items-start gap-2.5">

- className="flex flex-wrap items-center font-mono ..."
+ className="flex min-w-0 flex-wrap items-center font-mono ..."

- <div className="flex items-center gap-2 border-t ..."
+ <div className="flex min-w-0 items-center gap-2 border-t ..."

Depois medido nos 4 viewports

ViewportCards estourandoPx de invasãoBotão foraMenus que abrem
19200 / 120 px012 / 12
15360 / 120 px012 / 12
13660 / 120 px012 / 12
12800 / 120 px012 / 12

Confirmado em produção

O bundle servido antes da correção (Home-HiFcmfBb.js) tinha 2× flex items-start gap-2.5 sem min-w-0 — o mesmo código. O defeito estava no ar, não era da minha build.

Como medi: Chromium real (Playwright), 12 projetos com o conteúdo exato do seu print. O truque que importa: userEvent.click(element) não reproduz — ele entrega o evento direto ao elemento, sem hit-test, e “abre” mesmo com o botão coberto. Só o hit-test de verdade (document.elementFromPoint) reproduz o que você sente.
Medido por mim (orquestrador) em 21/10/2026 na sandbox agent-package-audit, branch fix/cards-projetos-1021 sobre origin/main = 02967533.
Depois: mergeado na main como 2ac3ae5e, deployado às 21:50 UTC (container 0d4025ac2543). O bundle no ar é Home-luCh0W6u.js.
Relatório do deploy →