Skip to content

feat: shareable result card + age-group split percentile pills#182

Merged
rootulp merged 14 commits into
mainfrom
claude/distracted-chandrasekhar-16623a
May 12, 2026
Merged

feat: shareable result card + age-group split percentile pills#182
rootulp merged 14 commits into
mainfrom
claude/distracted-chandrasekhar-16623a

Conversation

@rootulp
Copy link
Copy Markdown
Owner

@rootulp rootulp commented May 12, 2026

Summary

Two coupled UX upgrades to the result page (the most-shared surface on the site):

  • Shareable result card — every result URL now unfurls into a polished 1200×630 PNG (Layout A: dark gradient, name + race meta, hero finish time, overall + AG percentile, three split tiles). The result page header now has a ghost-styled Share button that opens a popover with Copy link and Download image. Image is served by a new opengraph-image.tsx route; Next.js wires <meta property="og:image"> and <meta name="twitter:image"> automatically.
  • Inline age-group percentile pills — each discipline card (Swim / Bike / Run / Total) on the result page now shows a small amber corner pill with the athlete's AG percentile. renders when histogram data is unavailable.

Spec: docs/superpowers/specs/2026-05-10-share-card-and-split-percentiles-design.md
Plan: docs/superpowers/plans/2026-05-10-share-card-and-split-percentiles.md

Files

New

  • app/src/lib/percentile.tsformatPercentile (handles 0 / NaN / Infinity as no-data → )
  • app/src/components/PercentilePill.tsx — small server component
  • app/src/components/ShareDialog.tsx — client component (clipboard, Escape, outside-click, focus return)
  • app/src/app/race/[slug]/result/[id]/opengraph-image.tsx — Node-runtime next/og image route, 24h revalidate, fallback for missing race/athlete
  • app/src/lib/__tests__/percentile.test.ts — vitest
  • app/e2e/result-share-and-pills.spec.ts — Playwright

Modified

  • app/src/app/race/[slug]/result/[id]/page.tsx — header is now flex (name left, Share right), pills added to each of the four discipline cards

Test plan

  • Unit (npm test) — 13/13 pass (3 new, 10 existing)
  • E2E (npx playwright test) — 10/10 pass (5 new: pills render, share dialog opens, clipboard copy, Escape close, OG returns PNG, og:image meta present)
  • Lint (npm run lint) — clean
  • Production build (npm run build) — succeeds; opengraph-image route registered as dynamic
  • Smoke against npm run start — OG route returns 200 + image/png; result page HTML contains <meta property="og:image" ...>
  • Verify on Vercel preview: paste a result URL into Slack / iMessage / Twitter and confirm the card unfurls
  • Verify on mobile viewport: Share button shows as icon-only, header doesn't push the button off-screen with long athlete names

Out of scope (deferred)

  • AthleteRaceList percentile pills (needs separate perf decision per race-row histogram lookup)
  • Per-pill color variation by performance band (kept amber)
  • Web Share API integration

🤖 Generated with Claude Code

rootulp and others added 14 commits May 10, 2026 20:08
Brainstormed design for two UX features: an OG image / downloadable share
card on result pages, and inline age-group percentile pills on each
discipline card. Layout and integration decisions locked via visual
review. Implementation plan to follow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 tasks covering: percentile formatting helper (TDD), PercentilePill
component, integration into result page discipline cards, ShareDialog
client component, header integration, opengraph-image route via
next/og, and Playwright e2e coverage. Plan references the design spec
in docs/superpowers/specs/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rootulp rootulp self-assigned this May 12, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 12, 2026

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

Project Deployment Actions Updated (UTC)
tritimes Building Building Preview, Comment May 12, 2026 6:45pm

@rootulp rootulp merged commit 5a75b18 into main May 12, 2026
5 of 6 checks passed
@rootulp rootulp deleted the claude/distracted-chandrasekhar-16623a branch May 12, 2026 18:45
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.

1 participant