11 — Design System Mapping (CRM Module)
- 1. Status color semantics (single source)
- 2. Source icons & typography
- 3. Shared components → module mapping
- 4. Spacing & density
- 5. Empty & error states (copy)
- 6. Accessibility tokens
- 7. Motion tokens (per 00-shared/08)
- 8. Copy & i18n
Maps CRM UI to the shared design system (00-shared/04_Design_System_Mapping.md, tokens in 00-shared/02_Design_Tokens.md — proposed defaults until designer sign-off). Defines status → semantic-color rules, type scale usage, and shared component substitutions.
1. Status color semantics (single source)
Lead statuses (lead.schema.ts:7-13):
| Status | Role color | Container | Token intent |
|---|---|---|---|
| new | onSecondaryContainer | secondaryContainer | neutral/awaiting |
| contacted | onPrimaryContainer | primaryContainer | in-progress |
| qualified | onTertiaryContainer | tertiaryContainer | warm/positive |
| converted | onSuccessContainer | successContainer | terminal-success |
| closed | onSurfaceVariant | surfaceVariant | terminal-muted |
Admission statuses (admission.schema.ts:7-17): open states use neutral
secondary/primary/tertiary containers; approved/converted → success;
rejected → error container; waitlisted → surfaceVariant.
Campaign statuses (campaign.schema.ts:7-12): active → success-tinted border;
draft/paused/completed → surface variants with icon.
Rule: never color-only — every badge has icon + label (00-shared/09:76).
2. Source icons & typography
- Source icons per 07 §2 (material symbols, 20 dp default).
- Typography: list rows →
titleMedium(name) /bodySmall(meta); detail headers →headlineSmall; stat cards →headlineMedium(number) /labelLarge(caption); timeline →bodyMedium+labelSmalltimestamps.
3. Shared components → module mapping
| Shared (00-shared/03) | Module usage |
|---|---|
AppCard | pipeline/placement/documents/interview/notes cards (S2/S6) |
AppListTile | leads/admissions rows (wrapped in module tiles 07 §3,7) |
AppChips | filter rows (07 §13), panel/mode chips, source chips |
AppBadge | status badges (07 §1,6) |
AppAvatar | identity (40/56 dp), initials from name |
AppTimeline | follow-up timeline (S2), workflow timeline (S6, read-only) |
AppDialog | Convert (S4), Decision (S9) |
AppBottomSheet | forms (S3, follow-up, document, interview, campaign) |
AppDatePicker | scheduledAt, dates (datetime variant for follow-up/interview) |
AppSegmentedButton | decision choice, interview mode |
AppSkeleton / AppEmptyState / AppErrorState / AppOfflineBanner | all list/detail states |
AppFAB | create actions (gated by permission) |
AppTextField | all form fields |
4. Spacing & density
- List rows: 72 dp height (avatar 40 + two lines) — dense enough for a working queue; detail cards 16 dp padding.
- Filter rows: 8 dp above list; chips 8 dp gap.
- Bottom action bars: 8 dp safe-area padding; primary action right-aligned.
- Tablet: two-pane master-detail with 320 dp min detail width; sheets ≤ 560 dp.
5. Empty & error states (copy)
| State | Illustration | Copy |
|---|---|---|
| No leads | inbox | "No leads yet — create your first lead" |
| No leads in filter | filter_alt_off | "No leads in this status" + Clear filter |
| No admissions | description | "No applications yet" |
| No campaigns | campaign | "No campaigns yet" |
| Lead 404 | search_off | "Lead not found" |
| Offline | cloud_off | standard AppOfflineBanner + cached list |
| Permission | lock | "Ask your admin for CRM access" (when crm.read missing) |
6. Accessibility tokens
- Overdue text:
color.errorat ≥ 4.5:1 on card surface; paired with alert icon. - Focus ring: 2 dp outline in
color.primary; minimum touch targets 48 dp (chips 40 dp acceptable with padding). - Dark mode: all container pairs defined in tokens; goldens cover light/dark × 3 sizes for badges/timeline/stat cards (07 §Composition rules).
7. Motion tokens (per 00-shared/08)
Standard curves/easings; durations per 10 §6. Status chip transitions use the
m-fast emphasis variant; timeline stagger is the only module-specific choreography.
8. Copy & i18n
All strings keyed under crm.* (see 07 §Composition rules, 08 §1);
server business-4xx messages fall back via error-code → key mapping
(00-shared/11 §9). Locale: en first, org-locales on demand.