Design artifacts. Sandboxed iframe designs use public/design-starters/*/tokens.css — separate from the app shell.
Control decision tree
App-wide actions.stdbutton / .altbutton in app-buttons.css
Canvas chrome.cv-* in canvas.css — toolbars, inspector, pills
DropdownsAppListSelect / .app-dropdown — not native <select>
Legacystyles.css patterns — migrate, do not extend
Color
Semantic tokens for the active preview theme. Semantic greens/reds are for feedback only — not decorative chrome.
Text hierarchy
--colorInk / primary text
--text-secondarySecondary text
--text-tertiaryTertiary text
Surfaces
--bgPage background
--verylightbgSubtle surface
--popupbgPopup / panel
--headerbgHeader
--surface-chromeFrosted chrome
--scrim-defaultModal scrim
--scrim-denseDense scrim (no blur)
--modalbgModal tint
--skeleton-baseSkeleton base
Interactive / chrome
--hairlineHairline border
--bordercolorBorder
--field-bgField background
--field-borderField border
--field-border-hoverField border (hover)
--buttonbgButton fill
--lighthoverHover fill
--stdbuttonbgPrimary fill (= ink)
--stdbuttoncolorPrimary fill text
--accentcolorAccent (= ink)
--focus-ringFocus ring
--control-font-sizeCanvas control text
--control-height-mdCanvas control height
--form-control-font-sizeForm field text
--textarea-height-compactCompact textarea
--textarea-height-defaultDefault textarea
--textarea-height-longformLong-form textarea
--textarea-max-height-defaultTextarea max height
Semantic (feedback only)
--color-successSuccess
--color-errorError
--color-warningWarning
Typography
Marketing display for logged-out landing heroes; canvas scale for in-product UI. Titles use --font-title (Space Grotesk Semibold); body and UI copy stay on --font-sans (Inter).
Inter 400 body · 500 UI · Space Grotesk 600 titles
Logged-out landing scale — larger than in-app canvas titles. Space Grotesk Semibold, tight tracking.
Create anything.
Generate, edit, and organize on an infinite canvas.
Seven steps from 2rem page titles down to 11px panel labels. Pick by structural depth: page list → settings section → top bar name → inspector group → uppercase row label — not by how “important” the copy feels.
2.2rem · Page titleMy Boards
20px · Section titleBoard settings
16px · Subsection titleSharing & access
14px · Chrome titleUntitled board
13px · Chat headingNext steps
13px · Inspector sectionLayout
12px · Panel labelLayers
Largest to smallest above. Page title is a step above everything else; chrome and chat sit between section copy and inspector labels. Panel labels are 11px, uppercase, secondary ink.
Sample
Rendered
Class
Token
Where
My Boards
2.2rem2.2rem
cv-heading-page
--text-page-title
.cv-list-title · .app-page-title
Board settings
20px20px
app-section-title
--text-section-title
Settings / modal sections
Sharing & access
16px16px
app-subsection-title
--text-subsection-title
Nested settings blocks
Untitled board
14px14px
cv-heading-chrome
--text-chrome-title
.cv-topbar-title
Next steps
13px13px
cv-heading-chat
--text-chat-heading
.cv-cc-md h1–h6
Layout
13px13px
cv-heading-section
--text-panel-title
.cv-inspector-section-title
Layers
12px12px
cv-heading-panel-label
--text-panel-label
.cv-layers-heading-row · uppercase
Spacing
4px base grid. Prefer tokens over raw pixel values.
--space-14px
--space-28px
--space-312px
--space-416px
--space-520px
--space-624px
--space-832px
--space-1040px
--space-1248px
--space-1664px
Border radius
Radius is contextual: --radius-md for inspector fields, --radius-lg for top-bar controls, --radius-full for toolbars and selection pills.
--radius-nonenone
--radius-smsm (4px)
--radius-mdmd (6px)
--radius-lglg (8px)
--radius-xlxl (12px)
--radius-2xl2xl (16px)
--radius-fullfull
Shadows
--shadow-sm
--shadow-md
--shadow-lg
--shadow-xl
Materials & blur
Frosted chrome, modal scrims, and floating bars use tokenized blur values. Always pair -webkit-backdrop-filter with backdrop-filter for Safari.
Toolbar, inspector, and drawer controls use .cv-* classes where layout-specific.
Icon ghost
Developer spec.cv-icon-btn
Share actions
Developer spec.cv-share-btn · .cv-share-primary
Aspect pills
Developer spec.cv-section-aspect-pill
Primary CTA
Developer spec.cv-section-generate-btn
Floating toolbar
Developer spec.cv-toolbar · .cv-tool
Full canvas chrome catalog lives in styles/components/canvas.css.
Form controls
Text inputs use .app-input. Textareas use .stdtextarea: default for descriptions, .stdtextarea--compact for comments and short notes, and .stdtextarea--longform only for prompts, markdown, or code. Fields are outlined — they sit on --field-bg with a --field-border stroke (no grey fill); hover darkens the border. Field text uses --form-control-font-size; do not use body-copy sizing inside controls. Dropdowns use AppListSelect — not native <select>.
Hierarchy comes from opacity and weight, not product color accents in the app shell.
Developer spec--text-secondary
Layout & dividers
Hairline dividers, cards, and popup surfaces. Page widths use the three shell tiers documented under Page shells.
Horizontal divider
Content above
Content below
Developer spec.app-divider · --hairline
Vertical divider
Developer spec.app-divider-vertical
Content card
Summer campaign
Updated 2 hours ago · 12 assets
Developer spec.app-card
Popup surface
Dropdown or panel on popup surface.
Developer spec--popupbg · --shadow-md
Focus & accessibility
Keyboard focus uses --focus-ring — never hardcoded outline colors.
Focus ring
Tab to the control — uses box-shadow: var(--focus-ring).
Developer spec--focus-ring · .app-focus-target
Input focus
Developer spec.app-input:focus-visible
Elevation & z-index
Staggered stack — higher z-index layers sit above lower ones.
--z-base(1)
--z-dropdown(50)
--z-studio(150)
--z-header(190)
--z-modal(200)
Logos
Logo lockup — header
L icon — compact mark
Lockup — on light
Maintain clear space equal to the height of the “L” mark. Do not stretch, recolor, or place on low-contrast backgrounds.
Do / Don't
✓Do
Add shared UI to styles/components/app-*.css
Use semantic tokens from styles/tokens/
Use canvas heading classes for in-app titles
Use .stdbutton / .altbutton for app-wide actions
Use AppListSelect for dropdown menus
Keep one filled primary per action row
Use opacity-based secondary text
Use --page-* shell tokens for page max-widths
Scope marketing purple to .lp2 only
✕Don't
Stack multiple .stdbutton fills in one row
Use global h1–h6 in app UI
Use native <select> for product UI
Add purple accents to app shell
Add new patterns to styles.css
Hardcode hex in component CSS
Invent one-off page max-widths
Use flat #bbb for secondary text
Page shells
Logged-in content pages pick one shell tier. Long-form copy inside a shell centers on the reading column. Prefer .app-page (with .app-page--narrow / .app-page--wide) or point existing wrappers at these tokens — do not invent a new pixel width.
--page-narrow (720px) — linear single-purpose pages (notifications, simple forms)