Files
nick-doc/05 - Design System/Design System Overview.md
Siavash Sameni dceaf82934 audit: 2026-05-30 full-codebase audit — report, issues, docs, runbooks
Full-codebase-audit 2026-05-30 outputs:
- Audit report: 09 - Audits/Full Codebase Audit - 2026-05-30.md
- 81 issue files ISSUE-055..135 (decisions + 1 skipped no-brainer).
- Scanner docs from scratch (was zero): architecture, data model, API ref, payment
  flow, operations runbook + repo README.
- Doc-sync updates across API reference, data models, flows, design system.
- Secret Rotation Runbook (08 - Operations) for the exposed credentials.
- Reusable workflow guide (07 - Development) + .claude/workflows/full-codebase-audit.js.

Issues remain status:open intentionally — the code fixes are uncommitted-then-committed
working-tree changes per repo and aren't "resolved" until merged/deployed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 18:48:04 +04:00

7.6 KiB
Raw Blame History

title, tags, created, updated
title tags created updated
Design System Overview
design-system
ui
mui
2026-05-23 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

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