UI
Product Page Grammar
The shared structure and primitives used by authenticated product pages.
Product pages should feel like one system even when their data and permissions
differ. Use the shared components exported by @leavelocalhost/ui instead of
recreating page-level patterns in each route.
Standard Anatomy
- A
PageHeaderwith one clear title, optional description, and a compact action area. - A responsive content grid with the primary task first in DOM order.
- Semantic cards or sections; use headings to label regions, not decorative text.
- A route-level skeleton whose geometry matches the final page.
- A designed empty or error state in the same content footprint.
Use PageHeader, EmptyState, ErrorState, StatusBadge, and the structural
skeletons from packages/ui. Use shadcn primitives for interaction behavior.
State and URL Rules
- Store filters, selected tabs, pagination, and expanded rows in the URL with
nuqsso views are shareable and browser navigation works. - Use
aria-disabledwith guarded activation and visible adjacent explanation for unavailable actions. Plan-gated upgrade destinations remain real links. - Never hide permissions failures behind a disabled control with tooltip-only explanation.
- Keep meaningful data in a single preloaded route view model when the page cannot render usefully without it.
Responsive Rules
Design mobile-first. Actions may wrap below the title, tables may become a purpose-built compact list, and charts must keep readable labels. Horizontal page scrolling is a failure; intentionally scrollable inner regions must have an accessible name.