polish(team): semantic h1, portfolio context, tablist keyboard nav#19
Open
f1shyfang wants to merge 1 commit into
Open
polish(team): semantic h1, portfolio context, tablist keyboard nav#19f1shyfang wants to merge 1 commit into
f1shyfang wants to merge 1 commit into
Conversation
… states
Page opened straight into filter chips with no title or context.
Added an eyebrow + semantic h1 ("The students running CEUS this year")
+ subtitle, then per-portfolio h2 with a short student-voice blurb
and member-count line. Portfolio blurbs sit in a small dictionary so
they're easy to revise without touching layout.
GSAP entrance now wrapped in window.matchMedia('(prefers-reduced-motion: reduce)')
check and uses gsap.context() for proper cleanup.
Empty state replaced from a centered <p> with no CTA to the bordered-
card pattern used elsewhere: brand-voice copy ("This portfolio is
recruiting.") + Brand Navy contact CTA. Separate top-level state for
"committee still being finalised" when the global dataset is empty.
Container background switched from bg-gray-100 to bg-white to match
the polished home and events pages. Filter row gains
section[aria-label="Filter by portfolio"] + div[role="tablist"], with
full arrow-key + Home/End navigation (automatic activation; roving
tabindex on FilterButton children).
FilterButton (shared): active state to Brand Navy (was bg-blue-500),
role="tab" + aria-selected + tabIndex={isActive ? 0 : -1} for tablist
children, hairline border, focus-visible ring, fixed file-header
copy-paste artifact (was labelled EventFilterButton).
MemberCard (shared): focus-visible everywhere (was focus:),
motion-safe on hover:scale-125 (magnitude preserved per design spec),
explicit transition-[transform,box-shadow,colors], richer alt text
including role, hairline border, Ink Strong heading color. Non-clickable
variant (no LinkedIn URL) now drops interactive hover affordances
(scale, shadow lift, focus ring, name color shift) so it doesn't
mis-signal interactivity.
tsc --noEmit: clean. eslint: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Polish pass on the /team page and its shared UI components to improve semantic structure, accessibility (notably keyboard navigation), and overall page context/empty-state presentation.
Changes:
- Added a semantic page intro (eyebrow +
<h1>+ subtitle) and richer per-portfolio context (blurb + member count + improved empty states). - Implemented
tablist-style portfolio filters with roving tabindex and arrow/Home/End keyboard navigation. - Updated shared
MemberCardandFilterButtonstyling/behavior (reduced-motion guards, focus-visible rings, brand color alignment, non-interactive card variant).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| CEUS/src/app/team/TeamClient.tsx | Adds hero/title context, tablist keyboard navigation, GSAP reduced-motion guard, and improved empty states for team portfolios. |
| CEUS/src/components/FilterButton.tsx | Updates filter button styling and adds tab semantics (role/tabIndex/aria-selected). |
| CEUS/src/components/MemberCard.tsx | Refines focus/hover behavior, reduced-motion guards, alt text, and non-clickable variant styling. |
| CEUS/src/app/team/page.tsx | Updates /team metadata title/description for clearer SEO/context. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'bg-white p-5 md:p-6 rounded-xl border border-gray-200 shadow-lg flex flex-col items-center text-center member-card-gsap'; | ||
|
|
||
| const interactiveClasses = | ||
| 'group cursor-pointer transition-[transform,box-shadow,colors] duration-300 ease-out ' + |
| className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 lg:gap-8" | ||
| > | ||
| {displayedMembers.map((member) => ( | ||
| <div key={member.id} className="member-card-gsap"> |
Comment on lines
+14
to
+16
| role="tab" | ||
| aria-selected={isActive} | ||
| tabIndex={isActive ? 0 : -1} |
Comment on lines
+171
to
+174
| <section | ||
| aria-labelledby="active-portfolio-heading" | ||
| className="container mx-auto px-4 sm:px-6 lg:px-8 pb-20 md:pb-28" | ||
| > |
| 'bg-white p-5 md:p-6 rounded-xl border border-gray-200 shadow-lg flex flex-col items-center text-center member-card-gsap'; | ||
|
|
||
| const interactiveClasses = | ||
| 'group cursor-pointer transition-[transform,box-shadow,colors] duration-300 ease-out ' + |
| className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 lg:gap-8" | ||
| > | ||
| {displayedMembers.map((member) => ( | ||
| <div key={member.id} className="member-card-gsap"> |
Comment on lines
+14
to
+16
| role="tab" | ||
| aria-selected={isActive} | ||
| tabIndex={isActive ? 0 : -1} |
Comment on lines
+171
to
+174
| <section | ||
| aria-labelledby="active-portfolio-heading" | ||
| className="container mx-auto px-4 sm:px-6 lg:px-8 pb-20 md:pb-28" | ||
| > |
Comment on lines
+175
to
+179
| {!hasAnyMembers ? ( | ||
| <div className="mx-auto max-w-2xl rounded-xl border border-gray-200 bg-gray-50 px-8 py-10 md:px-12 md:py-14 text-center shadow-sm"> | ||
| <p className="text-lg font-semibold text-gray-900 mb-2"> | ||
| The 2026 committee is still being finalised. | ||
| </p> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Polish pass on
/teamplus the sharedMemberCardandFilterButtonit uses. Critique score moved from 18/40 → 33/40 (largest individual-page jump in the series).Page (
team/page.tsx,TeamClient.tsx)<h1>("The students running CEUS this year") with eyebrow + subtitle. The page used to open straight into filter chips with no title or context.<h2>+ a short student-voice blurb (CATEGORY_BLURBSdictionary) + member-count line. The page used to look like a directory dump.<section aria-label="Filter by portfolio">+<div role="tablist">with full WAI-ARIA arrow-key + Home/End navigation (automatic activation; roving tabindex on FilterButton children).prefers-reduced-motioncheck viawindow.matchMedia, usinggsap.context()for proper cleanup.bg-gray-100tobg-whiteto match other polished pages.MemberCard(shared)focus-visible:everywhere (wasfocus:).motion-safe:hover:scale-125— magnitude preserved per the "warm-hearted chapter" design spec, just guarded for reduced-motion users.transition-[transform,box-shadow,colors](wastransition-all)."{name}, {role}"for screen readers.linkedInUrl): now drops interactive hover affordances (scale, shadow lift, focus ring, name color shift) so a static card doesn't look interactive.FilterButton(shared)bg-blue-500).role="tab"+aria-selected={isActive}+tabIndex={isActive ? 0 : -1}for tablist children.EventFilterButton).Test plan
npm run dev→/team— verify hero eyebrow + h1 + subtitle appear above the filter rowprefers-reduced-motion: reduce; verify the GSAP card entrance is staticlinkedInUrlon a member (or all members), verify the card doesn't scale or color-shift on hoverVerification
tsc --noEmit: cleaneslint: cleanMerge note
Independently mergeable. No file overlap with other polish PRs.
🤖 Generated with Claude Code