Skip to content

feat(ui): pseudo-function style for 404, footer, empty state, library card#6436

Merged
MarkusNeusinger merged 4 commits into
mainfrom
claude/fix-anyplot-issues-U5dPX
May 16, 2026
Merged

feat(ui): pseudo-function style for 404, footer, empty state, library card#6436
MarkusNeusinger merged 4 commits into
mainfrom
claude/fix-anyplot-issues-U5dPX

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Follow-up to #5293, addresses the in-codebase surfaces from #5292.

Summary

Applies the brand's .verb() / subject.verb() notation (style guide §7.4.1) to the surfaces that already exist in the frontend and were deferred from the previous pseudo-function pass.

Surface Before After
404 headline (NotFoundPage) 404 page.miss()
404 sub-message page not found 404 — no route matched
404 home link back to anyplot.ai page.home()
Footer about link about .about()
Footer legal link legal .legal()
Empty filter state (FilterBar, MapPage) no matches results.empty()
Library-card hover CTA (LibraryCard) browse → .explore()

aria-label attributes retain human-readable copy ("Page not found", "About anyplot", "No matches", etc.) per §7.4.1 — screen readers shouldn't announce .about() as "dot about open close paren".

Out of scope (still tracked on #5292)

These surfaces don't exist in the codebase yet — the issue stays open for convention-before-build:

  • Keyboard-help (?) overlay → help.keys()
  • RSS / subscribe → feed.subscribe()
  • Copy-link / share on spec detail → .share()

Footer contact link also doesn't exist; only about and legal were re-labelled. legal mapped to .legal() rather than the issue's .license() because the actual page covers legal notice, privacy, and transparency — .license() would be too narrow.

Test plan

  • yarn lint (no new warnings)
  • yarn tsc --noEmit (clean)
  • yarn test --run (452/452 passing — updated NotFoundPage, Footer, RouteErrorBoundary, SpecPage tests for new copy)
  • Manual: visit /some-bogus-route and confirm page.miss() headline renders two-tone
  • Manual: hover library card, confirm .explore() turns green
  • Manual: open filter dropdown with no matches, confirm results.empty() renders mono

Refs #5292


Generated by Claude Code

…ibrary card

Follow-up to #5293. Applies the brand's `.verb()` / `subject.verb()`
notation to the surfaces already in the codebase that were deferred in
issue #5292:

  page.miss()       404 headline (NotFoundPage)
  page.home()       NotFoundPage back-to-home link
  .about()          footer about link
  .legal()          footer legal link
  results.empty()   empty filter state (FilterBar, MapPage)
  .explore()        library-card hover CTA (was "browse →")

aria-labels keep human-readable copy for screen readers per style guide
§7.4.1. Out-of-scope items from #5292 (keyboard-help overlay, RSS,
spec-detail share button) remain tracked there — those surfaces don't
exist in the codebase yet.

Refs #5292
Copilot AI review requested due to automatic review settings May 12, 2026 07:15
@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
app/src/pages/MapPage.tsx 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the frontend “pseudo-function” brand copy pass by updating a few remaining UI surfaces (404 page, footer links, empty states, and the library-card CTA) to use .verb() / subject.verb() notation while keeping screen-reader-friendly text via aria-label.

Changes:

  • Restyled the 404 page headline/link and updated related tests to assert via accessible heading name.
  • Updated footer “about/legal” link labels to .about() / .legal() and adjusted tests accordingly.
  • Updated empty-result copy in FilterBar/MapPage to results.empty() and the library card CTA to .explore() (with hover color change).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
app/src/pages/SpecPage.test.tsx Updates 404 assertions to match the new NotFound copy/accessibility name.
app/src/pages/NotFoundPage.tsx Applies pseudo-function styling to 404 headline/sub-message/home link.
app/src/pages/NotFoundPage.test.tsx Adjusts NotFoundPage tests for new heading/message/link rendering.
app/src/pages/MapPage.tsx Updates empty search state copy to results.empty().
app/src/components/RouteErrorBoundary.test.tsx Updates 404 fallback assertions to match new NotFound copy/accessibility name.
app/src/components/LibraryCard.tsx Changes hover CTA from “browse →” to .explore() and adds hover color styling.
app/src/components/Footer.tsx Renames footer link labels to .about() / .legal() and adds aria-labels.
app/src/components/Footer.test.tsx Updates footer tests for the new .about() / .legal() labels.
app/src/components/FilterBar.tsx Updates “no matches” empty state to results.empty() with mono styling.

Comment on lines 32 to 38
<Box
component={Link}
to="/"
sx={{ color: colors.primary, fontFamily: typography.fontFamily, textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }}
sx={{ color: colors.primary, fontFamily: typography.mono, textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }}
>
back to anyplot.ai
<Box component="span" sx={{ color: 'var(--ink-muted)' }}>page</Box>.home()
</Box>
Comment on lines +97 to 108
<Box className="lib-card-cta" sx={{
fontFamily: typography.mono,
fontSize: '11px',
color: 'var(--ink-muted)',
mt: 'auto',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
transition: 'color 0.2s',
}}>
<span>browse →</span>
<span aria-label={`Browse ${name} examples`}>.explore()</span>
</Box>
Comment thread app/src/pages/NotFoundPage.test.tsx Outdated
render(<NotFoundPage />);
const link = screen.getByText('back to anyplot.ai');
expect(link.closest('a')).toHaveAttribute('href', '/');
const link = screen.getByText('.home()').closest('a');
…ntrols

Address Copilot review feedback on #6436:

- NotFoundPage home link: add aria-label="Go home" and wrap the visible
  page.home() text in aria-hidden so screen readers announce the
  human-readable name instead of "dot home open close paren".
- LibraryCard button: add aria-label="Browse <name> examples" on the
  outer button (the interactive element) and mark the visible
  .explore() span as aria-hidden.
- NotFoundPage test: assert via getByRole('link', { name: /go home/i })
  so the test verifies the accessible name rather than implementation
  text nodes.

Matches style guide §7.4.1: pseudo-function style is a visual
convention; aria-label must stay in readable human language.
Copilot AI review requested due to automatic review settings May 16, 2026 19:43
@MarkusNeusinger MarkusNeusinger enabled auto-merge (squash) May 16, 2026 19:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

MarkusNeusinger and others added 2 commits May 16, 2026 21:44
Drops the pseudo-function styling (.about() / .legal()) from the Footer
while preserving it on the other surfaces (404, library card, empty
states). Removes the aria-label crutch since the text is now readable
on its own.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MarkusNeusinger MarkusNeusinger merged commit 9901194 into main May 16, 2026
7 checks passed
@MarkusNeusinger MarkusNeusinger deleted the claude/fix-anyplot-issues-U5dPX branch May 16, 2026 19:46
MarkusNeusinger added a commit that referenced this pull request May 18, 2026
Version bump for the v2.4.0 release. Release notes will be attached to
the tag once this lands.

## Highlights since v2.3.0

- **R / ggplot2 added as the 10th library** + multi-language pipeline
(#6944, #6961, #7052). 30 ggplot2 implementations landed across
foundational plot types.
- **In-app feedback widget** (#7143).
- **Stats page** with Plausible visitors chart + daily-impl timeline
(#6608).
- **Language across the site**: `/plots?lang=` filtering, cross-language
carousel, language in URLs and titles (#7141, #7142, #7144).
- **UI polish**: pseudo-function styling for 404 / footer / empty state
/ library card (#6436); mobile fixes for `/stats`, `/mcp`, breadcrumb +
FAB (#6902, #7283).
- **Pipeline**: review-retry listener + stuck-jobs watchdog (#6084);
daily-regen 2h → hourly (#6943).
- **Dependencies**: mypy 1.20→2.1, urllib3 2.6→2.7, authlib bump,
react/mui/python-minor groups.
- ~1200 implementation regenerations across all 10 libraries.

No SemVer-breaking changes.

**Full Changelog:**
v2.3.0...main

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.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.

3 participants