Skip to content

Say where the app came from, in a footer on every screen - #22

Merged
danielededo merged 1 commit into
mainfrom
claude/activity-footer
Aug 22, 2026
Merged

danielededo merged 1 commit into
mainfrom
claude/activity-footer

Conversation

@danielededo

Copy link
Copy Markdown
Owner

Why

Somebody can arrive in front of a running Activity Hub without having been the one who deployed it — a NAS in the house, a server set up years ago — and the running app is then their only clue. So the footer carries the link out to the project and its licence.

On every screen, including the one that reports an unreachable API: a person whose stack will not come up is exactly the person who wants the repository, and that screen is where they are stuck. A parameterised test pins all three states.

What it says

Activity Hub — your training, on your own machine. on the left; Source on GitHub (with the mark) and MIT licence on the right, both opening in a new tab with no referrer — the app is self-hosted, and a local address is nobody else's business.

The links are underlined, not merely coloured. They sit in body ink, where colour alone would not say they are links, and this app's rule is that identity is never colour alone. .muted carries the descriptive half: I measured it at 4.55:1 on the light surface and 7.29:1 on the dark one, both clear of AA for normal text — worth checking rather than assuming, at text-xs.

The bug this cost, found by measuring

Putting the footer under every state needs a shell around all three, so the page became a min-h-screen column with a growing body. That made the dashboard a flex item, and a flex item takes its cross size from its content — so the activity table pushed the page out to 339px inside a 320px column and dragged the whole document with it. The same 19px overflow that table-scroll had just been written to stop, arriving by a different route.

I only caught it because I rendered the page and measured document.scrollWidth against the viewport, then confirmed against main that the overflow was mine and not pre-existing. *:w-full on the column gives every child an explicit width and takes the choice away.

docs/DESIGN.md now records it as the third of a family: a grid item needs min-width: 0 to be allowed to shrink, a flex item needs a width to be made to fill, and neither default is what a page layout wants.

A second, smaller one from the same change: the first-run form centred itself with min-h-screen, which would have pushed the footer off a short screen. It grows with the column instead — verified still centred at 800px and 1100px tall (heading at 186 and 336, so it does scale), and content-height on a 420px window where centring would be pointless.

Verified

No horizontal overflow at 320, 360 or 390 px. Footer visible without scrolling on the first-run screen at 1280×800 and 320×640. Rendered and inspected in light and dark. 232 frontend tests (up from 223), 343 backend, eslint and the production build clean. The README's frontend test count is updated with them.

Not regenerated: the twelve README screenshots. They crop the top of each view, so the footer does not appear in any of them.


Generated by Claude Code

Somebody can arrive in front of a running Activity Hub without having been
the one who deployed it — a NAS in the house, a server set up years ago — and
the running app is then their only clue. So the footer carries the link out to
the project and its licence.

On every screen, including the one that reports an unreachable API: a person
whose stack will not come up is exactly the person who wants the repository,
and that screen is where they are stuck. That needs a shell around all three
states, so the page became a min-h-screen column with a growing body and the
footer after it, rather than a footer appended to a full-height view where a
short screen would leave it below the fold.

The links are underlined rather than merely coloured. They sit in body ink,
where colour alone would not say they are links, and this app's rule is that
identity is never colour alone. `.muted` carries the descriptive half: 4.55:1
on the light surface and 7.29:1 on the dark one, both clear of AA.

The layout cost one bug, found by measuring rather than by reading. Making the
body a flex column made the dashboard a flex item, and a flex item takes its
cross size from its content — so the activity table pushed the page to 339px
inside a 320px column and dragged the document with it, the same overflow the
table-scroll utility had just been written to stop. `*:w-full` gives every
child an explicit width and takes the choice away. Third of a family in
docs/DESIGN.md now: a grid item needs min-width:0 to be allowed to shrink, a
flex item needs a width to be made to fill.

The first-run form centred itself with min-h-screen, which would have pushed
the footer off a short screen; it grows with the column instead. Verified
centred at 800px and 1100px tall, and no horizontal overflow at 320, 360 or
390.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019mNxXmXqwMZf6MG8PoWbq4
@danielededo
danielededo merged commit 4932342 into main Aug 22, 2026
4 checks passed
@danielededo
danielededo deleted the claude/activity-footer branch August 22, 2026 13:18
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