Skip to content

Make app cards one clear, accessible click target everywhere - #60

Merged
hipstersmoothie merged 6 commits into
ATProtocol-Community:mainfrom
renderghost:renderghost/app-card-usability
Nov 7, 2026
Merged

hipstersmoothie merged 6 commits into
ATProtocol-Community:mainfrom
renderghost:renderghost/app-card-usability

Conversation

@renderghost

@renderghost renderghost commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Why

App cards were drawn five different ways across the site, and they had several usability and accessibility problems:

  • The large home card was just an image, so it didn't read as an app or as something to click.
  • Grid cards had room for star ratings and categories but showed neither.
  • Hovering a card made the cursor flicker between the arrow and the pointing hand.
  • Trending rows had an Explore button inside a row that was already a link.
  • Cards had rounded corners, but their keyboard focus outline was square.
  • On Browse, only the icon and name of a row were clickable, not the whole row.

The goal is cards that are more usable, more accessible and more delightful, without breaking any layout.

What changed

One card family

  • AppCard (large / medium / small) replaces the three hand-rolled home cards, EcosystemListingCard, FeaturedListingFallbackCard and the three copies of the lexicon listing card.
  • AppListRow has two variants with the same look: RankedAppRow for the home "Trending" list and DetailedAppRow for Browse.

Interaction and accessibility

  • One link per card or row, with nothing clickable inside it. The Explore button is gone and chips are plain labels. Each link is named after the app and described by its tagline, labels and rating.
  • No cursor flicker: the link itself never moves, and only the surface inside it lifts on hover. The flicker happened because the old cards moved the link out from under the pointer at their bottom edge.
  • No dead zones between rows: the spacing between rows belongs to the row links.
  • Rounded keyboard focus: a 2px primary ring with a 2px offset that follows the card's rounded corners, shown for keyboard focus only (:focus-visible).
  • Real lists: Trending is an <ol>, so screen readers announce "1 of 6", and Browse results are a <ul>.

Content

  • Grid cards show a star rating, or empty stars with "No reviews yet". They also show up to 2 labels (ecosystem category first, then editorial tags) plus a "+N" count, kept to one line.
  • Browse rows show every label, the same rating format, favourites, last update, and a chevron.
  • The large card now shows the full details under its image, like the medium card.

Layout

  • Home hero: on desktop, the hero takes 2 columns with 3 spotlight cards stacked beside it. On tablet, the spotlights sit in a row of 3 under the hero. On phones, everything stacks.
  • Hero image fills spare height: a large card's image grows when the card is taller than its content, so the card never has an empty band. On desktop that crops the image to about 1.38:1; on tablet and phone it stays exactly 16:9.
  • Narrow cards adapt to their own width with a container query (@container (max-width: 16rem)). They tighten padding, put the icon above the name, shorten the rating text and show 1 label plus "+N". This handles the tablet row of 3 at 640–1023px.
  • "Fresh apps" is a row of 3 on tablet instead of 2 + 1.
  • FeaturedListingGrid (ecosystem and lexicon pages) uses the same pattern as the home hero, so a block is now 7 apps instead of 9. The ecosystem page's first section shows 7 apps so it fills evenly.

Data / admin

  • The home page asks for 3 spotlights instead of 2.
  • The admin "Home page hero" screen has 4 slots. If fewer apps are configured, they're kept and the rest are filled from recent apps; previously a short list was thrown away entirely.

Fixes along the way

  • AspectRatioImage applied its style to both the wrapper and the <img>. Nothing else passed a style, but it doubled the new hover zoom.
  • Pagination kept the browser's default list indent, which made Browse scroll sideways on 360–375px phones. This was already broken before this PR; it's in its own commit.

Behaviour changes worth a look

  • Browse labels are no longer filter links. They're plain labels inside the row link, and the sidebar filters still do the filtering.
  • Large cards no longer have the blurred colour glow on ecosystem and lexicon pages.
  • Ecosystem and lexicon pages feature every 7th app instead of every 9th, and the ecosystem page's first section shows 7 apps instead of 6.
  • The admin hero screen needs 4 picks to save. A 3-pick configuration already saved still works; the 4th spotlight is auto-filled until someone picks one.

Testing

  • pnpm test, lint, format:check, typecheck and build all pass. A new unit test covers the label helper.
  • I checked home, Browse and the Bluesky ecosystem page in the browser at 360, 375, 640, 768, 1024, 1280 and 1440px, in light and dark mode:
    • no horizontal scroll at any width;
    • every app link is a single target with nothing clickable nested inside;
    • the pointer cursor shows on every element inside the cards;
    • there are no gaps between row links;
    • the focus ring follows the rounded corners.
  • Not checked with real data:
    • The lexicon pages: there's no lexicon data locally, so I only confirmed they load. They use the same grid and card as the ecosystem page.
    • The admin hero screen, which needs an admin login.

Screenshots

https://mu.social/profile/did:plc:s2rczyxit2v5vzedxqs326ri/post/3mzpytubkfc2s

🤖 Generated with Claude Code

renderghost and others added 6 commits November 7, 2026 13:36
The home page had three hand-rolled card variants. Replace them with one
shared AppCard (large/medium/small). The link is now the stationary hit
area and only the inner surface lifts on hover, which stops the cursor
flickering at the card's bottom edge. Keyboard focus draws a 2px primary
ring that follows the card's rounded corners.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Medium and small cards now show up to two labels (ecosystem category,
then editorial tags) with a "+N" overflow chip, plus a star rating or
"No reviews yet". Labels stay on one line: only the first may truncate
and later ones are width-capped, so short tags never collapse. The card
link is described by tagline, labels and rating for screen readers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The large card is now a real card: image on top, then the same details
as other cards (identity, tagline, labels, rating, chevron). On desktop
the hero sits beside three stacked spotlights and its image grows to
fill any spare height; on tablet the spotlights and the "Fresh apps"
grid sit in a row of three under the hero.

Cards adapt to their own width with a container query: narrow cards
tighten padding, stack the icon above the name, shorten the rating and
show one label plus "+N".

The home page now asks for three spotlights. The admin hero screen gets
a fourth slot, and a partial admin list is topped up from recent apps
instead of being discarded. AspectRatioImage no longer applies its image
style to the wrapper as well, which doubled the hover zoom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add AppListRow with two variants sharing one look: a compact numbered
row for the home "Trending" list and a detailed row for Browse. Each row
is one stationary link (no Explore button, no nested filter-badge
links), hovers with a tint and shadow, and draws the rounded focus ring.
Spacing between rows belongs to the links, so there are no dead zones.

Browse rows show every label (wrapping), the card rating format and a
chevron. Both lists are now real lists; the trending list is an ordered
list so screen readers announce position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace EcosystemListingCard and the three copied lexicon listing cards
with AppCard, and delete the now-unused EcosystemListingCard and
FeaturedListingFallbackCard.

FeaturedListingGrid follows the home hero rhythm: the large card spans
two columns and three rows on desktop (full width on tablet) with three
small cards beside it, so blocks are now seven apps instead of nine.
The ecosystem page's first section shows seven apps so it fills evenly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pagination lists kept the browser's default list indent and margins,
which pushed the control 4-19px past the edge of 360-375px viewports and
made the Browse page scroll sideways. Reset them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renderghost
renderghost marked this pull request as ready for review November 7, 2026 13:34
@hipstersmoothie
hipstersmoothie merged commit 87e937e into ATProtocol-Community:main Nov 7, 2026
5 checks passed
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