---
title: Design System Overview
tags: [design-system, ui, mui]
created: 2026-05-23
updated: 2026-05-30
---

# Design System Overview

> [!info] Current version: **Amaneh v2.7.0** (commit 56fc84e, 2026-05-29)
> Major full-app redesign. Key changes: warm-earth palette (Saffron / Pistachio / Persian Blue / Honey / Pomegranate), three-font stack (Source Serif 4 italic / IBM Plex Sans / IBM Plex Mono), SealMark SVG logo (saffron octagon + serif italic wordmark), CSS custom properties (`--amn-*`) in `global.css`, settings-drawer preset picker simplified to single Amaneh entry.

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 `sx` prop 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 `direction` overrides.
- **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>/` with `index.ts` + `component.tsx` + `classes.ts` + `types.ts` so 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

```mermaid
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-*.ts` exporting `useXxx`.
- Folder per component with `index.ts` barrel.
- Import order: **Styles → Side-effects → Types → External libs → MUI → Internal**.
- Forbidden: inline hex colors, `!important`, mixing `style={{}}` with `sx`.
- 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 `htmlFor` or wrapping `<label>`.
- Color contrast verified at WCAG AA (`4.5:1` body text, `3:1` large 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-rtl` when `direction === '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 `dayjs` with locale `fa`/`ar` loaded 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
