You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since #125, components/site/Footer.tsx has no top padding (pt-16 was removed to fix #123 — the footer's own top padding stacked on top of the preceding section's --frame-pad-y and produced a conspicuous empty band).
This means the footer now derives all of its vertical separation from the bottom padding of whatever block precedes it. Today that is always a Frame (components/ui/Frame.tsx), which applies py-[var(--frame-pad-y)] (clamp 5–7rem):
/ — last section is Close (a Frame)
/blog, /blog/[slug] — content wrapped in a Frame
So it works correctly on every current route, and the coupling to Frame's vertical rhythm is intentional (the design system has Frame own section spacing — see AGENTS.md).
Risk
The contract — "<Footer /> must be preceded by a block that supplies bottom padding (a Frame)" — is implicit and unenforced. Any future page that renders <Footer /> directly after a non-Frame block (or a Frame with fill={false} and unusually short content, or raw markup) will render the footer rule flush against the preceding content, with no diagnostic.
(b) Document and/or enforce the "footer must follow a Frame" rule — e.g. a comment on Footer, or composing the footer inside the final Frame / a shared layout primitive so the spacing is structural rather than incidental.
Not urgent — no current route is broken. Filing so the implicit contract is tracked rather than rediscovered the hard way when a new page is added.
Background
Since #125,
components/site/Footer.tsxhas no top padding (pt-16was removed to fix #123 — the footer's own top padding stacked on top of the preceding section's--frame-pad-yand produced a conspicuous empty band).This means the footer now derives all of its vertical separation from the bottom padding of whatever block precedes it. Today that is always a
Frame(components/ui/Frame.tsx), which appliespy-[var(--frame-pad-y)](clamp 5–7rem):/— last section isClose(aFrame)/blog,/blog/[slug]— content wrapped in aFrameSo it works correctly on every current route, and the coupling to
Frame's vertical rhythm is intentional (the design system hasFrameown section spacing — seeAGENTS.md).Risk
The contract — "
<Footer />must be preceded by a block that supplies bottom padding (aFrame)" — is implicit and unenforced. Any future page that renders<Footer />directly after a non-Frameblock (or aFramewithfill={false}and unusually short content, or raw markup) will render the footer rule flush against the preceding content, with no diagnostic.Options to consider
Footera small intrinsic top padding (e.g.pt-10) and instead reduce the preceding section's contribution, so the footer is self-sufficient. (Trade-off: reintroduces some double-padding onFrame-preceded routes — the exact thing Unnecessary empty space above the footer on the homepage #123/fix: footer gap (#123) + scrollToAnchor NaN guard (#124) #125 removed; would need the preceding--frame-pad-yaccounted for.)Frame" rule — e.g. a comment onFooter, or composing the footer inside the finalFrame/ a shared layout primitive so the spacing is structural rather than incidental.Not urgent — no current route is broken. Filing so the implicit contract is tracked rather than rediscovered the hard way when a new page is added.
Surfaced during the #125 review (PR #125).