Comprehensive reference for building UIs with the Coherence Design System (Microsoft's internal design system for C+AI). Use when building UI with Coherence components (`cui-*` web components from `@charm-ux/cui`), or when the user asks about Coherence component usage, guidance, accessibility, or API. Also use when composing pages with Coherence templates (dashboard, form, settings), task flows (bulk edit, inline edit, favorites, save presets), or following Coherence UX guides (accessibility, AI patterns, data visualization, writing for UI). Also use when the user asks about Coherence design tokens, theming, colors, spacing, typography, shadows, CSS custom properties, or any `--color-*`, `--spacing-*`, `--font-*` variable. Triggers: any mention of Coherence, `cui-` components, `@charm-ux/cui`, design tokens, theme CSS, or building UI that should follow the Coherence design system.
Build UIs using the Coherence Design System — Microsoft's component library for C+AI products.
Default output: React. Always generate React components using the
@charm-ux/cui/reactwrappers unless the user explicitly asks for plain HTML web components or another format.
@charm-ux/cuiimport { CuiButton } from '@charm-ux/cui/react'import '@charm-ux/cui/dist/components/<name>/index.js'cui- (e.g. cui-button, cui-dialog)Cui + PascalCase component name (e.g. CuiButton, CuiCard, CuiDialog)Three complementary sources provide a complete picture of every component and the design system. Consult the relevant source(s) for the task at hand.
Fetch this URL to get the machine-readable API for any component. It follows the Custom Elements Manifest schema. For each component it provides:
How to look up a component: Find the module whose path matches src/components/<slug>/<slug>.ts, then read its declarations array for the entry with customElement: true.
Example: to look up cui-button, find the module with path: "src/components/button/button.ts" → its declaration is CuiButton.
Fetch this URL when answering questions about design tokens, theming, colors, spacing, typography, shadows, borders, animation timing, or component-level CSS variables. This auto-generated CSS file defines all CSS custom properties on :root / :host and is the single source of truth for token names and values.
What it contains:
| Category | Token prefix / examples | Description |
|---|---|---|
| Color palette | --color-brand-{10–160}, --color-neutral-{0–100}, --color-danger-*, --color-success-*, --color-warning-*, --color-caution-* | Raw color scale with -alt contrast pairs |
| Semantic colors | --neutral-foreground{1–4}, --neutral-background{1–6}, --brand-foreground*, --brand-background*, --subtle-background*, --compound-brand-* | Role-based color tokens with hover/pressed/selected/disabled states |
| Status colors | --danger-background*, --danger-foreground*, --success-*, --warning-*, --severe-* | Semantic status indicators |
| Stroke / border colors | --neutral-stroke{1–3}, --neutral-stroke-accessible*, --neutral-stroke-subtle, --brand-stroke*, --compound-brand-stroke*, --stroke-focus{1,2}, --transparent-stroke* | Semantic border/stroke tokens |
| Overlay / scrollbar | --background-overlay, --scrollbar-overlay | Modal overlay and scrollbar colors |
| Typography | --font-family-base, --font-family-numeric, --font-family-monospace, --font-size-base{100–600}, --font-size-hero{700–1000}, --font-weight-*, --line-height-* | Type scale and font stacks |
| Spacing | --spacing-none through --spacing-xxxl | Layout spacing scale (0–32 px) |
| Borders | --border-radius-{none,sm,md,lg,xl,circular}, --border-width-{none,thin,thick,thicker,thickest} | Border radius and width tokens |
| Default border | --default-border, --default-border-size, --default-border-style, --default-border-color | Shorthand border defaults used by many components |
| Shadows | --shadow-{0,2,4,8,16,28,64}, --drop-shadow-* | Elevation / shadow tokens |
| Animation | --duration-{ultra-fast…ultra-slow}, --timing-function-{accelerate,decelerate,easy-ease,linear}-* | Motion timing tokens |
| Focus | --focus-outline, --focus-outline-color, --focus-outline-offset, --focus-outline-size, --focus-outline-style | Global focus ring styling |
| Component defaults | --button-*, --form-control-*, --link-*, --heading-*, --body-* | Pre-composed component-level variables that reference the above tokens |
How the theme CSS relates to component reference docs:
The theme CSS defines global defaults for ~578 tokens. Of those, about 51 are also documented in component reference files (mainly --button-*, --form-control-*, and --default-border). Component reference docs additionally list component-specific CSS custom properties (e.g. --accordion-item-*, --card-*, --dialog-*, --checkbox-*) that are not in the theme CSS — those are defined inside individual component stylesheets and can still be overridden. Use both sources together: the theme CSS for token values/names and the component refs for per-component override hooks.
When to fetch: Any time the user asks about available colors, spacing values, font sizes, shadow levels, how to theme a component, what CSS variables exist, or when you need the exact token name/value for a style.
The reference docs below contain information the manifest does not have:
When the user asks to build UI or use a Coherence component:
.tsx) using @charm-ux/cui/react wrappers. Only output plain HTML web components (<cui-*>) if the user explicitly requests it.When composing a full page or layout, also read the relevant template and task flow references. For Azure portal pages specifically, start with the composition patterns in references/patterns/ — especially the Resource Page Shell — to avoid rebuilding the standard Azure chrome from scratch.
Reference files contain design guidance and code examples only — not API details. Always fetch the manifest for API data.
Components with a reference file (66 — guidance available):
Components in the manifest only (API-only — no design guidance doc yet):
| Component | Tag | Manifest path |
|---|---|---|
| Button Group Overflow | cui-button-group-overflow | src/components/button-group-overflow/button-group-overflow.ts |
| Menu Group | cui-menu-group | src/components/menu-group/menu-group.ts |
| Push Pane | cui-push-pane | src/components/push-pane/push-pane.ts |
| Teaching Popover | cui-teaching-popover | src/components/teaching-popover/teaching-popover.ts |
| Tree Item | cui-tree-item | src/components/tree-item/tree-item.ts |
Page-level layout patterns. Read before composing full pages.
| Template | Reference |
|---|---|
| Dashboard | references/templates/dashboard.md |
| Form | references/templates/form.md |
| Settings | references/templates/settings.md |
Multi-step interaction patterns. Read when implementing these specific user flows.
| Task Flow | Reference |
|---|---|
| Bulk Edit | references/task-flows/bulk-edit.md |
| Create an Item | references/task-flows/create-an-item.md |
| Edit an Item | references/task-flows/edit-an-item.md |
| Favorites | references/task-flows/favorites.md |
| Inline Edit | references/task-flows/inline-edit.md |
| Save Presets | references/task-flows/save-presets.md |
Reusable multi-component patterns extracted from real Azure portal prototypes. Read when composing Azure-style pages to avoid re-inventing common layouts.
| Pattern | Description | Reference |
|---|---|---|
| Azure Portal Header | Header with search, Copilot button, avatar popover | references/patterns/azure-portal-header.md |
| Azure Resource Page Shell | Full page scaffold: app frame + header + side nav + breadcrumb + title + toolbar | references/patterns/azure-resource-page-shell.md |
| Info Message Bar (Blue) | Blue info banner with token overrides for cui-message-bar intent="info" | references/patterns/info-message-bar.md |
| Pipeline Health Metric Card | Compact KPI card with semantic status accent icon and metric value | references/patterns/pipeline-health-metric-card.md |
| Side Nav with Iconify Icons | Side navigation using Iconify SVG URLs with regular/filled pairs | references/patterns/side-nav-with-iconify.md |
| Resource Page Toolbar | Horizontal action bar with buttons, dividers, and dropdown menus | references/patterns/resource-page-toolbar.md |
When building an Azure portal page prototype, start with the Resource Page Shell pattern and customize it. It composes the Header, Side Nav, and Toolbar patterns together.
These live React components exist in coherence-preview/src/patterns/ and must be imported instead of hand-building equivalent UI. Re-implementing them from scratch is a recurring mistake that produces inconsistent, non-dismissible, unstyleable results.
| Component | Import path (from experiment root) | What it does | When to use |
|---|---|---|---|
| PageHeader | ../../patterns/PageHeader | Title row: icon + h1 + star + more actions + CopilotSuggestions | Every page that has a title. Pass copilotSuggestions={[...]} prop to include Copilot pills. |
| CopilotSuggestions | ../../patterns/CopilotSuggestions | Dismissible pill bar with CuiIcon name="copilot", CuiTag pills, +N overflow, dismiss button | Automatically used when you pass copilotSuggestions to PageHeader. Import directly only if placing suggestions outside the title row. |
| CopilotButton | ../copilot-button | White pill button for the header's slot="search" area | Every page with an Azure portal header. |
Anti-pattern: Do NOT create custom <button>, <div>, or <span> elements styled to look like Copilot suggestion pills. Always use the CopilotSuggestions pattern or pass the copilotSuggestions prop to PageHeader.
Complete starter files for common Azure portal page types. Copy a scaffold to coherence-preview/src/ and customize the TODOs.
| Scaffold | Description | Asset |
|---|---|---|
| Resource Page | Standard resource blade with header, side nav, breadcrumb, toolbar, content area | assets/scaffolds/azure-resource-page/ |
| List Page | Two-column list + detail layout (APIs, Subscriptions, etc.) | assets/scaffolds/azure-list-page/ |
| Overview Page | Essentials panel + card grid sections | assets/scaffolds/azure-overview-page/ |
| Marketplace Browse | Categories sidebar with service + marketplace grid | assets/scaffolds/azure-marketplace-browse/ |
Multi-step or multi-page flow templates. These involve navigation between steps or pages.
| Flow | Description | Asset |
|---|---|---|
| Create Flow | Multi-step wizard with tabbed form and action bar | assets/flows/azure-create-flow/ |
| Multi-Page Flow | End-to-end flow with multiple pages (Browse → Create → Detail) | assets/flows/azure-multi-page-flow/ |
Usage: Copy the scaffold or flow folder, rename it, fill in the TODO sections, and register it as an experiment in the preview app.
Cross-cutting design guidance. Read when the topic is relevant.
| Guide | Reference |
|---|---|
| Accessibility | references/guides/accessibility.md |
| AI Basics | references/guides/ai-basics.md |
| AI Entry Points | references/guides/ai-entry-points.md |
| Data Visualization | references/guides/data-visualization.md |
| Illustration | references/guides/illustration.md |
| Writing for UI | references/guides/writing-ui.md |
Codified spacing, typography, color, border, shadow, state, layout, and accessibility rules extracted from the Coherence component library, manifest API, theme CSS, and all established patterns. Read before building custom UI and use the coherence-ui-verification skill to check compliance after.
| Resource | Reference |
|----------|-----------||
| Styling Standards Registry | references/styling-standards.md |
| UI Verification Skill (checklist) | ../../coherence-ui-verification/SKILL.md |
The verification skill cross-references three sources: the standards registry, the live API manifest, and the theme CSS. When it encounters a styling decision with no established standard, it asks the user whether to save it as a new rule.
import { CuiButton } from '@charm-ux/cui/react';
export function SaveButton() {
return <CuiButton appearance="primary">Save</CuiButton>;
}
Web component slots map to React props with the same name. Use the slot attribute on child elements:
import { CuiButton, CuiIcon } from '@charm-ux/cui/react';
export function AddItemButton() {
return (
<CuiButton>
<CuiIcon slot="start" name="add" />
Add item
</CuiButton>
);
}
Coherence React wrappers expose events as camelCase callback props. Use the onEventName pattern:
import { CuiDialog, CuiButton } from '@charm-ux/cui/react';
import { useRef } from 'react';
export function ConfirmDialog() {
const dialogRef = useRef<HTMLElement>(null);
return (
<CuiDialog
ref={dialogRef}
heading="Confirm"
onDialogRequestClose={(e) => {
// Optionally prevent close: e.preventDefault();
}}
>
<p>Are you sure?</p>
<CuiButton slot="footer" appearance="primary">Yes</CuiButton>
<CuiButton slot="footer">Cancel</CuiButton>
</CuiDialog>
);
}
import { CuiButton, CuiDrawer } from '@charm-ux/cui/react';
export function SettingsDrawer() {
return (
<>
<CuiButton shows="my-drawer">Open Drawer</CuiButton>
<CuiDrawer id="my-drawer" heading="Settings">
<p>Drawer content</p>
</CuiDrawer>
</>
);
}
Override component styling via CSS custom properties (same in React and HTML):
cui-button {
--button-bg-color: var(--colorBrandBackground);
--button-fg-color: var(--colorNeutralForegroundOnBrand);
--button-border-radius: 8px;
}
<script type="module">
import '@charm-ux/cui/dist/components/button/index.js';
</script>
<cui-button appearance="primary">Save</cui-button>
Every component meets the Microsoft Accessibility Standards (MAS). When composing UIs:
cui-skip-to as the first tab stop on every page<main>, <nav>, <header>) for skip-to navigationaria-label or heading text for dialogs and drawersA Vite + React preview app is set up at coherence-preview/. Use it to render any generated .tsx component in the browser.
coherence-preview/src/main.tsx:
import '@charm-ux/cui/dist/themes/cui/theme.css';
import '@charm-ux/cui/dist/themes/cui/reset.css';
import MyComponent from '../../MyComponent';
cd coherence-preview && npx vitehttp://localhost:5173)The theme CSS imports provide all Coherence design tokens. The @charm-ux/cui/react wrappers auto-register their underlying web component definitions on first render.
Edit coherence-preview/src/main.tsx — replace or add the component import and render it inside the root <div>. Vite HMR will update the browser automatically.
The cui-icon component relies on the Fluent 2 icon set. Icons referenced by name attribute must be registered first.
When generating code that uses <cui-icon name="..."> (or <CuiIcon name="..."> in React), you must ensure the project configuration is imported. Without it, icons will show a fallback question-mark and log a console warning.
For web components / plain HTML:
import '@charm-ux/cui/dist/project-config.js';
import '@charm-ux/cui/dist/components/icon/index.js';
For React: No extra import needed — the @charm-ux/cui/react wrappers auto-register icons.
For the preview app (coherence-preview/): Add this import to main.tsx:
import '@charm-ux/cui/dist/project-config.js';
After importing the project config, ~120 Fluent 2 icons are available. Simple names (prefer these — no network request needed): accessibility, add, alert, attach, bookmark, bot, calendar, chat, checkmark, clock, comment, copilot, copy, cut, delete, dislike, dismiss, edit, emoji, eye, filter, history, hourglass, info, like, link, location, mail, navigation, open, options, paste, pause, person, phone, pin, play, prohibited, resize, save, search, send, settings, share, snooze, star, stop, warning. Compound names: arrow-clockwise, arrow-download, arrow-left, arrow-maximize, arrow-minimize, arrow-move, arrow-redo-regular, arrow-reply, arrow-right, arrow-sort-down, arrow-sort-up, arrow-sync, arrow-undo-regular, arrow-upload, bookmark-filled, calendar-clock, checkmark-circle, chevron-double-left, chevron-double-right, chevron-down, chevron-left, chevron-up, circle-half-fill, code-regular, contact-card, copy-filled, cut-filled, dislike-filled, dismiss-circle, document-checkmark, document-edit, document-ribbon, emoji-meh, emoji-sad, error-circle, eye-off, filter-filled, highlight-regular, like-filled, link-edit-regular, link-regular, lock-closed, lock-open, more-horizontal, paste-filled, person-feedback, pin-filled, star-filled, start-line-horizontal, subtract-circle, tap-single, task-list, text-*-regular (all rich text icons), zoom-in, zoom-out.
Always prefer
nameoverurlwhen the icon exists in the registered set. Only fall back to Iconify URLs orurlattribute for icons not available natively (e.g.terminal,stethoscope,globe,folder,server,database, etc.).
See references/components/icon.md for the full list and custom icon registration.
When working in the local charm-pilot codebase (@charm-ux/core):
Coherence (cui-*) | charm-pilot (ch-*) |
|---|---|
cui-button | ch-button |
cui-dialog | ch-dialog |
cui-input | ch-input |
| ... | ... |
The design guidance, slots, attributes, events, and CSS properties documented in the Coherence references apply to both. The ch-* components in charm-pilot are built following the same Coherence specifications.