Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions agentic/commands/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ This prompt helps you determine what documentation you should read based on the
- When implementing new visualizations
- When modifying existing plot implementations

- agentic/context/260207-footer-responsive-hide-name-add-contact-links.md
- Conditions:
- When working with the Footer component responsive behavior
- When modifying contact or social links in the Legal page
- When adjusting mobile breakpoint visibility of footer elements
Comment on lines +51 to +55
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

agentic/commands/context.md is a general “conditional documentation” guide; adding a single run-specific context file path here doesn’t scale and will quickly bloat this list. Consider pointing to agentic/context/ (or describing a naming pattern) instead of hardcoding an individual context file entry.

Suggested change
- agentic/context/260207-footer-responsive-hide-name-add-contact-links.md
- Conditions:
- When working with the Footer component responsive behavior
- When modifying contact or social links in the Legal page
- When adjusting mobile breakpoint visibility of footer elements
- agentic/context/
- Conditions:
- When there is a run-specific or task-specific context file related to your changes
- When you see a context filename (for example, date-prefixed and task-described) mentioned in the task
- When you need additional guidance for a particular change beyond the general project documentation

Copilot uses AI. Check for mistakes.

- agentic/
- Conditions:
- When working with agentic commands or workflows
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Responsive Footer Name & Legal Contact Links

**Run ID:** d7e7bdf6
**Date:** 2026-02-07
**Specification:** agentic/specs/260207-footer-responsive-hide-name-add-contact-links.md

## Overview

The footer's "markus neusinger" link is hidden on mobile viewports (below 900px / `md` breakpoint) to prevent a cramped layout, and social contact links (LinkedIn, X, GitHub) were added to the Legal Notice page's Contact section to keep contact information discoverable.

## What Was Built

- Responsive hiding of the "markus neusinger" link and its dot separators in the footer on screens below the `md` breakpoint (900px)
- LinkedIn, X (Twitter), and GitHub contact links added to the Legal Notice page Contact section with analytics tracking

## Technical Implementation

### Files Modified

- `app/src/components/Footer.tsx`: Wrapped the "markus neusinger" link and its surrounding dot separators in a `<Box>` with responsive `display` (`{ xs: 'none', md: 'contents' }`) to hide them on mobile
- `app/src/pages/LegalPage.tsx`: Added three social links (LinkedIn, X, GitHub) to the Contact section below the existing email link, each with `target="_blank"`, `rel="noopener noreferrer"`, matching `#3776AB` color styling, and `trackEvent` analytics calls

### Key Changes

- Used MUI's responsive `sx` display prop for pure CSS-based hiding — no JavaScript media query hooks needed
- The `<Box component="span" sx={{ display: { xs: 'none', md: 'contents' } }}>` wrapper ensures the name link and both adjacent dot separators are hidden/shown together, and `contents` on desktop means the Box has no visual impact
- Social links in the Legal page follow the existing pattern: `<br />` line breaks within the `<Typography>` block, consistent `#3776AB` link color
- Analytics tracking uses `trackEvent('external_link', { destination: 'linkedin' | 'x' | 'github_personal' })` matching the existing event pattern

## How to Use

1. On mobile devices or viewports narrower than 900px, the footer displays: `github · stats · mcp · legal`
2. On desktop viewports (900px and wider), the footer displays the full set: `github · stats · markus neusinger · mcp · legal`
3. Social contact links are always visible on the Legal Notice page (`/legal`) in the Contact section

## Configuration

No configuration needed. The `md` breakpoint (900px) is defined by the MUI theme and matches the FilterBar's mobile breakpoint.

## Testing

- `cd app && npx tsc --noEmit` — Verify TypeScript types
- `cd app && yarn build` — Verify no compilation errors
- Resize browser below/above 900px to confirm the footer name link hides/shows
- Visit `/legal` and verify LinkedIn, X, and GitHub links appear in the Contact section

## Notes

- The 900px breakpoint was chosen to match where the FilterBar catalog/filter row wraps to 2 lines on the homepage
- The LinkedIn URL in the footer and Legal page are intentionally the same — redundancy ensures discoverability
- The `github_personal` destination in analytics distinguishes the personal GitHub profile link from the project repository link
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Feature: Responsive Footer Name & Legal Contact Links

## Metadata

run_id: `d7e7bdf6`
prompt: `In the footer, my full name "markus neusinger" is quite long and on small mobile screens it no longer looks clean or minimal. Starting at the same breakpoint where the filter row on the homepage ("catalog" / filters) wraps to two lines, I want my name to no longer be shown in the footer. Instead, in the Legal page Contact section there should be links to my LinkedIn, X, and GitHub accounts in addition to the existing email: https://x.com/MarkusNeusinger https://github.com/MarkusNeusinger https://www.linkedin.com/in/markus-neusinger/`

## Feature Description

Two related changes to improve the mobile experience:

1. **Footer**: Hide the "markus neusinger" link on small screens (below `md` / 900px breakpoint) — the same breakpoint where the FilterBar catalog/filter row wraps to 2 lines on the homepage. The name is too long and makes the footer look cramped on mobile. The dot separator before/after the name link should also be hidden.

2. **Legal Page**: Add social/contact links (LinkedIn, X/Twitter, GitHub) to the Contact section in the Legal Notice, alongside the existing email. This ensures the contact information remains discoverable even when the footer name link is hidden on mobile.

## Requirements

- Hide the "markus neusinger" link (and its surrounding dot separators) in the footer when viewport width is below `md` (900px) — matching the FilterBar's `isMobile` breakpoint
- On viewports `md` and above (900px+), the footer remains unchanged
- Add LinkedIn, X (Twitter), and GitHub links to the Contact section of the Legal Notice on LegalPage
- Social links: LinkedIn (`https://www.linkedin.com/in/markus-neusinger/`), X (`https://x.com/MarkusNeusinger`), GitHub (`https://github.com/MarkusNeusinger`)
- Maintain consistent styling with existing Legal Page link patterns (color `#3776AB`, monospace font)
- Track social link clicks via existing analytics (`onTrackEvent` / `trackEvent`)

## Relevant Files

### Existing Files to Modify

- **`app/src/components/Footer.tsx`** — Hide the "markus neusinger" `<Link>` and its adjacent dot `<span>` separators on screens below `md` breakpoint using MUI's `sx` display responsive prop
- **`app/src/pages/LegalPage.tsx`** — Add LinkedIn, X, and GitHub links to the Contact section (lines 102-109) in the Legal Notice Paper, below the existing email link

### New Files to Create

None.

## Implementation Plan

IMPORTANT: Execute every step in order, top to bottom.

### 1. Update Footer to hide name on mobile

In `app/src/components/Footer.tsx`:

- Add `useMediaQuery` and `useTheme` imports from MUI
- Add `const theme = useTheme()` and `const isMobile = useMediaQuery(theme.breakpoints.down('md'))` inside the component
- Wrap the "markus neusinger" `<Link>` (lines 54-66) and the `<span>·</span>` separator immediately **before** it (line 53) in a `<Box>` (or use `sx={{ display: { xs: 'none', md: 'contents' } }}`) to hide them on small screens
- The simplest approach: use MUI's responsive `display` prop on the separator span and the link:
- On the `<span>·</span>` at line 53: add `sx={{ display: { xs: 'none', md: 'inline' } }}`
- On the `<Link>` for "markus neusinger": add `display: { xs: 'none', md: 'inline' }` to its `sx` prop
- This leaves the remaining 4 links (github · stats · mcp · legal) visible on mobile, with proper dot separation

### 2. Add social/contact links to Legal Page

In `app/src/pages/LegalPage.tsx`:

- Locate the Contact section inside the Legal Notice Paper (around lines 102-109)
- After the existing email link `<Link>`, add three more links on separate lines:
- LinkedIn: `https://www.linkedin.com/in/markus-neusinger/`
- X: `https://x.com/MarkusNeusinger`
- GitHub: `https://github.com/MarkusNeusinger`
- Use the same styling pattern as the email link (`sx={{ color: '#3776AB' }}`)
- Add `target="_blank"` and `rel="noopener noreferrer"` for external links
- Add `onClick` analytics tracking with `trackEvent('external_link', { destination: 'linkedin' })` etc.
- Structure: keep it as a simple list within the existing `<Typography sx={textStyle}>` block using `<br />` for line breaks (matching the existing pattern in the Contact section)

### 3. Verify responsive behavior

- Build the frontend to ensure no TypeScript/compilation errors
- Verify the footer shows 4 links on mobile (<900px) and 5 links on desktop (>=900px)
- Verify the Legal page Contact section shows email + 3 social links

### 4. Add Tests

- No frontend test files exist in the project currently — skip test creation as there is no test infrastructure for React components
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

This spec says there is “no test infrastructure for React components”, but the frontend already has Vitest configured (app/vitest.config.ts, yarn test). If the intent is that there’s no React component testing setup (e.g., Testing Library/JSDOM), please clarify the wording to avoid implying there’s no frontend test runner at all.

Suggested change
- No frontend test files exist in the project currently — skip test creation as there is no test infrastructure for React components
- The frontend already has Vitest configured as a test runner, but there is currently no React component testing setup (e.g., Testing Library/JSDOM) for this area — you can skip adding new component tests for this change

Copilot uses AI. Check for mistakes.

## Validation Commands

Execute these commands to validate the feature:

- `cd app && npx tsc --noEmit` - Check TypeScript types
- `cd app && yarn build` - Build frontend to verify no compilation errors

## Notes

- The `md` breakpoint (900px) was chosen because the user specifically asked for the same breakpoint where the FilterBar wraps to 2 lines, and `FilterBar.tsx` uses `theme.breakpoints.down('md')` for its `isMobile` check
- Using MUI responsive `display` (`{ xs: 'none', md: 'inline' }`) is the lightest-weight approach — no JS needed, pure CSS media queries via MUI's system
- The existing LinkedIn link in the footer (`markus neusinger`) already points to the same URL that will be added to the Legal page — this is intentional redundancy for discoverability
- The GitHub link uses `GITHUB_URL` constant already imported in LegalPage for the Source Code section; the personal GitHub URL (`https://github.com/MarkusNeusinger`) is different from the project repo URL
30 changes: 16 additions & 14 deletions app/src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,22 @@ export function Footer({ onTrackEvent, selectedSpec, selectedLibrary }: FooterPr
>
stats
</Link>
<span>·</span>
<Link
href="https://www.linkedin.com/in/markus-neusinger/"
target="_blank"
rel="noopener noreferrer"
onClick={() => onTrackEvent?.('external_link', { destination: 'linkedin', spec: selectedSpec, library: selectedLibrary })}
sx={{
color: '#9ca3af',
textDecoration: 'none',
'&:hover': { color: '#6b7280' },
}}
>
markus neusinger
</Link>
<Box component="span" sx={{ display: { xs: 'none', md: 'contents' } }}>
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

Breakpoint docs/PR text mention <768px / 960px, but this code uses MUI's md breakpoint. The theme in app/src/main.tsx does not override breakpoints, so md will be the default (900px). Please align the intended cutoff (update copy/specs or adjust theme/breakpoint used here) so the hide/show behavior matches the stated requirement.

Copilot uses AI. Check for mistakes.
<span>·</span>
<Link
Comment on lines +53 to +55
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

The PR description/test plan mentions hiding the footer name on mobile viewports "< 768px", but the implementation hides it below MUI md (900px) via display: { xs: 'none', md: 'contents' }. Please align the requirement and implementation (either update the PR description/test plan to 900px, or change the breakpoint logic to match 768px).

Copilot uses AI. Check for mistakes.
href="https://www.linkedin.com/in/markus-neusinger/"
target="_blank"
rel="noopener noreferrer"
onClick={() => onTrackEvent?.('external_link', { destination: 'linkedin', spec: selectedSpec, library: selectedLibrary })}
sx={{
color: '#9ca3af',
textDecoration: 'none',
'&:hover': { color: '#6b7280' },
}}
>
markus neusinger
</Link>
</Box>
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

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

On viewports below md, this wrapper hides both dot separators around the LinkedIn/name link, which also removes the separator between stats and mcp. On mobile this will render as github · stats mcp · legal (missing the middle dot). Keep a separator between stats and mcp when the name section is hidden (e.g., add a dot that shows on xs/sm and hides on md+ where the name section provides the separators).

Suggested change
</Box>
</Box>
<Box component="span" sx={{ display: { xs: 'inline', md: 'none' } }}>·</Box>

Copilot uses AI. Check for mistakes.
<span>·</span>
<Link
component={RouterLink}
Expand Down
33 changes: 33 additions & 0 deletions app/src/pages/LegalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,39 @@ export function LegalPage() {
<Link href="mailto:admin@pyplots.ai" sx={{ color: '#3776AB' }}>
admin@pyplots.ai
</Link>
<br />
LinkedIn:{' '}
<Link
href="https://www.linkedin.com/in/markus-neusinger/"
target="_blank"
rel="noopener noreferrer"
onClick={() => trackEvent('external_link', { destination: 'linkedin' })}
sx={{ color: '#3776AB' }}
>
markus-neusinger
</Link>
<br />
X:{' '}
<Link
href="https://x.com/MarkusNeusinger"
target="_blank"
rel="noopener noreferrer"
onClick={() => trackEvent('external_link', { destination: 'x' })}
sx={{ color: '#3776AB' }}
>
@MarkusNeusinger
</Link>
<br />
GitHub:{' '}
<Link
href="https://github.com/MarkusNeusinger"
target="_blank"
rel="noopener noreferrer"
onClick={() => trackEvent('external_link', { destination: 'github_personal' })}
sx={{ color: '#3776AB' }}
>
MarkusNeusinger
</Link>
</Typography>

<Typography sx={textStyle}>
Expand Down
Loading