4.9 KiB
Product Visual Design System
This document defines shared visual standards for the Flutter application. Platform-specific interaction, capability, packaging, and release requirements belong in platform-rules/README.md.
Design principles
- Prefer semantic design tokens over raw color, spacing, or dimension values.
- Keep the interface neutral, restrained, and consistent across platforms.
- Adapt layout and interaction to the available space without creating unrelated visual systems.
- Preserve accessibility, text scaling, keyboard access, and visible focus states.
- Use Forui components as the foundation and add product wrappers only when they provide stable application-wide behavior.
Semantic color roles
Define light and dark values for these roles rather than using colors directly in feature widgets:
backgroundsurfacesurfaceElevatedtextPrimarytextSecondaryborderprimaryprimaryForegroundsuccesswarningdangerfocus
Starting palette values:
| Role | Value | Use |
|---|---|---|
| Primary | #2563EB |
Actions, links, and selection |
| Light background | #F8FAFC |
Light-mode page canvas |
| Dark surface | #111827 |
Dark-mode panels |
| Light border | #E2E8F0 |
Light-mode separators |
These values are starting points. Forui theme colors and component styles remain the source of truth for Forui widgets.
Spacing, dimensions, and shape
Use a 4 logical px base grid:
| Token | Value |
|---|---|
space1 |
4 |
space2 |
8 |
space3 |
12 |
space4 |
16 |
space6 |
24 |
space8 |
32 |
space12 |
48 |
| Small radius | 6 |
| Standard radius | 10 |
| Large radius | 14 |
| Standard border | 1 |
| Standard icon | 20 |
| Compact control height | 36 |
| Standard control height | 40 |
| Comfortable control height | 44–48 |
| Minimum touch target | 48 |
| Maximum reading width | 800 |
Do not use fixed-height text containers that clip enlarged system text. Use content constraints and intrinsic sizing where text may wrap or scale.
Typography
- Use a consistent system sans-serif font for UI text.
- Start body text at 14–16 logical px.
- Do not reduce secondary text below comfortable readability to fit more information.
- Use weight and spacing for hierarchy before adding more colors.
- Give editor text a separate configurable reading scale.
- Use monospace styling for code where appropriate.
- Test all important screens with enlarged system text and browser zoom.
Responsive visual policy
Use centralized layout classes based on LayoutBuilder constraints:
| Layout class | Width | Visual policy |
|---|---|---|
| Compact | < 600 |
One main pane and compact app bar or bottom navigation |
| Medium | 600–839 |
Navigation rail or drawer with optional secondary pane |
| Expanded | 840–1199 |
Persistent sidebar and main content |
| Wide | 1200+ |
Sidebar, main content, and optional secondary panel |
These classes describe shared layout behavior. Navigation input, system gestures, URLs, file access, and window behavior are defined by each platform rule document.
Component standards
| Component | Required behavior |
|---|---|
AppButton |
Primary, secondary, outline, ghost, and destructive variants |
AppIconButton |
Consistent sizing, tooltip, focus, and accessibility label |
AppTextField |
Label, helper text, validation, disabled, and error states |
AppSearchField |
Search input, clear action, loading, and empty states |
AppDialog |
Confirmation and form dialogs with keyboard dismissal rules |
AppSheet |
Mobile-friendly secondary actions and forms |
AppToast |
Brief success and non-blocking feedback |
AppEmptyState |
Human-readable message and optional next action |
AppErrorState |
Recoverable error message and retry action |
AppLoadingState |
Loading indicator and optional supporting text |
AppPageHeader |
Title, description, actions, and breadcrumbs when relevant |
AppSidebar |
Selected state, collapse behavior, and accessible navigation labels |
AppResponsiveContainer |
Content width and horizontal padding |
AppSplitView |
Main content and secondary panel on larger windows |
AppStatusBadge |
Semantic status labels, not decorative colors |
Every interactive component must define disabled, focus, hover where relevant, loading, and accessibility behavior. Every asynchronous feature must define loading, success, empty, and error states.
Accessibility baseline
- Provide accessible names for all interactive controls.
- Maintain visible focus indicators for keyboard users.
- Ensure color is not the only way to communicate status.
- Support system text scaling without clipping or loss of actions.
- Keep touch targets at least 48 logical px where practical.
- Test contrast, keyboard navigation, screen-reader labels, and reduced-motion preferences where supported.