Design System

Canvas UI, token, and shadcn consumption rules.

Canvas uses local shadcn-derived UI and CSS variables without forking shadcn.

styles/index.css
  -> Tailwind, shadcn CSS, font imports, and CSS pipeline imports

styles/foundation.css
  -> shared font and semantic material entrypoint for Canvas and Desktop

styles/base.css
  -> base rules such as text selection

styles/materials/*
  -> raw material values and Tailwind bridge

styles/kits/*
  -> standard kits for artifact root, content scale, and rich component values

styles/layouts/index.css
  -> artifact layout style API entrypoint

styles/layouts/composition.css
  -> artifact-consumable L2 composition classes

styles/internal/*
  -> Artifact root and artifact-adjacent implementation styles

packages/cli/src/host/styles/*
  -> host chrome tokens plus overlay, sidebar, prompt, and theme editor
     implementation styles that consume Canvas tokens

apps/desktop/src/styles.css
  -> shared foundation consumer plus Desktop title bar and centrally owned
     --canvas-desktop-* values

theme/*
  -> host-owned theme preset registry and shadcn CSS sources

components/ui/*
  -> local visual primitives

components/*.tsx
  -> reusable rich components

artifact files
  -> primitive composition and Canvas public classes

CSS Entry Points

agent-html/styles/index.css is the runtime CSS entrypoint. It imports Tailwind, shadcn CSS, the shared foundation entrypoint, base styles, layout classes, and internal artifact-adjacent classes.

agent-html/styles/foundation.css is the reusable token entrypoint. It owns the Geist font import and delegates raw semantic values to materials/index.css. Canvas and the packaged Desktop consume this file at build time. At runtime Canvas Style sends Desktop an allowlisted theme snapshot; Desktop never reads or injects a selected workspace stylesheet.

agent-html/styles/base.css owns base stylesheet behavior that applies across the Canvas surface, including text selection colors.

agent-html/styles/materials/* owns raw material values and Tailwind mapping. Read materials/foundation.css for base color, font, radius, chart, and shared theme values.

agent-html/styles/kits/* owns artifact-facing standard kits. Read kits/artifact.css, kits/content.css, and kits/code-block.css for artifact root, content scale, and rich component values. Host chrome and theme editor tokens live in packages/cli/src/host/styles/tokens.

agent-html/styles/materials/tailwind.css maps semantic variables into Tailwind tokens.

agent-html/styles/layouts/index.css owns the artifact layout style API entrypoint. It imports narrower public class owners.

agent-html/styles/layouts/composition.css owns the current L2 composition classes artifact agents may consume for layout rhythm, surfaces, icon boxes, and text scale. L3 semantic role classes are intentionally not part of the current artifact layout API.

agent-html/styles/internal/* owns the Artifact reading container and artifact-adjacent implementation styles. Artifact agents do not read it by default. Host chrome implementation styles live in packages/cli/src/host/styles/* and consume Canvas tokens without becoming artifact authoring context.

agent-html/theme/* owns host theme preset resources. Preset files under theme/presets/*.css use standard shadcn v4 CSS format. The preset registry parses :root and .dark variable blocks into Canvas theme variables instead of hand-writing TS variable objects. Matching theme/presets/*.layout.ts modules export Canvas-safe layout metadata such as font assets and antialiased. Host code may consume these through #agent-html-playground/theme/*; artifacts consume semantic tokens and do not choose preset values directly.

Host inspection chrome, including surface padding, toolbar offsets, status spacing, sidebar local spacing, floating prompt surface values, block hover highlighting, and block action placement, uses the same foundation token pipeline. Canvas-specific host tokens and host styles live under packages/cli/src/host/styles.

Canvas Style owns theme mode, preset selection, and live editor variables for both Canvas and Desktop. Canvas Host, sidebar, toolbar, artifact surface, and Desktop page structure share --background and its foreground/action pairs. The Host surface derives its namespaced sidebar tokens from those primitives; sidebar color is not an independent theme axis. Only transient overlays such as dialogs, popovers, and floating prompts use --popover or another elevated surface.

Desktop chrome is borderless by default. Establish groups with spacing, alignment, typography, density, and foreground emphasis. Use token-driven boundaries only for focus-visible, selected, invalid, destructive, or overlay ambiguity. Product composition must not add colored cards, decorative background blocks, gradients, raw palette utilities, literal colors, component-local color mixing, or local visual scales. Desktop primitives are packaged app source and never import a selected workspace's agent-html/components/ui.

Desktop consumes Canvas foundation variables for semantic color, font, radius, and depth. Desktop-only geometry and product chrome values remain under --canvas-desktop-*; Desktop must not redefine shared theme primitives.

DesktopTitleBar is Desktop React chrome, not an operating-system-owned title bar. It consumes the same semantic theme snapshot as DesktopContent, keeps platform-specific window-control order, and owns only --canvas-desktop-* geometry. It does not import Canvas Host styles.

Viewport And Touch Ownership

Desktop and Canvas Host documents lock their root viewport. Desktop home and dialogs own their local overflow; the runtime iframe does not scroll its outer document. In Canvas Host, the artifact ScrollArea viewport is the sole vertical scroll owner and stops scroll chaining at its boundary.

Do not set global touch-action or cancel pointer movement. Carousels, maps, sliders, drag surfaces, and pinch-capable content own their gestures. Touch movement does not produce block hover. When a coarse pointer is available, host controls use a minimum 44px hit target and block actions remain visible.

Artifact root layout also uses this pipeline. Root width and block rhythm are explicit --canvas-artifact-* tokens in styles/kits/artifact.css and are applied by .agent-html-artifact in styles/internal/artifact.css. Artifact color follows the shared --background and --foreground foundation tokens.

Artifact content composition uses Canvas public composition classes for spacing, typography, panel padding, icon-box size, and grid gap. These classes are backed by --canvas-content-* tokens. Panel radius, border, and icon-box color come from shared semantic tokens.

Rich component implementation tokens use matching feature files, such as kits/code-block.css for CodeBlock diff colors.

Artifacts do not import CSS files directly. They consume semantic token classes:

className="bg-background text-foreground border-border"

UI Primitives

agent-html/components/ui/* is the only visual primitive layer for Canvas. It is local source generated from shadcn conventions, but Canvas owns how it is consumed. Artifacts and host controls should use these primitives before hand-writing common UI.

Do not create raw primitive buttons, cards, badges, inputs, tables, sidebars, or dialog controls in artifacts when a local UI primitive exists.

Current Canvas primitives include accordion, alert, alert-dialog, badge, button, calendar, card, carousel, chart, checkbox, collapsible, combobox, command, context-menu, dialog, drawer, dropdown-menu, field, hover-card, input, input-group, input-otp, label, menubar, native-select, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, sidebar, skeleton, slider, switch, table, tabs, textarea, toggle, toggle-group, and tooltip.

Rich components live outside components/ui. agent-html/components/README.md owns the current component route and identifies when to use a rich component instead of a primitive.

Do not rewrite every local primitive to tokenize all spacing, density, or typography values. Keep local shadcn-derived primitives low-modification unless Canvas needs a primitive API, correctness fix, or accessibility fix.

Scale Discipline

Color, radius, font, host chrome spacing, artifact root layout, and artifact content scale use the token pipeline. Local shadcn-derived primitives may still encode their internal spacing and typography as Tailwind utilities.

Font and radius values start in styles/materials/foundation.css and are mapped in styles/materials/tailwind.css:

--font-sans

--font-heading

--font-mono

--radius
  -> --radius-sm/md/lg/xl/2xl/3xl/4xl

--canvas-host-sidebar-* is owned and derived by the Host surface. Foundation and preset files do not define a second sidebar palette.

Shadow uses the static shadcn-style shadow scale. Source-like shadow knobs are not part of the Canvas theme editor unless they drive the full scale.

Artifacts use Canvas public composition classes such as canvas-stack-md, canvas-content-panel, canvas-grid-gap, canvas-icon-box-sm, and canvas-text-body through styles/layouts/index.css for visual scale. Layout behavior utilities such as flex, grid, min-w-0, overflow-hidden, flex-wrap, shrink-0, and truncate may stay in artifact code when they express local structure or overflow behavior. Fixed-format media, map, and carousel blocks may use narrow layout constraints already recorded in packages/cli/src/react-canvas/style-ownership-contract.test.mjs; do not add new arbitrary values when a Canvas semantic class or ordinary layout utility can express the same constraint.

Static artifact styling should stay as plain className strings. Use the local cn helper only when class names are conditional or need to merge with an incoming className; do not import clsx directly in artifacts. Repeated section, header, and panel shapes should stay as React snippets and semantic classes unless they carry reusable behavior. Shared artifact helpers should prefer local hooks and pure functions for fetch, selection, and status mapping over new visual wrapper components.

Artifacts should not use raw palette classes, arbitrary values, decorative gradients, oversized radius, heavy shadows, custom font families, manual tracking, or one-off button, card, and table markup.

Visual Boundary

Artifact owns the readable root container. Agents do not pass root layout or visual props to Artifact; update --canvas-artifact-max-width and --canvas-artifact-block-gap instead. Artifact color follows the shared --background and --foreground foundation tokens.

Block remains a protocol marker. Block content layout and visual treatment belong inside blocks through artifact composition and agent-html/components/ui/*. Block hover highlighting, prompt actions, and floating prompt UI belong to host overlay chrome.

On this page