This document is the source of truth for frontend visual consistency and layout behavior.
It complements AGENTS.md and does not replace PLAN.md for data contracts.
- Dashboard shell and navigation
- Auth surface layout
- Typography and spacing rhythm
- Interaction states (hover, active, focus)
- Component-level styling primitives
- Sidebar width:
256px(w-64) - Sidebar top row height:
72px - Content header height:
72px - Content header and sidebar top row must stay equal height
- Main content gutter:
px-7 - Main content vertical inset:
py-4
- Dashboard pages must use
components/dashboard/PageShell.tsx - Sidebar nav must be defined in
app/dashboard/layout.tsx - Navigation actions (manage/sign-out) must be defined in
components/DashboardNav.tsx
Avoid per-page ad hoc header wrappers unless intentionally introducing a new global pattern.
- App surfaces and canonical screen specs use
Interonly. Do not introduce alternate display or navigation fonts. - Page title (dashboard shell):
text-lg,font-semibold, subtle tracking - Sidebar brand:
text-[14px],font-semibold - Nav labels:
text-[13px] - Supporting text:
text-[12px]ortext-[13px]
Typography should prioritize legibility and predictable hierarchy over display flair in app surfaces.
- Use
lucide-reacticons only for sidebar navigation - Icon size:
h-4 w-4 - Active state must be visibly stronger than hover:
- Active: stronger bg + border + text contrast
- Hover: clear but lower contrast than active
- Active state should be unambiguous at a glance
- Monochrome-first palette:
- Primary text:
#0A0A0A/#111111 - Secondary text:
#555555 - Muted text:
#999999 - Disabled text:
#BBBBBB - Divider:
#EBEBEB - Input/card border:
#E0E0E0 - Page bg:
#FAFAFA - Panel bg:
#FFFFFF/#F4F4F4
- Primary text:
- Inputs:
h-10orh-11,rounded-[8px], inside border, no heavy shadow - Cards:
rounded-[14px], thin border, white fill - Tables: consistent header row height (
h-10) and row spacing - Buttons:
- Secondary app actions should default to outlined monochrome
- High-emphasis destructive/auth actions should not dominate utility navigation zones
- Preset source of truth:
fe+convex/components.jsonmust usestyle: "radix-vega"for generated components. - Shared shadcn semantic tokens must be defined in
fe+convex/app/globals.cssand remain monochrome-first:background:#FAFAFAforeground:#111111card:#FFFFFFpopover:#F4F4F4border/input:#E0E0E0primary:#0A0A0Aprimary-foreground:#FFFFFFmuted-foreground:#999999ring:#0A0A0Aradius:8px
- Default primitive behavior requirements:
Button: monochrome variants, default control height44px, radius8pxDialog: centered modal, monochrome overlay/surface, Pencil typography hierarchyTabs: strong active highlight, monochrome inactive state, radius8px
- New dashboard/auth interfaces should prefer shared shadcn primitives over per-page ad hoc class stacks.
- Use subtle transitions (
transition, 120-200ms feel) - Avoid excessive animation in dashboard surfaces
- Keep hover/active/focus states crisp and functional
When updating dashboard visuals:
- Update shared primitives first (
PageShell, sidebar, nav actions) - Apply changes across all dashboard pages for parity
- Verify alignment:
- Top row height parity (sidebar/content)
- Nav state contrast
- Gutter consistency
- If a new global pattern is introduced, update this file in the same change