Skip to content

fix(docs): stop the vendor-official badge clipping adapter card titles - #893

Closed
aldosch wants to merge 2 commits into
mainfrom
fix-vendor-badge-clipping
Closed

fix(docs): stop the vendor-official badge clipping adapter card titles#893
aldosch wants to merge 2 commits into
mainfrom
fix-vendor-badge-clipping

Conversation

@aldosch

@aldosch aldosch commented Sep 3, 2026

Copy link
Copy Markdown

Summary

On phones the Vendor official badge on the adapters listing sat on top of the card title and cut it off — Liveblocks rendered as Liveblo, Sendblue as Sendb, AgentPhone as AgentP — and the badge itself ran past the card's right edge.

Root cause is a size collision, not a z-index or spacing issue:

  • @vercel/geistdocs' Geist breakpoints put sm at 401px, not 640px, so grid gap-4 sm:grid-cols-2 goes two-up on every modern phone (Pixel 7 = 412px, iPhone 16 Pro Max = 430px). Each card is then ~175px wide, leaving ~125px of content width inside p-6.
  • The Vendor official badge is 115px and, via badgeVariants, whitespace-nowrap shrink-0 — so it claimed almost the entire row.
  • The header row was a non-wrapping justify-between flex row, and the docs CSS applies a global min-width: 0 reset, which defeats flexbox's automatic minimum size. The title's flex item was squeezed to 51px while its text needed 80px, so the name spilled to the right underneath the opaque badge and overflow-hidden on the Card clipped the remainder.

Approach

The header row now switches placement on the breakpoint, not on the title:

  • Below md (601px) the header stacks — title, then badge on its own line, left-aligned — for every card.
  • At md and above every card puts the badge inline to the right, exactly as it does today.

md is the point where the narrowest card can hold the widest badge with room to spare. The two-column band opens at 401px with only ~123px of row width, less than the 115px Vendor official badge plus a gap; by 601px the row is ~228px. Above md a long title wraps within its own flex item rather than pushing the badge out, so the badge keeps its position.

Supporting changes in the same row:

  • shrink-0 on CardAction. The Badge already had it, but its wrapper did not, so the wrapper was shrinking to a smaller box than its own content.
  • min-w-0 + break-words on the title, so a long single-word name breaks rather than spilling.
  • shrink-0 on the platform logo, which was being squashed out of square on narrow cards — the Microsoft Teams mark rendered 12x20 instead of 20x20, and Google Chat 14.5x20.

One file, five class-list changes; no data, copy, or component-API changes.

Why not flex-wrap (the first commit in this PR)

Letting the row wrap fixes the clipping, but wrapping is content-driven: with the 44px Beta badge, Slack (42px) and Discord (57px) still fit inline while Google Chat (93px) and Microsoft Teams (124px) pushed the badge to the next line. Between ~430px and ~560px a single grid row showed both placements side by side. The second commit replaces it with the breakpoint switch above.

Test plan

Ran pnpm --filter docs dev and measured /adapters in a real browser at 320, 360, 375, 390, 400, 401, 412, 430, 470, 500, 560, 600, 601, 640, 700, 768, 900, 960, 961, 1024, 1280 and 1440px, asserting per card that placement mode is uniform across the page, the badge sits a constant distance from the card edge, the header row does not overflow, the title does not spill, the badge stays inside the card's content box, and every logo renders 20x20.

main flex-wrap (1st commit) this PR
widths mixing inline + stacked badges 0 (all clipped instead) 430–560px none
distinct badge offsets from card edge 25px, all 32 cards, all 22 widths
cards with a clipped title or badge @412px 13 0 0
worst header-row overflow 68px 0 0
worst title spill 29px 0 0
squashed logos 5+ 0 0

Also confirmed visually at 430px (uniform stacked badges where the mixed placement was reported), 640px (uniform inline badges, including the one title that wraps to two lines) and 1440px (three-column layout unchanged from main), plus on the PR's own preview deployment.

One known sub-pixel residual: at exactly 401px — the two-column breakpoint boundary, where cards are 169px — PostgreSQL plus its 20px logo needs 0.89px more than the row, so the final glyph loses under a pixel to overflow-hidden. wrap-anywhere removes it but renders the name as PostgreSQ / L, which is a worse outcome for an invisible gain, so break-words is kept.

Also ran npx ultracite check apps/docs/app (clean) and tsc --noEmit for apps/docs (clean).

Checklist

  • All commits are signed and verified
  • All commits are signed off for the DCO (git commit -s)
  • pnpm validate passes — not run in full; it builds every package and needs adapter credentials. Ran the parts that cover this change: ultracite check apps/docs/app and tsc --noEmit in apps/docs, both clean.
  • Changeset added (or N/A) — N/A, apps/docs is private and CONTRIBUTING lists documentation changes as not needing one.
  • Documentation updated (or N/A) — N/A, no content change.

Note

The commits are GPG-verified, but they were authored through a Vercel Devbox, so the author identity is vercel[bot] with Signed-off-by/Co-Authored-By trailers for @aldosch. If the DCO check wants the sign-off to match the author line, say so and I'll push a remediation commit (allowRemediationCommits.individual is enabled).

The Geist breakpoints geistdocs ships put `sm` at 401px, so the adapters
grid goes two-up on every modern phone and each card is only ~175px wide.
The card header row was a non-wrapping `justify-between` flex row, so the
115px `Vendor official` badge — `whitespace-nowrap shrink-0` — took nearly
the whole row: the title's flex item was squeezed below its own text width
(a global `min-width: 0` reset defeats the automatic minimum size), the
name spilled out under the opaque badge, and the card's `overflow-hidden`
cut off whatever was left. "Liveblocks" rendered as "Liveblo", and the
badge itself ran ~16px past the card edge.

Let the header row wrap so the badge drops onto its own line when there is
no room beside the title, and keep the pieces from being squeezed:

- `flex-wrap` plus `gap-x-3 gap-y-2` on the row. With `justify-between`
  the badge still sits right-aligned beside the title whenever it fits, so
  the two- and three-column layouts are unchanged.
- `shrink-0` on `CardAction` — the `Badge` already had it, but its wrapper
  did not, so the wrapper was shrinking to a smaller box than its content.
- `min-w-0` plus `break-words` on the title, so a long single-word name
  breaks instead of spilling.
- `shrink-0` on the platform logo, which was being squashed out of square
  on narrow cards (the Microsoft Teams mark rendered 12x20 instead of
  20x20).

Verified in a browser at 320-1440px: no row overflow, no title spill, no
squashed logos, and desktop layout byte-for-byte unchanged.

Signed-off-by: aldo <5773006+aldosch@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Co-Authored-By: aldo <5773006+aldosch@users.noreply.github.com>
@aldosch
aldosch requested a review from a team as a code owner September 3, 2026 23:34
@vercel

vercel Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
chat Ready Ready Preview, v0 Sep 3, 2026 11:50pm UTC
chat-sdk-nextjs-chat Ready Ready Preview, v0 Sep 3, 2026 11:50pm UTC

@aldosch

aldosch commented Sep 3, 2026

Copy link
Copy Markdown
Author

not ideal because now we have inconsistent badge placement depending on card title length
2026-09-03 at 23 39 28

…-driven

The previous commit let the card header row wrap, which fixed the clipping
but made placement depend on each card's title length: with a 44px `Beta`
badge, `Slack` (42px) and `Discord` (57px) still fit inline while
`Google Chat` (93px) and `Microsoft Teams` (124px) pushed the badge onto
the next line. Between roughly 430px and 560px — iPhone Pro Max width —
a single grid row therefore showed both placements side by side.

Wrapping is content-driven by definition, so replace it with a breakpoint
switch. Below `md` (601px in the Geist scale) the header stacks: title,
then badge on its own line, left-aligned, for every card. At `md` and up
every card puts the badge inline to the right. Whether a badge fits is now
a property of the layout, not of the name next to it.

`md` is where the narrowest card can hold the widest badge with room to
spare: the two-column band starts at 401px with ~123px of row width — less
than the 115px `Vendor official` badge plus a gap — while at 601px the row
is ~228px. Above `md` the title still wraps within its own flex item if it
is long, so the badge keeps its position instead of being pushed out.

Measured across 320-1440px: badge placement mode is uniform at every width
(no width mixes inline and stacked), and the badge sits exactly 25px from
the card edge in all 32 cards at all 22 widths sampled.

Signed-off-by: aldo <5773006+aldosch@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Co-Authored-By: aldo <5773006+aldosch@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants