{"slug":"business/UI_DESIGN","title":"UI Design Guide — IntegrateWise Platform","section":"business","sectionLabel":"Business","status":"unclassified","type":"document","path":"business/UI_DESIGN.mdx","bytes":13985,"description":null,"updated":null,"source":"integratewise/Integratewise-docs-wiki","content":"\nDesign system, components, and patterns for building workbenches on top of IntegrateWise.\n\n---\n\n## Design Language\n\n**Forest · Paper · Combo**\n\n| Token  | Value     | Usage                                    |\n| ------ | --------- | ---------------------------------------- |\n| Canvas | `#1A1A1A` | Sidebar, nav foundation (dark earthy)    |\n| Paper  | `#F7F6F2` | Main content (warm white)                |\n| Accent | `#5B814F` | Forest green — highlights, active states |\n| Gold   | `#B8943F` | Insight, premium, wayfinding             |\n\n---\n\n## Typography\n\n| Font                 | Usage                          |\n| -------------------- | ------------------------------ |\n| **Bebas Neue**       | Display / hero headlines ONLY  |\n| **DM Serif Display** | h1–h3 (serif headings)         |\n| **Instrument Sans**  | h4–h6, body, UI (default sans) |\n| **IBM Plex Mono**    | Code, technical labels, data   |\n\n---\n\n## Design Tokens\n\n```css\n:root {\n  /* Surfaces */\n  --iw-surface-canvas: #f4f0e8;\n  --iw-surface-default: #ebe5d8;\n  --iw-surface-subtle: #e0d9c8;\n  --iw-surface-raised: #f9f6ef;\n  --iw-surface-inverse: #0c0c0c;\n\n  /* Text */\n  --iw-text-strong: #0c0c0c;\n  --iw-text-default: #0c0c0c;\n  --iw-text-muted: #5a5550;\n  --iw-text-faint: #8a8580;\n  --iw-text-inverse: #f4f0e8;\n  --iw-text-accent: #2d5a3d;\n  --iw-text-highlight: #b8943f;\n\n  /* Borders */\n  --iw-border-subtle: #d8d0c0;\n  --iw-border-default: #c4baa8;\n  --iw-border-strong: #a89a88;\n  --iw-border-accent: #b8943f;\n\n  /* Status */\n  --iw-status-success: #3d7a50;\n  --iw-status-warning: #b8943f;\n  --iw-status-danger: #8b2020;\n  --iw-status-info: #3d5247;\n}\n```\n\n---\n\n## Layout Structure\n\n### App Shell\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│  Sidebar (240px)  │           Main Content                  │\n├───────────────────┼─────────────────────────────────────────┤\n│  Logo             │  Header (breadcrumb, actions)           │\n│  Navigation       │  ┌─────────────────────────────────┐   │\n│  - Dashboard      │  │                                 │   │\n│  - Entities       │  │         Page Content             │   │\n│  - Integrations   │  │                                 │   │\n│  - Capabilities   │  │                                 │   │\n│  - Settings       │  └─────────────────────────────────┘   │\n│                   │  Footer (optional)                      │\n└───────────────────┴─────────────────────────────────────────┘\n```\n\n### Sidebar\n\n```tsx\n<Sidebar>\n  <Logo />\n  <Navigation>\n    <NavItem icon=\"dashboard\" label=\"Dashboard\" href=\"/app/work/dashboard\" />\n    <NavItem icon=\"entities\" label=\"Entities\" href=\"/app/work/entities\" />\n    <NavItem icon=\"integrations\" label=\"Integrations\" href=\"/app/work/integrations\" />\n    <NavItem icon=\"capabilities\" label=\"Capabilities\" href=\"/app/work/capabilities\" />\n    <NavItem icon=\"settings\" label=\"Settings\" href=\"/app/work/settings\" />\n  </Navigation>\n  <UserProfile />\n</Sidebar>\n```\n\n---\n\n## Core Components\n\n### 1. Entity Card\n\nDisplays a single entity (account, contact, deal, etc.).\n\n```tsx\n<EntityCard\n  entity={{\n    id: \"acc_001\",\n    name: \"Acme Corp\",\n    entity_type: \"account\",\n    status: \"active\",\n    metadata: { industry: \"Technology\", ARR: 120000 },\n  }}\n  onClick={() => navigate(`/app/work/entities/acc_001`)}\n/>\n```\n\n**Props:**\n\n```typescript\ninterface EntityCardProps {\n  entity: SpineEntity;\n  onClick?: () => void;\n  selected?: boolean;\n  showActions?: boolean;\n}\n```\n\n---\n\n### 2. Entity List\n\nDisplays a list of entities with filtering and sorting.\n\n```tsx\n<EntityList\n  entities={workbench.entities.deal}\n  filters={[\n    { key: \"status\", label: \"Status\", options: [\"open\", \"won\", \"lost\"] },\n    { key: \"source_tool\", label: \"Source\", options: [\"salesforce\", \"hubspot\"] },\n  ]}\n  sortBy=\"updated_at\"\n  sortOrder=\"desc\"\n  onEntityClick={(entity) => navigate(`/app/work/entities/${entity.id}`)}\n/>\n```\n\n---\n\n### 3. Connector Card\n\nDisplays a connector with status and connect button.\n\n```tsx\n<ConnectorCard\n  connector={{\n    id: \"salesforce\",\n    name: \"Salesforce\",\n    category: \"crm\",\n    status: \"available\",\n    capabilities: { auth: true, webhook: true },\n  }}\n  onConnect={() => connectConnector(\"salesforce\")}\n/>\n```\n\n---\n\n### 4. Capability Card\n\nDisplays a capability with execute button.\n\n```tsx\n<CapabilityCard\n  capability={{\n    name: \"salesforce:read-accounts\",\n    description: \"Read accounts from Salesforce\",\n    min_tier: \"free\",\n    channel: \"sync\",\n  }}\n  onExecute={(params) => executeCapability(\"salesforce:read-accounts\", params)}\n/>\n```\n\n---\n\n### 5. Signal Card\n\nDisplays a signal (insight, alert, notification).\n\n```tsx\n<SignalCard\n  signal={{\n    id: \"sig_001\",\n    severity: \"warning\",\n    title: \"Deal at risk\",\n    description: \"Acme Corp deal hasn't been updated in 14 days\",\n    timestamp: \"2026-07-21T10:30:00Z\",\n  }}\n  onDismiss={() => dismissSignal(\"sig_001\")}\n/>\n```\n\n---\n\n### 6. Readiness Meter\n\nDisplays department readiness score.\n\n```tsx\n<ReadinessMeter\n  readiness={{\n    overall_score: 0.85,\n    overall_state: \"live\",\n    buckets: [\n      { capability: \"accounts\", state: \"live\", score: 0.9 },\n      { capability: \"deals\", state: \"live\", score: 0.85 },\n    ],\n  }}\n/>\n```\n\n---\n\n### 7. Timeline\n\nDisplays activity timeline.\n\n```tsx\n<Timeline\n  events={[\n    { id: \"evt_001\", type: \"created\", title: \"Deal created\", timestamp: \"2026-07-21T10:00:00Z\" },\n    { id: \"evt_002\", type: \"updated\", title: \"Stage changed\", timestamp: \"2026-07-21T11:00:00Z\" },\n  ]}\n/>\n```\n\n---\n\n## Page Templates\n\n### Dashboard Page\n\n```tsx\nfunction DashboardPage() {\n  const { workbench, loading } = useWorkbench(token, tenantId, \"SALES\");\n\n  if (loading) return <Spinner />;\n\n  return (\n    <Page>\n      <Header>\n        <Title>Sales Dashboard</Title>\n        <Actions>\n          <Button onClick={refresh}>Refresh</Button>\n        </Actions>\n      </Header>\n\n      <Metrics>\n        <MetricCard label=\"Accounts\" value={workbench.entities.account.length} />\n        <MetricCard label=\"Deals\" value={workbench.entities.deal.length} />\n        <MetricCard label=\"People\" value={workbench.entities.person.length} />\n        <MetricCard label=\"Signals\" value={workbench.signals.length} />\n      </Metrics>\n\n      <ReadinessMeter readiness={workbench.readiness} />\n\n      <Grid>\n        <Section title=\"Recent Deals\">\n          <EntityList entities={workbench.entities.deal.slice(0, 5)} />\n        </Section>\n\n        <Section title=\"Signals\">\n          <SignalList signals={workbench.signals.slice(0, 5)} />\n        </Section>\n      </Grid>\n    </Page>\n  );\n}\n```\n\n---\n\n### Entities Page\n\n```tsx\nfunction EntitiesPage() {\n  const { workbench, loading } = useWorkbench(token, tenantId, \"SALES\");\n  const [entityType, setEntityType] = useState(\"deal\");\n\n  return (\n    <Page>\n      <Header>\n        <Title>Entities</Title>\n        \n      </Header>\n\n      <EntityList\n        entities={workbench.entities[entityType] || []}\n        filters={[...]}\n        sortBy=\"updated_at\"\n        onEntityClick={(entity) => navigate(`/app/work/entities/${entity.id}`)}\n      />\n    </Page>\n  );\n}\n```\n\n---\n\n### Integrations Page\n\n```tsx\nfunction IntegrationsPage() {\n  const { connectors, loading, connect } = useConnectors(token, tenantId);\n  const { integrations } = useIntegrations(token, tenantId);\n\n  return (\n    <Page>\n      <Header>\n        <Title>Integrations</Title>\n      </Header>\n\n      <Section title=\"Connected\">\n        {integrations.map((integration) => (\n          <ConnectorCard\n            key={integration.provider}\n            connector={integration}\n            status=\"connected\"\n            onDisconnect={() => disconnect(integration.provider)}\n          />\n        ))}\n      </Section>\n\n      <Section title=\"Available\">\n        {connectors\n          .filter((c) => c.status === \"available\")\n          .map((connector) => (\n            <ConnectorCard\n              key={connector.id}\n              connector={connector}\n              onConnect={() => connect(connector.id)}\n            />\n          ))}\n      </Section>\n    </Page>\n  );\n}\n```\n\n---\n\n### Capabilities Page\n\n```tsx\nfunction CapabilitiesPage() {\n  const { capabilities, loading, execute } = useCapabilities(token, tenantId);\n\n  return (\n    <Page>\n      <Header>\n        <Title>Capabilities</Title>\n      </Header>\n\n      <Grid>\n        {capabilities.map((capability) => (\n          <CapabilityCard\n            key={capability.name}\n            capability={capability}\n            onExecute={(params) => execute(capability.name, params)}\n          />\n        ))}\n      </Grid>\n    </Page>\n  );\n}\n```\n\n---\n\n### Entity Detail Page\n\n```tsx\nfunction EntityDetailPage({ entityId }) {\n  const { workbench } = useWorkbench(token, tenantId, \"SALES\");\n  const entity = findEntity(workbench, entityId);\n\n  return (\n    <Page>\n      <Header>\n        <BackButton onClick={() => navigate(-1)} />\n        <Title>{entity.name}</Title>\n        <Actions>\n          <Button onClick={() => editEntity(entity)}>Edit</Button>\n          <Button onClick={() => deleteEntity(entity)} variant=\"danger\">\n            Delete\n          </Button>\n        </Actions>\n      </Header>\n\n      <Grid>\n        <Section title=\"Details\">\n          <EntityDetails entity={entity} />\n        </Section>\n\n        <Section title=\"Relationships\">\n          <RelationshipList\n            relationships={workbench.relationships.filter(\n              (r) => r.source === entity.id || r.target === entity.id\n            )}\n          />\n        </Section>\n\n        <Section title=\"Timeline\">\n          <Timeline events={workbench.timeline.filter((e) => e.entity_id === entity.id)} />\n        </Section>\n\n        <Section title=\"Signals\">\n          <SignalList signals={workbench.signals.filter((s) => s.entity_id === entity.id)} />\n        </Section>\n      </Grid>\n    </Page>\n  );\n}\n```\n\n---\n\n## Responsive Design\n\n### Breakpoints\n\n```css\n/* Mobile */\n@media (max-width: 640px) {\n  .sidebar {\n    display: none;\n  }\n  .main-content {\n    padding: 16px;\n  }\n}\n\n/* Tablet */\n@media (min-width: 641px) and (max-width: 1024px) {\n  .sidebar {\n    width: 64px;\n  }\n  .sidebar-label {\n    display: none;\n  }\n}\n\n/* Desktop */\n@media (min-width: 1025px) {\n  .sidebar {\n    width: 240px;\n  }\n  .main-content {\n    padding: 24px;\n  }\n}\n```\n\n---\n\n## Dark Mode\n\n```css\n@media (prefers-color-scheme: dark) {\n  :root {\n    --iw-surface-canvas: #1a1a1a;\n    --iw-surface-default: #2a2a2a;\n    --iw-surface-subtle: #3a3a3a;\n    --iw-surface-raised: #4a4a4a;\n    --iw-surface-inverse: #f4f0e8;\n\n    --iw-text-strong: #f4f0e8;\n    --iw-text-default: #e0e0e0;\n    --iw-text-muted: #a0a0a0;\n    --iw-text-faint: #707070;\n    --iw-text-inverse: #1a1a1a;\n\n    --iw-border-subtle: #3a3a3a;\n    --iw-border-default: #4a4a4a;\n    --iw-border-strong: #5a5a5a;\n  }\n}\n```\n\n---\n\n## Accessibility\n\n### Color Contrast\n\n| Token           | Light Mode             | Dark Mode              | Ratio  |\n| --------------- | ---------------------- | ---------------------- | ------ |\n| Text on Paper   | `#0c0c0c` on `#f4f0e8` | `#f4f0e8` on `#1a1a1a` | 15.4:1 |\n| Text on Canvas  | `#f4f0e8` on `#1a1a1a` | `#0c0c0c` on `#f4f0e8` | 15.4:1 |\n| Accent on Paper | `#2d5a3d` on `#f4f0e8` | `#3d7a50` on `#1a1a1a` | 7.2:1  |\n\n### Keyboard Navigation\n\n- All interactive elements must be focusable\n- Focus order follows visual layout\n- Skip links for main content\n\n### ARIA Labels\n\n```tsx\n<button aria-label=\"Connect Salesforce\" onClick={connect}>\n  Connect\n</button>\n\n<nav aria-label=\"Main navigation\">\n  <a href=\"/dashboard\" aria-current=\"page\">Dashboard</a>\n</nav>\n```\n\n---\n\n## Component Library\n\n### Available Components\n\n| Component | Location                      | Description                         |\n| --------- | ----------------------------- | ----------------------------------- |\n| `Button`  | `@/components/common/button`  | Primary, secondary, danger variants |\n| `Card`    | `@/components/common/card`    | Container with header, body, footer |\n| `Input`   | `@/components/common/input`   | Text, number, search inputs         |\n| `Select`  | `@/components/common/select`  | Dropdown selection                  |\n| `Modal`   | `@/components/common/modal`   | Dialog overlay                      |\n| `Toast`   | `@/components/common/toast`   | Notification messages               |\n| `Spinner` | `@/components/common/spinner` | Loading indicator                   |\n| `Tabs`    | `@/components/common/tabs`    | Tab navigation                      |\n| `Badge`   | `@/components/common/badge`   | Status indicators                   |\n| `Avatar`  | `@/components/common/avatar`  | User/entity avatars                 |\n\n### Import Pattern\n\n```tsx\n```\n\n---\n\n## Resources\n\n- **Design Tokens:** `apps/web/src/styles/design-tokens.css`\n- **Components:** `apps/web/src/components/`\n- **API Reference:** `docs/api/PLATFORM_API.md`\n- **Service Topology:** `docs/api/SERVICE_TOPOLOGY.md`\n"}