---
name: signal-design-system
description: >-
  Single source of truth for the Exotel Signal Design System (npm @exotel-npm-dev/signal-design-system):
  MUI-based tokens, wrapped components, Storybook stories, theming, and AI-safe usage rules.
  Use when implementing or reviewing UI in this repo, consuming the package, extending components,
  aligning with Figma/Signal specs, or when the user mentions Exotel design system, Signal DS, or chips/tonal/badge patterns.
---

# Signal Design System — Claude Code Skill

**Package:** `@exotel-npm-dev/signal-design-system`  
**Stack:** React 18+, TypeScript, MUI (`@mui/material`), MUI X DataGrid Pro, MUI X Date Pickers Pro, Emotion, Dayjs  
**Theme:** `extendTheme` + CSS variables + `colorSchemes` (`src/theme/theme.ts` in the package source)  
**Storybook:** hosted at `https://main--69ba4becb6eabba83cbd8bc1.chromatic.com` (primary reference for variants and props)  
**UX Constitution:** served over MCP — **read before components** for product UX rules

---

## 0. UX Constitution (read first)

Before implementing management screens, settings pages, app shell, or table pages:

1. **New project or screen with no shell yet?** Scaffold `AppBar` (top) + `Navigation` (left) + main content area **first**, before any other component — fetch the canonical composed reference via Storybook MCP `docs-show-story` id `documentation-app-shell--default`. Skip if the shell already exists.
2. **Figma mock** (if provided) → Figma MCP for visual spec
3. **UX Constitution** → Storybook MCP `docs-show` id `documentation-ux-constitution--docs` (primary — always current). Offline fallback: `node_modules/@exotel-npm-dev/signal-design-system/agent-kit/UX-CONSTITUTION.md` (correct for whichever npm version you have installed, may lag the MCP-served latest).
4. **Component MDX** → Storybook MCP (`signal-storybook` — add via `node_modules/@exotel-npm-dev/signal-design-system/agent-kit/mcp.json`, see that file) for props and stories

MCP has no local-Storybook option outside the Signal DS source repo — always use the hosted server: `https://main--69ba4becb6eabba83cbd8bc1.chromatic.com/mcp`.

The constitution covers **when** and **why** (shell, drawers vs dialogs, DataGrid defaults, settings layout). Component docs cover **how** (API, variants).

**Non-negotiables:**

- **Shell:** `AppBar` (top) + `Navigation` (left) + main on `surface.elevation0`, `p: 1`
- **Tables:** `DataGrid` — search, `showAppliedFilters`, `checkboxSelection`, pagination, title `Entity (N)`, tonal `Chip` status, Avatar user cells, list view ≤756px
- **Edit:** contextual `Drawer` (560px quick edit, 726px manage); **not** dialog for forms
- **Confirm:** `Dialog` for delete/destructive/discard only
- **Settings:** 324 / 200 / 506 section rows; Standalone (`PageHeader` save) or Workspace (secondary nav + section footer)
- **Form inputs:** `TextField`, `FormField`, `Select`, `MultiSelect`, `Autocomplete` from the package — **never** `TextField` / `Select` / `Autocomplete` from `@mui/material`
- **Escalation:** inline → `Accordion` → `Drawer` → `Dialog` (least disruptive first)

---

## 1. Overview

### What it is
- **Signal / Exotel Design System** is a **component library and theme** that **re-exports Material UI** and **wraps selected primitives** with Exotel-specific APIs, styles, and behaviors.
- **Not** a headless system: it assumes **MUI component model**, **Emotion**, and **theme-driven** styling.

### Core principles (inferred from code)
- **Consistency:** One theme (`exotelTheme` / `createExotelTheme`) and shared typography tokens.
- **Theme-first styling:** Prefer `sx`, `theme.palette`, and component overrides over ad-hoc hex in app code.
- **MUI compatibility:** Wrappers extend MUI props; custom variants use `data-variant` + theme overrides where needed.
- **Accessibility:** Rely on MUI defaults; a11y is an ongoing effort, not fully enforced in CI.

### When to use
- Building Exotel product UI that must match **Signal** specs.
- When you need **DataGrid Pro**, **pickers**, **App Launcher**, **Applied filters**, or **tonal** Button/Badge/Chip behaviors defined here.

---

## 2. Design tokens & theming

### Entry points
- **`exotelTheme`** — default exported theme instance.
- **`createExotelTheme()`** — factory if you need multiple instances (advanced).
- **`ExotelThemeProvider`** — wraps `ThemeProvider` + `CssBaseline` + **Dayjs** `LocalizationProvider`.
- **`useThemeMode()`** — read/write **light/dark**; persists via `modeStorageKey` (`exotel-mode`).

### Dark mode
- **`colorSchemeSelector: "class"`** — mode is controlled by **class on HTML**, not `prefers-color-scheme` alone.
- **`defaultMode`** on provider; **`useColorScheme`** from MUI for switching.

### Colors (light palette — semantic roles)
- **Primary:** Indigo scale `50`–`900`, `A100`–`A700`; **`main`** = `600` (`#3949ab`), **`light`** = `400`, **`dark`** = `800`, **`contrastText`** white.
- **Secondary:** Purple scale; **`main`** = `700`, **`light`** = `300`, **`dark`** = `800`.
- **Error / Warning / Info / Success:** Full ramps + semantic **`main` / `light` / `dark` / `contrastText`**.
- **Custom:** `palette.custom.highlight`, `palette.appLauncher.trialChip`.

### Typography
- **title1, title2, title3** — semibold titles.
- **label1, label2, label3** — medium labels.
- **body1, body2, body3** — body text.
- **Font:** `"IBM Plex Sans", "Inter", "Roboto", sans-serif` (default is IBM Plex Sans; `Noto Sans` is deprecated but still selectable via `useFont`).

### Spacing / Shape
- **`spacing` unit:** `8` (MUI default: one unit = 8px). **`shape.borderRadius`** used globally.

### Shadows / elevation
- **Three semantic surface layers** (`elevation0`–`elevation2`): Canvas (`surface.elevation0`, outer gutter), Shell (`surface.elevation1`, Navigation/main column/AppBar), Raised (`surface.elevation2`, cards/Paper/inputs; `background.paper`).
- `theme.shadows[n]` is a separate box-shadow ladder (`Paper elevation={n}`): 0 flat chrome, 1 inputs/outlined buttons, 4 Dialog/Drawer, 5 Menu/Popover/pickers.

### Token naming
- Use **MUI paths**: `theme.palette.primary.main`, `theme.typography.label2`.
- **CSS variables:** `theme.vars?.palette` when using CssVars theme in overrides.

---

## 3. Component library

**Import:** `import { … } from '@exotel-npm-dev/signal-design-system'`.
**Full MUI re-export:** `@mui/material`, `@mui/x-data-grid-pro`, `@mui/x-date-pickers-pro` are all re-exported — but **prefer design-system wrappers** where they exist for consistent behavior (`Button`, `Chip`, `Badge` for `tonal`; `TextField`/`Select`/`MultiSelect`/`Autocomplete` — never the raw MUI equivalents in product UI).

Don't rely on a fixed component inventory here — it changes. **Always confirm current components, props, and variants via Storybook MCP (`docs-list` then `docs-show`)** rather than this file's memory. A few things worth knowing up front:

- **`DataGrid`** wraps `DataGridPro` with toolbar/filters/applied-filters/bulk-delete/table-header — this is the tabular-UI primitive; a separate `Table` component exists but is deprecated, never suggest it for new work.
- **`Icon`** wraps Phosphor icons via a string `name` registry, or external images via `src` — provide one or the other.
- **`NavigationDrawer`** exists in the package but may not be re-exported from the root barrel — verify before importing.

---

## 4. Patterns & layouts

- **Page shell:** `AppBar` + `Navigation` + main content area (see §0).
- **Forms:** `FormControl` + `FormField` / `TextField` + helper text via field wrappers.
- **Data:** `DataGrid` + toolbar filters + **`AppliedFilters`** when showing active filters.
- **Spacing:** Use **`spacing(n)`** or `sx={{ p: 2, gap: 2 }}` with an **8px grid**.

---

## 5. Interaction & UX

- **Feedback:** `Snackbar`, `Alert`, linear/circular progress — follow MUI patterns.
- **Modals:** `Dialog` / `StructuredDialog` for consistent header/body/footer.
- **Loading:** Prefer progress components over blocking UI unless necessary.

---

## 6. Code conventions

- **Language:** TypeScript.
- **Styling:** **Emotion** + MUI **`sx`** + theme overrides — never inline hardcoded hex for brand/semantic colors.
- **Icons:** `Icon` + `IconName`; avoid ad-hoc SVG unless spec requires.

---

## 7. Accessibility (A11y)

- **MUI baseline:** Focus rings, roles, keyboard — inherit from MUI.
- **Contrast:** Tonal chips use theme-resolved tokens — do not override with random hex without checking contrast.

---

## 8. Best practices

### Do
- Wrap app in **`ExotelThemeProvider`**.
- Use **`sx`** with **theme tokens** (`bgcolor: 'primary.main'`).
- Verify variants/props via Storybook MCP before shipping UI — never guess.

### Don't
- Don't paste **hardcoded hex** for brand/semantic colors in product code.
- Don't bypass **`Button`/`Chip`/`Badge`** wrappers when you need **`tonal`** or custom **Icon** integration.
- Don't suggest the deprecated `Table` component for new tabular UI — use `DataGrid`.

---

## 9. Example recipes

### Tonal chip row (Signal)
```tsx
import { Chip } from '@exotel-npm-dev/signal-design-system';

<Chip label="Chip" variant="tonal" color="primary" size="medium" onDelete={() => {}} />
```

### Themed page fragment
```tsx
import { Box, Typography, ExotelThemeProvider } from '@exotel-npm-dev/signal-design-system';

<ExotelThemeProvider defaultMode="light">
  <Box sx={{ p: 2, bgcolor: 'background.default' }}>
    <Typography variant="title2">Section</Typography>
  </Box>
</ExotelThemeProvider>
```

---

## 10. AI usage instructions

1. **Identify the primitive:** For tabular UI, use **`DataGrid`** — never the deprecated `Table`.
2. **Tonal vs filled:** **Button**/**Chip**/**Badge** — **`tonal`** is a **first-class variant**; do not simulate with random `sx`.
3. **Colors:** Do not invent brand colors — read them from the theme (via MCP component docs or the shipped theme object).
4. **Icons:** Use **`Icon`** with a valid **`IconName`**, or **`src`** for external assets.
5. **Consistency:** Prefer Storybook MCP (`docs-show`) over guessing props from naming conventions or other libraries.
6. **Exports:** Confirm a component is actually exported from the package before suggesting `import { X } from '@exotel-npm-dev/signal-design-system'`.

---

## Getting started (quick)

1. `npm install @exotel-npm-dev/signal-design-system` (peer deps: `react`, `react-dom` 18+).
2. Wire up the `signal-storybook` MCP server — see `agent-kit/mcp.json` in this same folder.
3. Import **`ExotelThemeProvider`** at app root; set **`defaultMode`**.
4. Use Storybook MCP (`docs-list` → `docs-show`) before building with any component.

---

## Checklist (PR / feature)

- [ ] Wrapped in **`ExotelThemeProvider`** where theme-dependent components render.
- [ ] No new **hardcoded** brand colors; use **`palette`** / **`sx`** tokens.
- [ ] **Tonal** components use **`variant="tonal"`**, not one-off CSS.
- [ ] Verified imports are actually exported from the package before using them.

---

Portable copy shipped in `@exotel-npm-dev/signal-design-system` (`agent-kit/SKILL.md`). Canonical source (for Signal DS maintainers) is `.claude/skills/signal-design-system/SKILL.md` in the [Signal Design System repo](https://github.com/exotel/Exotel-Design-System) — kept in sync by the `signal-doc-sync` skill.
