# Canon, the Oration design system > Canon holds the tokens, components, patterns and templates behind every Oration surface: the CRM, the Agents Platform, the Contact Center and Ticketing. North star: "The Well-Kept Ledger". Graphite ink on a white plane, rows ruled in hairlines, figures in tabular columns, and one quiet indigo saved for the decision. ## How to build with it - Import components from `@oration/canon/components/`, hooks from `@oration/canon/hooks/` and libraries from `@oration/canon/lib/`. Never fork a component into an app. - Style with the semantic Tailwind tokens (`bg-background`, `text-muted-foreground`, `shadow-border`, `bg-ink-65`), never raw colors. Light and dark come from the same names. - Dense UI is 13px (`text-13`), reading text 14px (`text-sm`), meta 12px (`text-xs`). Controls are 32px (28px in toolbars). - Raised surfaces: `rounded-xl bg-card shadow-border`. Sub-regions inside them: `rounded-[10px] bg-muted/70`. - Motion: `spring.fast | moderate | slow` and `exit.*` from `@oration/canon/lib/springs`. Hover highlights in lists and menus use `useFluidHover`. - State changes swap in place, never snap: `TextSwap` for short labels that change on screen, `IconSwap` for two different icons, `IconMorph` for two states of one line icon, `AnimatedNumber` for figures. See /design/patterns/state-changes. - Every data component renders skeleton, empty and error states through `DataState` and `useMockQuery`. - Copy is sentence case and specific to the sample tenant, Cedarline, an accounts-payable automation vendor: suppliers, invoices, remittances, payment runs, W-9s. - Toasts: `toast.add({ title, description?, type? })` from `@oration/canon/components/toast`. Every mutation gives feedback; reversible ones offer Undo. ## Named rules - **The Quiet Indigo Rule.** Indigo is spent on the view's one filled primary action, on selection, on focus, and on live state that carries a text label (running, active, upcoming), plus the viewer's own markers: the unread dot, an @mention of you, the unsaved-changes dot. It never fills data, tints an icon tile, colors a heading or decorates. - **The One Filled Button Rule.** Each view has at most one filled indigo button, the action the view exists for. Everything else is outline, secondary, ghost, link or a destructive tint. In a stack of proposals, only the expanded one shows its filled button. - **The Ink Fill Rule.** Magnitudes are drawn in ink steps (80, 65, 45, 25, 15) on a Well Gray track: meters, progress, the stage track, ICP bars and the forecast bar. A fill turns semantic only when the value is itself a verdict, such as a strong ICP fit in Ledger Green. It is never indigo. - **The Option Hue Rule.** The ten categorical hues belong to select-option values (stage, lifecycle, tier, list and attribute options) and to identity tints on avatars, monogram tiles and the four app marks. An app hue appears in two places: the glyph tile, and the 3px pill beside the active sidebar item. Categorical hues never color-code sections, navigation text, status or charts. - **The Hairline-and-Lift Rule.** A raised surface takes its edge and its lift from one composite shadow (`shadow-border`), never from a CSS border plus a shadow. CSS borders are for structural dividers only: table rules, header bottoms, section splits. - **The Tint Well Rule.** Inside a card, a sub-region is a Well Gray tint at 70% with a 10px radius, never a second bordered or shadowed card. No card is ever nested in a card. - **The Scroll Edge Rule.** Clipped content shows its edge. Horizontal tab and view rows fade the clipped side over 2rem, and the last pinned grid column casts its edge shadow only once the grid scrolls sideways. - **The Thirteen-Fourteen Rule.** Dense UI is 13px, reading text is 14px, meta is 12px. 11px is for footnotes only, and nothing is set smaller. - **The Tabular Figures Rule.** Every number that changes or gets compared (amounts, counts, percentages, times, credits) is set in tabular figures, and numeric columns align right. - **The Machine Mono Rule.** Geist Mono is only for strings a machine produced or will parse: record and run IDs, API keys, tokens, codes, DNS records, template variables, E.164 phone numbers, timecodes. Figures, labels, keyboard keys and headings stay in Geist Sans. - **The Label-Beside-Color Rule.** Status is never color alone. A dot, tint or ring always travels with a text label (On track, At risk, Running, Passed), so the state reads in grayscale. - **The Sentence Case Rule.** Everything is sentence case. No eyebrow or kicker label above a heading, no uppercase labels, no letter-spaced captions. - **The Layout Over Punctuation Rule.** Metadata is never joined into dot-separated strings (A · B · C). Separate it with layout, commas or words. - **The Owned States Rule.** Every component that shows data owns its loading, empty and error states, with a skeleton shaped like its final layout. A whole page is never gated on loading. - **The Three Springs Rule.** Motion uses `spring.fast`, `spring.moderate` and `spring.slow`, with exits one tier faster that never bounce. No other timings exist except the skeleton reveal, shimmer, the voice orb and meter fills, and keyboard-driven surfaces don't animate. - **The Skeleton Reveal Rule.** Every skeleton that stands in for loading content reaches the screen through `DataState` (data from a query) or `SkeletonReveal` (any other load), which pulse it, then cross-fade and cross-blur to the content over 400ms. Never `loading ? : content`, an `AnimatePresence` fade or a `FadeSwap` for a load. Suspense fallbacks, static skeleton galleries, `AILoader` and button spinners are not reveals. - **The Swap-In-Place Rule.** A label, icon or number that changes while people watch changes in place, never with a bare conditional. Short labels go through `TextSwap`, two different icons through `IconSwap`, two states of one line icon through `IconMorph`, and figures through `AnimatedNumber`. Text decided once (dialog titles, plurals, empty states), sentences, tooltips, menu items and `text-shimmer` labels stay plain. ## Refused outright - Hero-metric card grids (big number, tiny label, trend chip). Show metrics as stat strips, rows, tables or real charts. - Gradient text, glass, backdrop-blur decoration and thick colored left borders. The only gradient-clipped text is the shimmer on an in-progress label; the only animated gradient is the voice orb. - Nested cards. A sub-region inside a card is a tint well. - Solid red destructive buttons. Destructive is a 10% red tint with red text. - Bare lucide icons in circles as empty states. Empty states use an Illustration, a title, one sentence and the next action. - Guided tours, coach marks, modal walkthroughs and confetti. - Emoji in UI, invented customer logos, testimonials, revenue metrics and compliance claims. - Animating keyboard-driven surfaces such as the command palette or J and K moves, and entering from scale 0. ## Pages - [Overview](/design): Canon is the design system behind every Oration surface: its tokens, components, patterns and the rules that hold them together. - [Principles](/design/principles): The Well-Kept Ledger, the five canons and the named rules every screen is judged against. - [Using Canon](/design/using-canon): How designers and engineers pick up Canon: imports, composition, theming and the first screen. - [Repository](/design/repository): Where Canon lives in the monorepo, how a component file is built, and the conventions every file follows. - [Component lifecycle](/design/lifecycle): How a component moves from experimental to stable to deprecated, with live adoption across the suite. - [For agents](/design/for-agents): The condensed brief an AI agent reads before designing or building any Oration screen. - [Brand identity](/design/brand): The Oration mark, the Canon mark, app marks and the sample tenant that every demo speaks for. - [Voice and tone](/design/brand/voice-and-tone): How Oration sounds: professional, clear and friendly, and how the tone shifts from a greeting to an error. - [Writing](/design/brand/writing): The mechanics of Oration copy: sentence case, numbers, dates, labels, errors, empty states and the product glossary. - [Design tokens](/design/foundations/tokens): The token architecture, from raw OKLCH values to semantic roles, read live from the stylesheet. - [Color](/design/foundations/color): A near-monochrome cool-neutral palette with one quiet indigo, four semantic colors, ink steps and ten option hues. - [Typography](/design/foundations/typography): One neutral grotesque set small: Geist Sans for everything a person reads, Geist Mono for what a machine wrote. - [Spacing](/design/foundations/spacing): A 4px rhythm with named gaps for controls, blocks, cards, gutters and sections. - [Layout](/design/foundations/layout): One shell, two page shapes, and the widths, rails and gutters that frame every screen. - [Responsive](/design/foundations/responsive): Breakpoints at 640, 768 and 1024px and how each surface folds down to a phone. - [Shape](/design/foundations/shape): Four radii, 6, 8, 10 and 12px, stepped by size and nested concentrically. - [Elevation](/design/foundations/elevation): Hairline rings and soft layered shadows that lift surfaces without heavy borders. - [Motion](/design/foundations/motion): Fluid Functionalism: three springs, faster exits, a gliding hover and a strict reduced-motion story. - [Iconography](/design/foundations/iconography): Lucide icons at a 1.75 stroke, sized 12 to 16px, always with an accessible name when they stand alone. - [Illustration](/design/foundations/illustration): Neat spot drawings, one subject each: flat Card White shapes with an offset edge, a 1px stroke and one Ink 80 accent, each acting out its subject on mount and on hover. - [Theming](/design/foundations/theming): Light and dark from one token set, how the theme is applied, and how to preview a surface in both. - [Accessibility](/design/foundations/accessibility): The accessibility bar for every screen: focus, keyboard, names, contrast, targets and motion. - [Interaction states](/design/foundations/states): Rest, hover, focus, pressed, selected, disabled, invalid, loading and read-only, and how each is drawn. - [Styles and utilities](/design/foundations/styles): The custom Tailwind utilities, variants and recipes Canon adds on top of the defaults. - [All components](/design/components): Every Canon component by atomic level, category and status, with live adoption counts. - [Button](/design/components/button) (Atom, Stable): The action trigger: six variants, eight sizes and at most one filled indigo button per view. - [Badge](/design/components/badge) (Atom, Beta): A small pill for counts and short labels attached to a control; values use Tag instead. - [Tag](/design/components/tag) (Atom, Stable): A pale option chip for select values such as stage, tier and lifecycle, in ten categorical hues. - [Kbd](/design/components/kbd) (Atom, Stable): A keyboard key or chord, used in tooltips, menus and shortcut hints. - [Label](/design/components/label) (Atom, Stable): The visible name of a form control, linked to it for pointer and screen reader. - [Input](/design/components/input) (Atom, Stable): A single-line text field, 32px tall with an indigo caret and focus ring. - [Textarea](/design/components/textarea) (Atom, Stable): A multi-line text field that grows with its content. - [Checkbox](/design/components/checkbox) (Atom, Stable): A 16px square for independent on and off choices and row selection. - [Radio group](/design/components/radio-group) (Atom, Stable): A set of mutually exclusive options where every choice stays visible. - [Switch](/design/components/switch) (Atom, Stable): An immediate on and off setting that takes effect without a save. - [Slider](/design/components/slider) (Atom, Stable): A draggable thumb for choosing a value or range along a track. - [Toggle](/design/components/toggle) (Atom, Experimental): A two-state button that stays pressed, for formatting and view options. - [Separator](/design/components/separator) (Atom, Beta): A hairline rule that divides content horizontally or vertically. - [Skeleton](/design/components/skeleton) (Atom, Stable): Shimmering placeholders shaped like the content that is loading, with presets for text, rows, tables, cards, stats and charts. - [Spinner](/design/components/spinner) (Atom, Stable): A small indeterminate progress glyph for work that takes a moment. - [Status label](/design/components/status-label) (Atom, Stable): An 8px dot that always travels with a text label, in neutral, live, success, warning, danger and info tones. - [Avatar](/design/components/avatar) (Atom, Stable): A person's photo or initials in a circle, alone or in a group. - [Identicon](/design/components/identicon) (Atom, Stable): A deterministic Bayer mark seeded by a stable id. A circle for a person, a rounded square for a group. - [Agent avatar](/design/components/agent-avatar) (Atom, Stable): An AI agent's Bayer mark in a rounded tile, with a breathing indigo ring while it is live. - [Logo](/design/components/logo) (Atom, Beta): A brand mark or wordmark, in its own colors or in an ink that follows the surface. - [Monogram tile](/design/components/monogram-tile) (Atom, Beta): A neutral letter tile for companies and providers, never a brand logo. - [Progress](/design/components/progress) (Atom, Beta): A 4px ink bar that shows how much of a known task is done. - [Meter](/design/components/meter) (Atom, Stable): A measured bar in ink steps with optional stacked segments and a target marker. - [Animated number](/design/components/animated-number) (Atom, Stable): A tabular figure that rolls to its new value when it changes. - [Icon swap](/design/components/icon-swap) (Atom, Stable): A cross-fade between two icons in one cell, so a state change never shifts layout. - [Icon morph](/design/components/icon-morph) (Atom, Beta): A line icon whose strokes move into a related glyph: menu to close, plus to minus, a chevron flipping. - [Text swap](/design/components/text-swap) (Atom, Beta): A short label that changes in place: shared letters glide, new ones sharpen in, and the width follows. - [Marker](/design/components/marker) (Atom, Experimental): A quiet inline note with an optional icon, rule or bottom border. - [Well](/design/components/well) (Atom, Beta): A 70% Well Gray sub-region inside a card, used instead of a nested card. - [Illustration](/design/components/illustration) (Atom, Beta): Hairline spot illustrations for empty states, errors and education, animated with CSS on mount and hover. - [Hairline illustration](/design/components/hairline) (Molecule, Experimental): Interactive isometric figures in one 1px stroke, six studies of motion and one concept for each idea in the suite, that answer the pointer with springs and rest in a drawn pose. - [Variable chip](/design/components/variable-chip) (Atom, Beta): A {{variable}} token set in mono, showing whether the variable is defined. - [AI loader](/design/components/ai-loader) (Atom, Beta): A pixel-grid shimmer with elapsed seconds for work an AI model is doing. - [Voice orb](/design/components/voice-orb) (Atom, Beta): The one animated gradient in Canon: it visualizes a live voice agent's state and audio level. - [Waveform](/design/components/waveform) (Atom, Stable): Live level bars and a static, seekable waveform for recordings. - [Latency sparkline](/design/components/latency-sparkline) (Atom, Experimental): The line layer of Latency timeline: per-turn latency in exact pixels, with no axes or label of its own. - [Field](/design/components/field) (Molecule, Stable): The form row that ties a label, control, description and error together. - [Input group](/design/components/input-group) (Molecule, Stable): An input or textarea with addons such as icons, units, prefixes and inline buttons. - [Search field](/design/components/search-field) (Molecule, Stable): A compact search input with a leading glyph; clear buttons and key hints go in its children. - [Password input](/design/components/password-input) (Molecule, Beta): A password field with a show and hide toggle. - [One-time code](/design/components/input-otp) (Molecule, Beta): Single-character slots over one input, for verification and two-factor codes. - [Tag input](/design/components/tag-input) (Molecule, Stable): A field that turns typed values into removable chips, with validation and suggestions. - [Editable text](/design/components/editable-text) (Molecule, Stable): Click-to-edit text: Enter or blur commits and Escape restores. - [Slider field](/design/components/slider-field) (Molecule, Beta): A labelled slider with a value readout, min and max hints and reset to default. - [Duration picker](/design/components/duration-picker) (Molecule, Stable): A number and unit pair, with presets, for timeouts, delays and windows. - [Calendar](/design/components/calendar) (Molecule, Stable): A month grid for picking a date or a range. - [Dropzone](/design/components/dropzone) (Molecule, Stable): A drop target for files, with a browse fallback and clear accepted types. - [Select](/design/components/select) (Molecule, Stable): A trigger and popup list for choosing one value from a known set. - [Option select](/design/components/option-select) (Molecule, Stable): A one-line Select for a flat list of string options. - [Select field](/design/components/select-field) (Molecule, Beta): Pre-dressed Select variants for settings, config panels and forms. - [Native select](/design/components/native-select) (Molecule, Stable): The platform select, styled to match, for plain lists on phones and native forms. - [Combobox](/design/components/combobox) (Molecule, Beta): A searchable select for long lists, with single or multiple values as chips. - [Cascader](/design/components/cascader) (Organism, Experimental): A select whose options form a tree: drill into a level, search it and commit a value at any depth. - [Timezone select](/design/components/timezone-select) (Molecule, Beta): A searchable list of IANA time zones with city names, offsets and local times. - [Segmented control](/design/components/segmented-control) (Molecule, Stable): A small radio group drawn as a track with a sliding thumb, for two to five modes. - [Toggle group](/design/components/toggle-group) (Molecule, Beta): A row of toggles where one or several can be pressed, for formatting and filters. - [Choice card](/design/components/choice-card) (Molecule, Beta): Radio cards for choosing between a few modes, each with a description. - [Filter chip](/design/components/filter-chip) (Molecule, Beta): A 28px chip for an active filter, with an indigo tint and a remove button. - [Filters](/design/components/filters) (Organism, Experimental): A stepped filter builder: pick an attribute, a condition and a value as chips, or nest groups in the advanced builder. - [Button group](/design/components/button-group) (Molecule, Beta): Buttons joined into one control, with concentric inner radii. - [Icon action](/design/components/icon-action) (Molecule, Beta): An icon-only button with its tooltip, accessible name and pressed state built in. - [Pending button](/design/components/pending-button) (Molecule, Beta): A button that keeps its width while a spinner replaces its label. - [Hold button](/design/components/hold-button) (Molecule, Stable): A destructive confirmation that fills while you press and hold. - [Copy button](/design/components/copy-button) (Molecule, Stable): An icon button that copies a value and confirms with a check. - [Copy row](/design/components/copy-row) (Molecule, Stable): A read-only value in mono with a copy button, for keys, IDs and URLs. - [AI generate button](/design/components/ai-generate-button) (Molecule, Stable): The sparkles button beside any descriptive field: it drafts text, shimmers while working and offers undo. - [Tabs](/design/components/tabs) (Molecule, Stable): Switch between views of the same object, as a track or as a line. - [Side tabs](/design/components/side-tabs) (Molecule, Beta): A vertical tab list for master and detail pages that wraps to a strip on small screens. - [Breadcrumb](/design/components/breadcrumb) (Molecule, Beta): The path to the current page in the app header, with a sibling switcher on the last crumb. - [Pagination](/design/components/pagination) (Molecule, Experimental): Page links for long, stable result sets where position matters. - [Stepper](/design/components/stepper) (Molecule, Beta): The segmented stage track: done stages in Ink 25, the current one in Ink 80. - [Tooltip](/design/components/tooltip) (Molecule, Stable): A short Graphite Ink label that names an icon or explains a control, after the app's 400ms delay. - [Info tip](/design/components/info-tip) (Molecule, Stable): The i-button popover that explains jargon in place, with an optional help video. - [Popover](/design/components/popover) (Molecule, Stable): A non-modal surface anchored to its trigger for small forms and details. - [Hover card](/design/components/hover-card) (Molecule, Experimental): A preview that opens on hover or focus, for records behind a link. - [Dropdown menu](/design/components/dropdown-menu) (Molecule, Stable): A menu of actions or options that opens from a button. - [Context menu](/design/components/context-menu) (Molecule, Experimental): The right-click menu for rows, cards and canvas nodes, mirroring a visible menu. - [Alert](/design/components/alert) (Molecule, Beta): An inline message about the state of a page or section that stays until resolved. - [Toast](/design/components/toast) (Molecule, Stable): Brief feedback after an action, with undo for anything reversible. - [Empty](/design/components/empty) (Molecule, Stable): The primitives for an empty state: illustration, title, one sentence and the next action. - [Stat strip](/design/components/stat) (Molecule, Stable): Metrics as a strip of label, value, delta and trend, never as hero cards. - [Inline stat strip](/design/components/inline-stat-strip) (Molecule, Beta): A single line of label and value pairs for headers and summaries. - [Mini chart](/design/components/mini-chart) (Molecule, Stable): A sparkline, area or bar chart sized for a row, a stat or a cell. - [Radial chart](/design/components/radial-chart) (Molecule, Beta): A ring that shows one ratio, with a centered label and optional segments. - [Health bar](/design/components/health-bar) (Molecule, Stable): A row of verdict ticks, one per period, with the counts written beside it. - [Timeline](/design/components/timeline) (Molecule, Beta): A vertical list of dated events on a thin rail. - [Meta line](/design/components/meta) (Molecule, Beta): A 12px line of metadata whose parts are separated by gaps, never by dots. - [Item](/design/components/item) (Molecule, Experimental): A list row with media, title, description and actions. - [Card](/design/components/card) (Molecule, Beta): The raised container: 12px corners, a hairline lift and 16px of padding. - [Section header](/design/components/section-header) (Molecule, Beta): A section title on the left with a quiet action on the right, on one baseline. - [Toolbar](/design/components/toolbar) (Molecule, Beta): A row of 28px view controls above a grid or board, with search and filters. - [Accordion](/design/components/accordion) (Molecule, Experimental): Stacked sections that expand one or several at a time. - [Collapsible](/design/components/collapsible) (Molecule, Stable): One region that shows and hides behind a trigger, animating its height. - [Resizable panels](/design/components/resizable) (Molecule, Beta): Panels split by a draggable hairline handle, for editors and multi-pane tools. - [Code block](/design/components/code-block) (Molecule, Stable): Mono code on Row Mist with a title bar and copy, plus inline code. - [JSON viewer](/design/components/json-viewer) (Molecule, Beta): A collapsible, syntax-colored JSON tree with search, filtering, copy for any value or its path, and optional inline editing. - [Code snippet tabs](/design/components/code-snippet-tabs) (Molecule, Stable): Embed code in several languages behind tabs, with instructions and copy. - [QR code](/design/components/qr-code) (Molecule, Stable): A scannable code for a URL or secret, with a download action. - [Video facade](/design/components/video-facade) (Molecule, Beta): A lightweight video poster that loads the player only when someone presses play. - [Attachment](/design/components/attachment) (Molecule, Experimental): A file chip with media, name, size and actions, alone or in a group. - [Bubble](/design/components/bubble) (Molecule, Experimental): A chat bubble with grouping and reactions for human conversations. - [Message](/design/components/message) (Molecule, Experimental): A conversation message with avatar, header and footer for human channels. - [Key-value editor](/design/components/key-value-editor) (Molecule, Stable): Editable rows of keys and values, with secrets masked, for headers and metadata. - [Tool chip](/design/components/tool-chip) (Molecule, Beta): A tool call in a transcript: pending, running, done or failed, with its input and output. - [Thinking](/design/components/thinking) (Molecule, Beta): A collapsible reasoning trace with elapsed time. - [Task list](/design/components/task-list) (Molecule, Beta): Plan rows that tick through queued, running, done and failed. - [Source cards](/design/components/source-cards) (Molecule, Beta): Retrieved context as cards, with inline citation markers that point at them. - [Streaming text](/design/components/streaming-text) (Molecule, Stable): Model output that streams in with a caret, citations and follow-up chips. - [Diff](/design/components/diff) (Molecule, Beta): Inline word diffs and field-change tables for proposed edits. - [Model picker](/design/components/model-picker) (Molecule, Experimental): A compact menu for choosing the model behind a prompt. - [Dialog](/design/components/dialog) (Organism, Stable): A modal surface for focused tasks, with a title, body and a Well Gray footer band. - [Alert dialog](/design/components/alert-dialog) (Organism, Experimental): An interrupting dialog that asks for a decision before continuing. - [Confirm dialog](/design/components/confirm-dialog) (Organism, Stable): The standard confirmation for destructive actions, with an optional typed-name check. - [Form dialog](/design/components/form-dialog) (Organism, Beta): A dialog around a short create or edit form, with Cancel and a filled submit in the footer band. - [Stacked dialog](/design/components/stacked-dialog) (Organism, Beta): A multi-step dialog whose pages stack like cards. - [Sheet](/design/components/sheet) (Organism, Stable): A panel that slides in from an edge for details and secondary tasks. - [Drawer](/design/components/drawer) (Organism, Experimental): A bottom sheet with a swipe handle, for touch-first flows. - [Command menu](/design/components/command) (Organism, Stable): The ⌘K palette: search, jump and run commands from the keyboard. - [Sidebar](/design/components/sidebar) (Organism, Beta): The app rail: workspace switcher, search, grouped navigation and the user menu. - [Navigation menu](/design/components/navigation-menu) (Organism, Experimental): A horizontal menu with rich flyout panels, for marketing-style top navigation. - [Menubar](/design/components/menubar) (Organism, Experimental): A desktop-style row of menus for editors with many commands. - [Data grid](/design/components/data-grid) (Organism, Stable): The record table at Attio density: sticky headers, pinned columns, selection and resize. - [Table](/design/components/table) (Organism, Stable): A semantic table for small, static data sets inside cards and settings. - [Card table](/design/components/card-table) (Organism, Beta): A table set inside a card, with an empty row and compact headers. - [Kanban](/design/components/kanban) (Organism, Beta): A board of draggable cards in Well Gray columns, for pipelines and queues. - [Sortable list](/design/components/sortable-list) (Organism, Stable): A vertical list reordered by drag handle or keyboard. - [Action bar](/design/components/action-bar) (Organism, Beta): The floating bar that rises when rows are selected, with the count and bulk actions. - [Save bar](/design/components/save-bar) (Organism, Stable): The sticky unsaved-changes bar with a change count, Discard, Save and ⌘S. - [Settings section](/design/components/settings-section) (Organism, Stable): The rhythm of every settings page: sections, groups and label-left rows. - [Data state](/design/components/data-state) (Organism, Stable): One wrapper that renders a component's skeleton, empty, error and success states. - [Page intro](/design/components/page-intro) (Organism, Stable): A slim, dismissible banner that explains an overview page, remembered once closed. - [Page title](/design/components/page-title) (Organism, Beta): The document page body and its one h1 with description and actions. - [Card stack](/design/components/card-stack) (Organism, Beta): A pile of cards that fans on hover and cycles on click. - [Carousel](/design/components/carousel) (Organism, Experimental): A horizontal scroller of slides with previous and next controls. - [Chart](/design/components/chart) (Organism, Stable): The Recharts container with Canon's chart colors, tooltip and legend. - [Flow canvas](/design/components/flow) (Organism, Stable): The React Flow canvas: dotted grid, node cards, smooth-step edges and run states. - [Prompt editor](/design/components/prompt-editor) (Organism, Beta): The Tiptap editor for long prompts: variables, a slash menu, AI rewrites with inline diffs and change tracking. - [JSON schema builder](/design/components/json-schema-builder) (Organism, Beta): A visual tree for building tool parameter schemas, with a JSON preview. - [Business hours picker](/design/components/business-hours-picker) (Organism, Stable): A weekly schedule with time zone, per-day slots, copy to all and presets. - [Provider model picker](/design/components/provider-model-picker) (Organism, Beta): Providers as monogram tiles and models with speed, cost and recommendation tags. - [Voice picker](/design/components/voice-picker) (Organism, Beta): Search, filter and preview voices, with accent and gender tags. - [Questionnaire](/design/components/questionnaire) (Organism, Experimental): One question at a time with choices, free text and previous and next. - [Message scroller](/design/components/message-scroller) (Organism, Experimental): A conversation viewport that sticks to the newest message and offers a jump back down. - [Thread](/design/components/thread) (Organism, Beta): The Copilot conversation: welcome, suggestions, messages and scroll to bottom. - [AI message](/design/components/ai-message) (Organism, Beta): User and assistant messages with copy, retry, feedback and branch picking. - [Prompt bar](/design/components/prompt-bar) (Organism, Beta): The composer: autosizing input, @ mentions, / commands, model, attachments, dictation and send. - [Approval card](/design/components/approval-card) (Organism, Beta): Human in the loop: a proposed action with its fields, Approve, Edit and Skip. - [Recommendation card](/design/components/recommendation-card) (Organism, Beta): An AI recommendation with its rationale, confidence and impact. - [Insight card](/design/components/insight-card) (Organism, Beta): A generated insight with a metric, a small chart and its sources. - [Selection actions](/design/components/selection-actions) (Organism, Experimental): A floating toolbar on selected text: rewrite, shorten, translate or ask. - [Latency timeline](/design/components/latency-timeline) (Organism, Beta): Per-turn latency bars or a sparkline, with thresholds and a hover readout. - [Live transcript](/design/components/live-transcript) (Organism, Beta): Speaker-labeled transcript rows with interim text, timestamps and flow-node tags. - [Fluid hover](/design/components/fluid-hover) (Utility, Stable): One highlight that glides to the item under the pointer in lists, menus, tabs and nav. - [Springs](/design/components/springs) (Utility, Stable): The three motion springs and their faster exit tweens. - [Mock query](/design/components/use-mock-query) (Utility, Stable): Simulated loading, failure and retry for demo data, keyed per component. - [Demo controls](/design/components/demo-data) (Utility, Beta): Global latency and failure settings for demos, and a way to replay loading. - [Dirty form](/design/components/use-dirty-form) (Utility, Stable): Tracks which fields changed from their initial values and powers the save bar. - [Simulated stream](/design/components/use-simulated-stream) (Utility, Beta): Streams a string word by word to stand in for model output. - [Overflow fade](/design/components/use-overflow-fade) (Utility, Beta): Fades the clipped edge of a horizontal row over 2rem, only on the side that is clipped. - [Mobile breakpoint](/design/components/use-mobile) (Utility, Beta): Reports whether the viewport is below 768px. - [Size context](/design/components/size-context) (Utility, Experimental): Default and compact control sizes for a whole region, with a matching type scale. - [Class names](/design/components/cn) (Utility, Stable): Merges class names and resolves Tailwind conflicts. - [Scroll area](/design/components/scroll-area) (Utility, Experimental): A styled scroll container with a quiet thumb on a narrow track. - [Aspect ratio](/design/components/aspect-ratio) (Utility, Experimental): Holds media to a fixed ratio while it loads. - [Direction provider](/design/components/direction) (Utility, Experimental): Sets reading direction for components that position popups and sliders. - [Loading, empty and error](/design/patterns/data-states): Every data component owns its states: a skeleton shaped like the result, an empty state that teaches and an error with Retry. - [Forms and validation](/design/patterns/forms): Labels, help text, required fields, inline errors and the order in which a form reveals them. - [Saving and unsaved changes](/design/patterns/saving): When changes save instantly, when they wait for the save bar, and how leaving with unsaved work is handled. - [Destructive actions](/design/patterns/destructive-actions): Undo first, confirm when undo is impossible, and type to confirm when the loss is large. - [Feedback and undo](/design/patterns/feedback): Every mutation answers back: inline, in a toast, or in the place that changed. - [Navigation and wayfinding](/design/patterns/navigation): The sidebar, the header breadcrumbs, sibling switchers, tabs and how people always know where they are. - [Search, filter and sort](/design/patterns/search-and-filter): Search fields, filter chips, saved views and the filtered-to-nothing state. - [Selection and bulk actions](/design/patterns/selection-and-bulk-actions): Row selection, the floating action bar and what happens to a selection as views change. - [AI assistance](/design/patterns/ai-assistance): AI everywhere without noise: generate buttons, streaming summaries, approval cards and the one Copilot. - [Education and onboarding](/design/patterns/education): Pages that explain themselves, info tips beside jargon, empty states that teach, and no tours. - [Keyboard and commands](/design/patterns/keyboard): The command menu, global shortcuts, J and K moves and how shortcuts are shown. - [Permissions and availability](/design/patterns/permissions): Designing for can do, can see but not change, and does not exist for this workspace. - [Live and running states](/design/patterns/live-states): Calls, runs and enrichment that change while you watch, and how Canon shows work in progress. - [Labels and icons that change](/design/patterns/state-changes): When a label, icon or number changes on screen it changes in place: Text swap, Icon swap, Icon morph or Animated number, never a snap. - [Document page](/design/templates/document-page): The centered 72rem column for overviews, settings and records, with one h1 and 32px sections. - [Home](/design/templates/home): The approvals column and its 20rem right rail: what needs a decision, forecast, meetings and tasks. - [List page](/design/templates/list-page): The full-bleed tool: header, 28px toolbar, a grid or board that scrolls inside, and a totals footer. - [Record page](/design/templates/record-page): One record: its name, a sticky line tab bar, activity on the left and a 21rem attribute rail. - [Settings page](/design/templates/settings-page): Settings navigation, sections of label-left rows and the save bar. - [Three-pane workspace](/design/templates/workspace): Queue, conversation and context with AI assist, collapsing to one pane with a back affordance. - [Builder canvas](/design/templates/canvas): A node canvas on the dotted grid with a palette, an inspector and a test run. - [Sign in and account](/design/templates/auth): Centered and split layouts for sign in, sign up, verification and account states. ## Atoms ### Button - Level: Atom - Category: Actions - Status: Stable - Import: `@oration/canon/components/button` - Exports: `Button`, `buttonVariants` - Docs: /design/components/button Button starts an action: it saves, sends, opens, runs or removes something. It is the most used component in the suite, and the fill is rationed. Most buttons on a screen are outline, secondary or ghost; the filled indigo button is saved for the one action the view exists for. Buttons that go somewhere keep link semantics through `render`, and icon-only buttons always carry a name. When to use: - To commit or start an action in place: Save, Send, Run test, Approve and send. - For the primary action of a dialog, sheet, form or page, filled and placed last in its row. - For secondary and tertiary actions beside it, as outline, secondary or ghost. - For a styled link that looks like an action, such as Open workspace, by rendering a `Link` through `render`. - As a square icon button in toolbars and row actions, with an `aria-label` and a tooltip. When not to use: - To navigate inside running text. Use a plain underlined link. - To show a value such as a stage or tier. Values are tags, not controls. Use /design/components/tag instead. - For an icon-only action that needs a tooltip and a pressed state. Reach for the ready-made version. Use /design/components/icon-action instead. - For an on and off setting that applies immediately. Use /design/components/switch instead. - For choosing one of two to five modes of a view. Use /design/components/segmented-control instead. - For a delete that cannot be undone and should not be one click. Use /design/components/hold-button instead. Rules: - The One Filled Button Rule: Each view has at most one filled indigo button, the action the view exists for. Everything else is outline, secondary, ghost, link or a destructive tint. In a stack of proposals, only the expanded one shows its filled button. - Destructive is a tint: Destructive buttons are a 10% Signal Red tint with red text, never a solid red fill. Loss is communicated by the words and by a confirmation, not by alarm color. Anatomy: - Container: A 32px box with 10px corners and a transparent 1px border that becomes the focus edge. `bg-clip-padding` keeps fills inside it. - Leading icon: Optional, 16px, marked `data-icon="inline-start"` so the left padding tightens by 2px. - Label: Control type: 14px at weight 500, one line, verb first, sentence case. - Trailing icon: Optional, marked `data-icon="inline-end"`, for disclosure chevrons and outbound arrows. - Focus ring: A 3px Focus Indigo ring at 40% plus an indigo border, only for keyboard focus. States: - Rest: The variant's fill. Outline adds the control shadow; primary adds its inset highlight. - Hover: Primary darkens by mixing 9% black (8% white in dark). Outline and ghost fill Well Gray. Secondary mixes 5% ink. Destructive deepens to a 20% tint. 150ms on the house ease-out. - Focus visible: Indigo border and a 3px ring at 40%. Destructive uses a red ring at 20%. Pointer focus draws nothing. - Pressed: Scales to 0.96 while held, only when motion is allowed. - Expanded: When it opens a menu or popover (`aria-expanded`), outline and ghost keep the hover fill while the popup is open. - Disabled: 50% opacity and no pointer events. Prefer explaining why nearby over disabling silently. - Invalid: With `aria-invalid`, a red border and a 3px red ring at 20%, for buttons that act as form controls. - Pending: Use Pending button: the label fades in place and a spinner sits on top, so the width never jumps. Behavior: - Renders a native `