7.1 KiB
title, tags, created
| title | tags | created | |||
|---|---|---|---|---|---|
| Design System Overview |
|
2026-05-23 |
Design System Overview
The frontend design system is built on Material-UI v7 with project-specific tokens, an LTR + RTL-aware emotion cache, and a user-controllable settings drawer (mode, layout, color preset, font, direction).
[!info] All design decisions documented here are enforced by the cursor rules at
backend/.cursor/rules/ui-development-standards.mdc. When in doubt, that file is the authoritative source.
1. Philosophy
- Material first, brand second. Use MUI components and the
sxprop with array syntax for responsive overrides. Do NOT subclass primitives unless absolutely necessary. - Tokens over magic numbers. All colors, spacings, radii, and shadows come from the theme — never hard-code hex values or pixel offsets.
- RTL-first. Persian and Arabic are first-class. Layouts must mirror correctly without manual
directionoverrides. - Accessibility-by-default. WCAG AA contrast (4.5:1), semantic HTML, keyboard navigation, ARIA labels on icon-only buttons.
- One component, one folder. Each component lives in
components/<name>/withindex.ts+component.tsx+classes.ts+types.tsso it can be refactored without grep-and-replace pain. - Compose, don't inherit. Sections compose components, components compose primitives, primitives wrap MUI.
2. Component layering
flowchart TB
P[Pages — src/app/]
S[Sections — src/sections/]
C[Components — src/components/]
L[Layouts — src/layouts/]
H[Hooks — src/hooks/]
T[Theme — src/theme/]
M[MUI v7]
P --> S
P --> L
S --> C
C --> M
L --> C
L --> M
C --> H
S --> H
M --> T
- Pages are thin — they mount a section and pass URL params.
- Sections are page-specific compositions of components + hooks + queries.
- Components are reusable, free of business logic.
- Layouts wrap pages with sidebar / topbar / auth scaffolding.
3. Token system
The theme exposes these token groups (see Theme Configuration for exact values):
| Group | Examples | Used as |
|---|---|---|
| Palette | primary.main, error.dark, grey.500, background.paper |
sx={{ color: 'primary.main' }} |
| Typography | h1-h6, subtitle1/2, body1/2, caption, overline, button |
<Typography variant="h2"> |
| Spacing | unit = 8 px; use multiples: spacing(1) = 8, spacing(2) = 16, … |
sx={{ p: 2, mt: 3 }} |
| Shape | borderRadius = 8 (default), 12 for cards |
sx={{ borderRadius: 1 }} |
| Shadows | shadows[1]–shadows[24] + custom customShadows |
sx={{ boxShadow: 1 }} |
| Breakpoints | xs/sm/md/lg/xl = 0/600/900/1200/1536 |
sx={{ flexDirection: { xs: 'column', md: 'row' } }} |
| Z-index | named layers: appBar, drawer, modal, snackbar, tooltip |
sx={{ zIndex: 'modal' }} |
The unit of spacing is 8 px. Never use padding: '14px' — use sx={{ p: 1.75 }} if you really need it (or, better, fix the value to a multiple).
4. Modes
The app supports three independent user-controllable axes:
| Axis | Values | Persistence |
|---|---|---|
| Mode | light · dark · system |
localStorage.settings.mode |
| Contrast | default · bold |
localStorage.settings.contrast |
| Layout | vertical · mini · horizontal |
localStorage.settings.layout |
| Direction | ltr · rtl |
localStorage.settings.direction (auto-set from locale) |
| Color preset | one of N curated palettes | localStorage.settings.colorPresets |
| Font family | per theme defaults or overridden | localStorage.settings.fontFamily |
Toggled from the Settings Drawer (src/settings/drawer/). See Settings & Theming.
5. Folder structure
frontend/src/
├── theme/
│ ├── index.ts # createTheme + provider wiring
│ ├── options/
│ │ ├── palette.ts # Palette tokens (light + dark)
│ │ ├── typography.ts # Type scale & families
│ │ ├── shadows.ts # Elevation shadows
│ │ ├── custom-shadows.ts # Brand-specific glow/elevation
│ │ ├── overrides/ # MUI component overrides
│ │ └── …
│ └── styles/ # Global CSS resets, scrollbar
├── settings/
│ ├── context/ # SettingsContext provider
│ └── drawer/ # The visible drawer UI
├── components/ # ~50 reusable components (see below)
└── layouts/
├── auth-centered/
├── auth-split/
├── dashboard/ # sidebar + topbar
└── main/ # public marketing-style
6. Naming & code conventions (recap from cursor rules)
- File names: kebab-case (
custom-data-grid.tsx). - Component names: PascalCase (
CustomDataGrid). - Hook names:
use-*.tsexportinguseXxx. - Folder per component with
index.tsbarrel. - Import order: Styles → Side-effects → Types → External libs → MUI → Internal.
- Forbidden: inline hex colors,
!important, mixingstyle={{}}withsx. - Icons: Iconify only (
eva:*,solar:*prefixes preferred).
7. Accessibility checklist
- All interactive elements reachable with
Tab. - Focus visible (don't override default outline without replacement).
- Icon-only buttons have
aria-label. - Form fields linked to labels via
htmlForor wrapping<label>. - Color contrast verified at WCAG AA (
4.5:1body text,3:1large text). - Live regions for snackbars (
aria-live="polite"). - Skip-to-content link before the navbar.
8. RTL support
- The MUI emotion cache toggles
stylis-plugin-rtlwhendirection === 'rtl'. - DataGrid honors a custom Persian locale at
locales/custom-fa-data-grid-locale.ts. - Icon orientation (chevrons, arrows) is mirrored automatically by stylis-plugin-rtl.
- Date pickers use
dayjswith localefa/arloaded dynamically.
See Internationalization & RTL for the full setup.
9. Where to add new visuals
| Need | Add it to |
|---|---|
| New brand color | theme/options/palette.ts (light + dark) |
| New text variant | theme/options/typography.ts |
| MUI component override (default props, root sx) | theme/options/overrides/<Component>.ts |
| Reusable widget | src/components/<kebab-case-name>/ |
| Page-specific composition | src/sections/<feature>/<thing>.tsx |
| Layout variant | src/layouts/<name>/ |
| New language | src/locales/langs/<code>/ + register in locales-config.ts |
10. Related
- Theme Configuration — exact MUI theme structure
- Typography — type scale & font loading
- Colors — palette tokens & contrast
- Components — inventory of reusable components
- Layouts — layout patterns
- Internationalization & RTL — i18n + bidi
- Iconography — Iconify usage rules
- Settings & Theming — drawer-driven user prefs
- Frontend Architecture — where this fits in the broader system
- Coding Standards — full cursor-rules reference