Build
Patterns
Repeatable compositions for navigation, forms, data, feedback, and conversational work—built from the same primitives.
Choose the smallest honest shell
Navigation density follows product structure, not brand preference.
| Product shape | Composition | Use it when |
|---|---|---|
| Focused landing page | TopBar + PageCanvas | One route or one primary action carries the experience. |
| Multi-route product | AppShell + NavigationRail | People switch between durable work areas. |
| Dense editor or monitor | AppShell + full PageCanvas | The workspace needs maximum width and stable tools. |
| Narrow mobile journey | AppShell + BottomBar or drawer | Primary destinations must remain thumb-reachable. |
AnimatedRailStage wraps only route content. Key it by the selected destination, preserve the rail, and let reduced-motion preferences remove the translation.
Forms disclose effort progressively
Labels and recovery stay close to the decision they belong to.
- Start with a persistent label; placeholder text is an example, never the only name.
- Add a short description when it changes how the input should be interpreted.
- Validate on a meaningful boundary. Do not punish incomplete typing.
- Put field errors beside the field and submission failures in an
InlineAlert. - Preserve entered values after a recoverable failure.
Data surfaces preserve orientation
Density is useful only when people can recover where they are.
Use DataTable for comparable records, a semantic list for actions or narratives, and a grid only for genuinely visual objects. Keep column labels visible, align numeric values to the end, and provide an explicit empty state. Horizontal overflow is preferable to silently dropping fields.
Feedback has a time horizon
Match the component to how long the condition matters.
- Immediate: pending state on the initiating control.
- Short-lived: status region or polite announcement near the work.
- Persistent and local:
InlineAlertin the affected surface. - Blocking: modal only when proceeding would lose data, authority, or safety.
- No content:
EmptyStatethat names the state and the next useful action.
Conversation is still product UI
Chat surfaces inherit the same hierarchy and operational feedback as the rest of the app.
Messages distinguish speaker through structure and labeling, not color alone. Tool activity, attachments, citations, and recoverable errors remain separate semantic blocks. The composer keeps its label, keyboard behavior, send state, and attachment state explicit at every viewport.