VISUALLIdesign system

Building UI with the Visualli design system

Read this before writing or refactoring any frontend code in this monorepo (web app, www, MCP apps, Chrome extensions). It is the contract: build from these components and tokens only. CLAUDE.md in this folder is for changing the design system itself.

Sources of truth — read in this order

  1. components/dist/index.d.ts — every component and its props. If it isn't exported here, it isn't in the system.
  2. components/catalog/<Name>/README.md — when to use each component, and its do's and don'ts.
  3. tokens/tokens.json — every token, with a usage note saying where it belongs. Generated forms: tokens/dist/tokens.css (CSS variables), tokens/dist/tailwind.preset.cjs (Tailwind), tokens/dist/tokens.ts (typed object).
  4. docs/guidelines/brand-book.md (voice, color roles, type roles), canvas-language.md (maps, nodes, gestures), surfaces.md (page layouts), comfort-modes.md (themes and accessibility).
  5. The built docs site (npm run build → docs/dist/) has a live gallery with copyable JSX for every core component, and llms.txt lists every page as Markdown.

Setup in an app

import '@visualli/design-system/tokens.css';   // once, at the app root
import '@visualli/design-system/bundle.css';   // once, after tokens.css
import { Button, Card, TextField, Dialog } from '@visualli/design-system/components';

Tailwind (3.4) — use the preset so only token values have classes:

// tailwind.config.js — new app
module.exports = { presets: [require('@visualli/design-system/tailwind-preset')], content: ['./src/**/*.{ts,tsx,html}'] };
// existing app while migrating: theme: { extend: require('@visualli/design-system/tailwind-preset').theme }

Set the theme on <html>: data-theme = light | dark | focus-light | focus-dark | colorsafe-light | colorsafe-dark | contrast-light | contrast-dark, plus data-type, data-motion, data-reveal, data-scale — or call applyComfort(choice) from ComfortPanel. Never branch on dark mode in component code; the variables switch.

Rules

  1. Components first. Use a system component whenever one fits. Common names map like this:
    You want Use
    Button, link button, CTA Button (variant: primary, secondary = outline, ghost, danger; size: sm, md, lg)
    Icon-only button IconButton (always pass label)
    Input, InputField, textarea TextField (multiline for textarea)
    Search box SearchField
    Toggle, checkbox-like setting Switch
    Tabs / radio group (2–4 options) SegmentedControl
    Modal, dialog, confirm Dialog
    Card, tile, panel section Card
    Dropdown / context menu Menu
    Snackbar, notification Toast
    Tag, chip, status pill Badge
    Tooltip Tooltip
    Icon Icon with a Lucide name from ICONS
    Loader / spinner ThinkingTree (map work) or Button loading
    Chat input Composer; messages: ChatTurn
    Sidebar list of maps Vault / VaultItem
    Map / mind map / canvas VisualMap (never draw nodes by hand; Node, Edge, SemanticPeek, DepthTrail for custom canvases)
    Read-only .visualli viewer (desktop viewer, third-party embeds) VisualliViewer from @visualli/design-system/spec — the spec layer only; never add product features to it
    Hover card / summary popover for an idea SemanticPeek
    Definition popover for a word, glossary term SemanticAnchor
    Explainer side panel / "learn about X" GoDeeper (facets + Map it)
    Attachments / uploaded files / "view source" for a map SourcesPanel (via VisualMap aside)
    Chrome extension side panel / "visualize this page" ExtensionPanel (in chrome.sidePanel; no own brand or ✕ there)
    Floating button group .vi-toolbar with Button/IconButton (size="sm")
    Editing a map: toolbar, contextual actions, inline rename VisualMap editing/onEdit (renders EditBanner, SelectionBar, InlineText, SummaryEditor); applyEdit on the server
    File / link attachment SourceChip
    Settings for theme / accessibility ComfortPanel
  2. Tokens only for everything else. Layout and spacing between components use tokens: var(--space-4), var(--radius-md), var(--surface) — or the preset's classes (p-4, gap-3, rounded-md, bg-surface, text-ink, shadow-float, font-ui, text-body). No hex/rgb values, no px values off the spacing scale, no other fonts, no ad-hoc shadows, durations or easings. If a token is missing, stop and ask; don't invent one.
  3. Don't restyle components. No overriding vi-* classes or passing style props to change their look. If a variant is missing, propose it for the design system instead of forking it in the app.
  4. Accessibility is part of done. Text on the grounds its token note names (4.5:1; 7:1 in contrast-*), visible focus (the components handle it; custom elements use outline: 2px solid var(--focus)), labels on every control, touch targets ≥ 44px, motion that degrades under data-motion="reduced" / prefers-reduced-motion. Never encode meaning in color alone.
  5. Brand rules that are easy to break: no gradients (the spectrum appears as whole adjacent colors: SpectrumBar); hand faces (font-hand, font-note) only on the canvas and in marketing, never in controls; Haksen (font-display) is caps-only; one Signature word per screen; no colored side borders on cards; no emoji in product chrome.
  6. Copy: sentence case, American spelling, the vocabulary in the brand book — Visualli / Visuallis, vault, idea (node in code), connector, layer, rings, peek, step inside (enter an idea's layer), go deeper (understand it), map it, bring.
  7. Logos and icons come from assets/ and ICONS; never redraw, recolor or substitute them.
  8. Check before you finish: run the app in light and dark (and one comfort palette), at phone, tablet and desktop widths; no horizontal scroll; no console errors.

Prompt to give a coding agent

Build the new ‹page› using ONLY the components and tokens of our design system. Read design-system/AGENTS.md first and follow it: components from @visualli/design-system/components (API in design-system/components/dist/index.d.ts), every other value from design-system/tokens/tokens.json via CSS variables or the Tailwind preset. Don't hard-code colors, sizes, fonts, shadows or motion, and don't restyle components. If something you need doesn't exist, stop and list it as a proposed addition instead of inventing it. Verify in light and dark, and at phone, tablet and desktop widths.