# preset AI Documentation > Documentation for preset AI, the design system memory layer for AI coding tools. Full documentation corpus : 46 pages. Each section below is a single page delimited by its URL header, with a structured metadata block preceding the body. --- # preset AI · Documentation Source: https://presetai.dev/docs/ Summary: Pick a path: scan a repo, set up enforcement, plug an AI tool in, or read about the memory layer. Last updated: 2026-05-11 Related: Why the memory layer matters (https://presetai.dev/docs/memory-layer), Scan your repo (https://presetai.dev/docs/scan), Set up enforcement (https://presetai.dev/docs/enforce), Agent resources (https://presetai.dev/docs/agent-resources) --- owner: jschuyler updated: '2026-05-11' status: stable --- export const metadata = { title: 'preset AI · Documentation', description: 'Make AI fluent in your design system. The memory layer that teaches AI coding tools to follow your tokens, components, and patterns.', summary: 'Pick a path: scan a repo, set up enforcement, plug an AI tool in, or read about the memory layer.', last_updated: '2026-05-11', related: ['/memory-layer', '/scan', '/enforce', '/agent-resources'], } export const sections = [ { title: 'Choose where to start', id: 'choose-where-to-start' }, { title: 'Recipes', id: 'recipes' }, ]
Documentation

Make AI fluent in your design system.

The memory layer that teaches AI coding tools to follow your tokens, components, and patterns. Start with the Quickstart, or pick a path below that matches what you're trying to do.

Quickstart Agent resources View on GitHub
llms.txt llms-full.txt index.md
read-only
{`# preset AI Documentation

> Documentation for preset AI, the
> design system memory layer for AI
> coding tools.

- [What is preset AI](/index.md):
  Overview and core concepts.
- [The memory layer](/memory-layer.md):
  Why longitudinal beats snapshot.
- [Scan your repo](/scan.md):
  Run the scanner; review the output.
- [Set up enforcement](/enforce.md):
  Install MCP; watch the first reject.
- [Agent resources](/agent-resources.md):
  Every surface AI tools can read.`}
Live at presetai.dev/docs/llms.txt Open ↗
## Choose where to start

Four paths into preset AI. Pick the one that matches what you're trying to do; they connect.

Guide · 8 min
Scan your repo

Point the scanner at an existing codebase. Get your first memory layer in one command, no config.

Guide · 5 min
Set up enforcement

Install the MCP server. Connect your AI tool. Watch the first generation get redirected to a real preset.

For AI tools
Plug an AI tool in

MCP server, llms.txt, per-page markdown, copy-to-AI: every surface for making an agent fluent in your system.

Concept · 6 min
Read about the memory layer

Why longitudinal beats snapshot for design systems in the AI age, and what that unlocks.

--- # Agent resources Source: https://presetai.dev/docs/agent-resources Type: reference Summary: Every surface AI tools can read: MCP server, llms.txt, per-page markdown, copy-to-AI. Last updated: 2026-05-11 Related: Set up enforcement (https://presetai.dev/docs/enforce), Why the memory layer matters (https://presetai.dev/docs/memory-layer) --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Agent resources', description: 'Every way an AI tool can read preset AI: MCP server, llms.txt, per-page markdown, and one-click context handoff.', type: 'reference', summary: 'Every surface AI tools can read: MCP server, llms.txt, per-page markdown, copy-to-AI.', last_updated: '2026-05-11', related: ['/enforce', '/memory-layer'], } export const sections = [ { title: 'MCP server', id: 'mcp-server' }, { title: 'llms.txt and llms-full.txt', id: 'llmstxt-and-llms-fulltxt' }, { title: 'Per-page markdown', id: 'per-page-markdown' }, { title: 'Copy this page to AI', id: 'copy-this-page-to-ai' }, { title: "What's next", id: 'whats-next' }, ] # Agent resources preset AI is built to be read by AI tools, not just humans. This page lists every surface an agent can use: to query your memory layer, to ingest these docs, or to act on what it reads. Pick the surface that matches what the agent is trying to do. ## MCP server The Model Context Protocol server is the deepest surface. It lets an AI tool call into your live memory layer: list components, look up presets, validate generated code, read context rules at the moment of generation. ```bash claude mcp add --transport http preset https://mcp.presetai.dev/mcp ``` For Cursor, Windsurf, VS Code Agent, and Zed, the install command differs per client. See [developers.presetai.dev](https://developers.presetai.dev/) for the full per-tool list. The MCP server runs over OAuth: no config files, no API keys, no manual rotation. It's free on every plan. Use MCP when the agent needs to **act** on your memory layer: generate code that matches your presets, validate against forbidden primitives, look up the current state of a token. Use the markdown surfaces below when the agent just needs to **read** these docs. ## llms.txt and llms-full.txt For agents that ingest documentation as context, both files live at the root of this site: - [`/llms.txt`](https://presetai.dev/docs/llms.txt): a manifest listing every page with a one-line summary. Compact. Use it for "give me a map" prompts. - [`/llms-full.txt`](https://presetai.dev/docs/llms-full.txt): the full content of every page concatenated into a single payload. Drop the URL into any AI tool that supports remote context. Both regenerate on request, so they stay in sync with the live MDX corpus. No build step. ```bash curl https://presetai.dev/docs/llms-full.txt ``` ## Per-page markdown Every page on this site is also served as raw markdown: same path, `.md` suffix: | Page | Markdown | | ----------------------------- | --------------------------------- | | `presetai.dev/docs/enforce` | `presetai.dev/docs/enforce.md` | | `presetai.dev/docs/memory-layer`| `presetai.dev/docs/memory-layer.md` | | `presetai.dev/docs/` (this index) | `presetai.dev/docs/index.md` | The markdown view strips the chrome and leaves the prose and code blocks. Use it when you want to feed exactly one page to an agent: surgical context, not the whole site. ## Copy this page to AI The button in the top-right of every desktop page handles the common case: - **Copy as markdown**: copies the page's raw markdown to your clipboard, ready to paste into any AI tool. - **Open in Claude**: opens a Claude conversation pre-filled with this page's URL. - **Open in ChatGPT**: same, for ChatGPT. Use it when you're reading something and want the agent to read along with you. ## What's next
Guide
Set up enforcement

Connect a tool via MCP and watch the first rejection land.

Developers
Per-tool quickstarts

Claude Code, Cursor, Windsurf, VS Code, Zed: bespoke setup for each.

Overview
What is preset AI

Back to the overview.

--- # Connect an AI coding tool Source: https://presetai.dev/docs/ai-coding-tools Type: guide Summary: One-line MCP install for each major AI coding tool. preset AI becomes the design-system runtime for the agent. Last updated: 2026-05-12 Related: Agent resources (https://presetai.dev/docs/agent-resources), Set up enforcement (https://presetai.dev/docs/enforce) Install: claude mcp add --transport http preset https://mcp.presetai.dev/mcp --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Connect an AI coding tool', description: 'Give your AI coding assistant access to your design system via MCP. Per-tool install for Claude Code, Cursor, Copilot, Windsurf.', type: 'guide', summary: 'One-line MCP install for each major AI coding tool. preset AI becomes the design-system runtime for the agent.', last_updated: '2026-05-12', related: ['/agent-resources', '/enforce'], install_command: 'claude mcp add --transport http preset https://mcp.presetai.dev/mcp', } export const sections = [ { title: 'Pick a tool', id: 'pick-a-tool' }, { title: 'Claude Code', id: 'claude-code' }, { title: 'Cursor', id: 'cursor' }, { title: 'GitHub Copilot', id: 'github-copilot' }, { title: 'Windsurf', id: 'windsurf' }, { title: 'What your AI can do', id: 'what-your-ai-can-do' }, { title: 'Adaptive behavior', id: 'adaptive-behavior' }, { title: 'Troubleshooting', id: 'troubleshooting' }, ] # Connect an AI coding tool Give your AI coding assistant access to your design system. Once connected via MCP, the agent reads your tokens, presets, and patterns before it writes, and validates code against your rules after. ## Pick a tool Every major AI coding tool that speaks MCP works with preset AI. The install is one line in each. | Tool | Mode | Install | |---|---|---| | **Claude Code** | Terminal | `claude mcp add --transport http preset https://mcp.presetai.dev/mcp` | | **Cursor** | Editor | Add via Settings → MCP, see below | | **GitHub Copilot** | Editor (Agent Mode) | Via VS Code MCP settings | | **Windsurf** | Editor | Via MCP plugin settings | The MCP server runs over OAuth: no API keys to manage. Free on every plan. For a tool-specific operating loop (what to prompt, when to validate, common pitfalls) see the per-tool pages linked from the sidebar. ## Claude Code The fastest install. From any terminal: ```bash claude mcp add --transport http preset https://mcp.presetai.dev/mcp ``` Verify the connection: ```bash claude mcp list ``` You should see `preset` with status `connected`. See the [Claude Code guide](/ai-coding-tools/claude-code) for the recommended operating loop. ## Cursor In Cursor, open **Settings → MCP**. Add a new server: ```json { "mcpServers": { "preset": { "url": "https://mcp.presetai.dev/mcp", "type": "http" } } } ``` Cursor will prompt you to authenticate via OAuth on first use. See the [Cursor guide](/ai-coding-tools/cursor) for the prompting template. ## GitHub Copilot Copilot Agent Mode (VS Code) supports remote MCP servers. In VS Code, open **Settings → Copilot → Agent mode → MCP servers** and add: ```json { "preset": { "url": "https://mcp.presetai.dev/mcp" } } ``` OAuth flow runs on first request. See the [Copilot guide](/ai-coding-tools/copilot) for the governance recommendations. ## Windsurf In Windsurf, open the MCP settings panel and add: ```json { "mcpServers": { "preset": { "url": "https://mcp.presetai.dev/mcp" } } } ``` OAuth on first use. See the [Windsurf guide](/ai-coding-tools/windsurf) for team operating rules. ## What your AI can do Once connected, the agent gains these capabilities: | Capability | Example prompt | |---|---| | **Search** | "Search for button presets." | | **Suggest** | "What preset should I use for a delete action?" | | **Generate** | "Generate a form with email and password inputs." | | **Validate** | "Check this code for design system violations." | | **Fix** | "Fix the violations in this component." | | **Audit** | "Run a design system audit on this file." | ### Example conversations **Finding the right component**: > I need a dropdown for selecting a time period. The agent uses `get_intent_route` and `get_preferred_component` to find the matching preset, then generates code using your design system. **Checking your work**: > Validate this component for design system compliance. The agent uses `validate_generated_code` to check for violations and suggest fixes. **Understanding constraints**: > What should I avoid when building this form? The agent uses `get_forbidden_primitives` and `get_anti_patterns` to explain which patterns are blocked. ## Adaptive behavior The MCP server adapts to your design system's maturity: | Mode | Behavior | Best for | |---|---|---| | **Generative** | Proposes new patterns; warns but doesn't block | Early-stage teams | | **Hybrid** | Suggests existing patterns; warns on violations | Growing teams | | **Enforcement** | Requires existing presets; blocks violations | Enterprise teams | The mode is auto-detected from your preset count, token coverage, and other signals. Override with `set_system_mode`. ## Troubleshooting ### "Connection failed" 1. Confirm you're signed in to preset AI in your browser (OAuth state is shared) 2. Restart your AI tool after configuring MCP 3. Test the server directly: `curl https://mcp.presetai.dev/` returns a JSON health check (the `/mcp` path speaks MCP, not plain GET) ### "Tools not appearing" 1. Restart your AI tool after configuration 2. Check for JSON syntax errors in your config file 3. Confirm OAuth completed: first request opens a browser; you must approve ### "Gateway online but tools don't work" 1. The MCP server is healthy but tool calls may fail for other reasons 2. Check the specific error in the agent's reasoning trace 3. Ensure your design system has data (presets, tokens, components) to act on ## FAQ ### Do I need an API key? No. The MCP server runs over OAuth: your AI tool authenticates once, and the memory layer becomes available immediately. ### Can I use multiple AI tools with the same account? Yes. Every tool authenticates independently but reads from the same memory layer. ### Is my code sent to preset AI servers? Only when you explicitly ask the AI to validate or audit code. MCP tools operate on the code snippets you provide, not your entire codebase. ### What MCP tools are available? 60+ tools across guardrails, discovery, generation, validation, typography, accessibility, Figma, and workflows. See [developers.presetai.dev](https://developers.presetai.dev) for the full reference. --- # Claude Code with preset AI Source: https://presetai.dev/docs/ai-coding-tools/claude-code Type: guide Summary: Operating loop for Claude Code: read context first, generate with constraints, validate, propose canonical changes. Last updated: 2026-05-12 Prerequisites: Connect an AI coding tool (https://presetai.dev/docs/ai-coding-tools) Related: Agent resources (https://presetai.dev/docs/agent-resources), Set up enforcement (https://presetai.dev/docs/enforce) Install: claude mcp add --transport http preset https://mcp.presetai.dev/mcp --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Claude Code with preset AI', description: 'Use Claude Code as a governed design-system runtime. The recommended operating loop: read context, generate within constraints, validate, propose.', type: 'guide', summary: 'Operating loop for Claude Code: read context first, generate with constraints, validate, propose canonical changes.', last_updated: '2026-05-12', prerequisites: ['/ai-coding-tools'], related: ['/agent-resources', '/enforce'], install_command: 'claude mcp add --transport http preset https://mcp.presetai.dev/mcp', } export const sections = [ { title: 'Setup', id: 'setup' }, { title: 'Recommended operating loop', id: 'recommended-operating-loop' }, { title: 'Prompting pattern', id: 'prompting-pattern' }, { title: 'Read, generate, apply', id: 'read-generate-apply' }, { title: 'Common failure patterns', id: 'common-failure-patterns' }, { title: 'Team policy', id: 'team-policy' }, ] # Claude Code with preset AI Use Claude Code with preset AI as a governed design-system runtime. ## Setup One command: ```bash claude mcp add --transport http preset https://mcp.presetai.dev/mcp ``` OAuth runs on first request. Verify the connection: ```bash claude mcp list ``` You should see `preset` with status `connected`. The full per-tool install matrix lives in [Connect an AI coding tool](/ai-coding-tools). ## Recommended operating loop The four-step loop that keeps Claude Code aligned with the system: 1. **Read context first**: inspect relevant presets, patterns, and tokens; fetch active constraints for the target file or intent 2. **Generate with constraints**: request code by preset name and semantic intent; avoid hardcoded values and unapproved primitives 3. **Validate before and after**: run pre-generation checks when available; run generated-code validation and drift checks 4. **Propose before apply** (for system-level changes): for new or changed presets or rules, use the proposal lifecycle; apply only after validation and required approvals ## Prompting pattern Structure your prompts like this: - **Intent**: what you are building - **Context**: target route or component, and constraints - **Required artifacts**: preset names, token categories, patterns - **Validation ask**: request drift and compliance checks before finalizing Example: > Build a destructive confirmation flow for account deletion. Use approved destructive presets, token-based colors, and the interaction rules from the design system. Validate generated code and report drift and compliance findings before final output. ## Read, generate, apply ### Read - at the start of a task - when uncertain about naming or policy - when working in unfamiliar domains or components ### Generate - only after retrieving required constraints or artifacts - for implementation and refactor suggestions ### Apply - direct apply for low-risk local code changes with passing validation - proposal + approval path for canonical system artifacts ## Common failure patterns - generating from generic UI patterns without querying preset AI first - hardcoding style values where tokens exist - skipping post-generation validation - applying system-level changes without the proposal workflow ## Team policy Adopt a simple policy: - **No merge** without passing drift and compliance checks - **No canonical model writes from AI** without a proposal trail - **Require explicit approval** in stricter compliance modes --- # GitHub Copilot with preset AI Source: https://presetai.dev/docs/ai-coding-tools/copilot Type: guide Summary: Operating model for Copilot: gather context first, generate with intent-based constraints, validate, route canonical writes. Last updated: 2026-05-12 Prerequisites: Connect an AI coding tool (https://presetai.dev/docs/ai-coding-tools) Related: Claude Code with preset AI (https://presetai.dev/docs/ai-coding-tools/claude-code), Cursor with preset AI (https://presetai.dev/docs/ai-coding-tools/cursor) --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'GitHub Copilot with preset AI', description: 'Keep Copilot outputs aligned with preset AI tokens, presets, and patterns while maintaining development speed.', type: 'guide', summary: 'Operating model for Copilot: gather context first, generate with intent-based constraints, validate, route canonical writes.', last_updated: '2026-05-12', prerequisites: ['/ai-coding-tools'], related: ['/ai-coding-tools/claude-code', '/ai-coding-tools/cursor'], } export const sections = [ { title: 'Setup', id: 'setup' }, { title: 'Operating model', id: 'operating-model' }, { title: 'Prompting guidance', id: 'prompting-guidance' }, { title: 'Governance', id: 'governance' }, { title: 'Common pitfalls', id: 'common-pitfalls' }, ] # GitHub Copilot with preset AI Keep Copilot outputs aligned with preset AI tokens, presets, and patterns while maintaining development speed. ## Setup GitHub Copilot Agent Mode (VS Code) supports remote MCP servers. In VS Code, open **Settings → Copilot → Agent mode → MCP servers** and add: ```json { "preset": { "url": "https://mcp.presetai.dev/mcp" } } ``` OAuth runs on first request. See [Connect an AI coding tool](/ai-coding-tools) for the full install matrix. Standard Copilot inline completions don't consume MCP. Use Agent Mode for governed generation against your design system. ## Operating model Use Copilot as a coding accelerator, with preset AI as the policy and system-intelligence layer. Recommended flow: 1. Gather preset AI context first (presets, tokens, pattern guidance) 2. Generate with intent-based constraints 3. Validate generated output with drift and compliance checks 4. Route system-level changes through the proposal lifecycle ## Prompting guidance When requesting code, include: - intended component behavior - required preset names - token usage requirements - validation expectation before final merge Example: > Generate a settings card using approved presets and semantic tokens only. Include accessible interaction states and avoid hardcoded styles. ## Governance - enable PR checks for drift and policy validation - require explicit approval for canonical model writes - track recurring violation patterns to refine rules ## Common pitfalls - accepting quick suggestions that bypass semantic presets - copying generated code without a validation pass - mixing local style overrides that create drift --- # Cursor with preset AI Source: https://presetai.dev/docs/ai-coding-tools/cursor Type: guide Summary: Operating workflow for Cursor: discover context, generate within constraints, validate, govern canonical writes. Last updated: 2026-05-12 Prerequisites: Connect an AI coding tool (https://presetai.dev/docs/ai-coding-tools) Related: Claude Code with preset AI (https://presetai.dev/docs/ai-coding-tools/claude-code), Agent resources (https://presetai.dev/docs/agent-resources) --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Cursor with preset AI', description: 'Run Cursor with preset AI as a constrained design-system context source. Discover, generate within constraints, validate, govern.', type: 'guide', summary: 'Operating workflow for Cursor: discover context, generate within constraints, validate, govern canonical writes.', last_updated: '2026-05-12', prerequisites: ['/ai-coding-tools'], related: ['/ai-coding-tools/claude-code', '/agent-resources'], } export const sections = [ { title: 'Setup', id: 'setup' }, { title: 'Recommended Cursor workflow', id: 'recommended-cursor-workflow' }, { title: 'Prompting template', id: 'prompting-template' }, { title: 'Common mistakes', id: 'common-mistakes' }, { title: 'Team policy', id: 'team-policy' }, ] # Cursor with preset AI Generate and edit UI in Cursor while preserving preset AI alignment by default. ## Setup In Cursor, open **Settings → MCP** and add: ```json { "mcpServers": { "preset": { "url": "https://mcp.presetai.dev/mcp", "type": "http" } } } ``` OAuth runs on first request. Verify MCP server connectivity before coding sessions. The full per-tool install matrix lives in [Connect an AI coding tool](/ai-coding-tools). ## Recommended Cursor workflow Four steps per task: 1. **Discover context first**: ask Cursor to fetch relevant presets, patterns, and token guidance; retrieve active constraints for the target task 2. **Generate within constraints**: request intent-based outputs using approved preset names; avoid raw style values and ad-hoc component decisions 3. **Validate and iterate**: run drift and validation checks after generation; apply suggested fixes before finalizing 4. **Govern writes**: for canonical system changes, route through the proposal lifecycle; avoid direct apply in stricter compliance modes without approvals ## Prompting template Use a constrained prompt shape: - task intent - target file or surface - required system artifacts - validation requirement before final answer Example: > Implement a settings form using existing presets and semantic tokens. Validate for drift and compliance and show required fixes before final code. ## Common mistakes - generating from generic framework defaults without a preset AI lookup - accepting output without a validation pass - hardcoding token-like values in component code ## Team policy For teams using Cursor heavily: - enforce PR drift checks - require a proposal trail for system-level artifact changes - review recurring violations to improve rules and guidance --- # Windsurf with preset AI Source: https://presetai.dev/docs/ai-coding-tools/windsurf Type: guide Summary: Operating workflow for Windsurf: retrieve context, generate within constraints, validate, govern canonical writes. Last updated: 2026-05-12 Prerequisites: Connect an AI coding tool (https://presetai.dev/docs/ai-coding-tools) Related: Claude Code with preset AI (https://presetai.dev/docs/ai-coding-tools/claude-code), Cursor with preset AI (https://presetai.dev/docs/ai-coding-tools/cursor), GitHub Copilot with preset AI (https://presetai.dev/docs/ai-coding-tools/copilot) --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Windsurf with preset AI', description: 'Run Windsurf workflows with preset AI as the system constraint and governance source. Context, generation, validation, governed changes.', type: 'guide', summary: 'Operating workflow for Windsurf: retrieve context, generate within constraints, validate, govern canonical writes.', last_updated: '2026-05-12', prerequisites: ['/ai-coding-tools'], related: ['/ai-coding-tools/claude-code', '/ai-coding-tools/cursor', '/ai-coding-tools/copilot'], } export const sections = [ { title: 'Setup', id: 'setup' }, { title: 'Recommended workflow', id: 'recommended-workflow' }, { title: 'Team operating rules', id: 'team-operating-rules' }, { title: 'Failure modes', id: 'failure-modes' }, ] # Windsurf with preset AI Use Windsurf for high-velocity implementation while preserving design-system consistency and governance controls. ## Setup In Windsurf, open the MCP settings panel and add: ```json { "mcpServers": { "preset": { "url": "https://mcp.presetai.dev/mcp" } } } ``` OAuth runs on first request. See [Connect an AI coding tool](/ai-coding-tools) for the full install matrix. ## Recommended workflow Four steps per task: 1. **Context retrieval**: fetch relevant presets, patterns, and token guidance; identify active constraints for the target surface 2. **Generation**: request intent-first UI output; require semantic token and preset usage 3. **Validation**: run drift and compliance checks; capture violations and remediation before merge 4. **Governed changes**: for system-level artifact updates, use propose → validate → apply; require approvals based on current compliance mode ## Team operating rules - no production merge without automated drift and compliance checks - no direct system-artifact apply from AI without an approval path in stricter modes - maintain auditability of major AI-generated changes ## Failure modes Watch for these: - pattern drift introduced by convenience refactors - token bypass through local literals - unreviewed proposal application --- # Active guardrails Source: https://presetai.dev/docs/compliance/active-guardrails Type: guide Summary: Active guardrails combine pre-generation constraints, post-generation validation, and policy gates before apply: a controlled loop instead of ad-hoc assistant behavior. Last updated: 2026-05-12 Related: Rule model (https://presetai.dev/docs/compliance/rule-model), Validation and confidence (https://presetai.dev/docs/compliance/validation-and-confidence), Set up enforcement (https://presetai.dev/docs/enforce) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Active guardrails', description: 'How preset AI moves from passive guidance to active constraint enforcement for AI workflows.', type: 'guide', summary: 'Active guardrails combine pre-generation constraints, post-generation validation, and policy gates before apply: a controlled loop instead of ad-hoc assistant behavior.', last_updated: '2026-05-12', related: ['/compliance/rule-model', '/compliance/validation-and-confidence', '/enforce'], } export const sections = [ { title: 'Objective', id: 'objective' }, { title: 'Guardrail model', id: 'guardrail-model' }, { title: 'Core guardrail layers', id: 'core-guardrail-layers' }, { title: 'Expected outcomes', id: 'expected-outcomes' }, { title: 'Integration guidance', id: 'integration-guidance' }, { title: 'Relationship to compliance modes', id: 'relationship-to-compliance-modes' }, ] # Active guardrails How preset AI moves from passive guidance to active constraint enforcement for AI workflows. ## Objective Ensure AI-generated output is system-aligned by design, not corrected after drift appears. ## Guardrail model Active guardrails combine three moments: - **Constraints before generation**: the agent reads what's allowed before writing - **Validation after generation**: generated code is checked against rules - **Policy gates before apply**: canonical writes are gated on approval Together these create a controlled loop instead of ad-hoc assistant behavior. ## Core guardrail layers 1. Forbidden primitives and anti-pattern constraints 2. Context-aware active constraints by file, intent, or surface 3. Pre-generation validation checks 4. Post-generation code validation and drift checks 5. Mode-aware apply policy gates ## Expected outcomes - lower cleanup work after AI generation - fewer policy violations entering PRs - more predictable assistant behavior across teams ## Integration guidance Use guardrails as the default policy in AI-assisted coding flows: - retrieve constraints first - generate within constraints - validate before commit or apply - route unresolved cases into the proposal workflow ## Relationship to compliance modes Each compliance mode tunes how strictly guardrails block versus advise: - **Observe / Assist**: emphasis on guidance and learning - **Guard / Enforce**: stricter blocking and approval requirements See [Rule model](/compliance/rule-model) for the underlying rule contract and [Validation and confidence](/compliance/validation-and-confidence) for how guardrail results feed scoring. --- # Exceptions and escalation Source: https://presetai.dev/docs/compliance/exceptions-and-escalation Type: guide Summary: Three exception levels (local, domain, system), explicit escalation triggers, and review cadence. No permanent exceptions by default. Last updated: 2026-05-12 Related: Rule model (https://presetai.dev/docs/compliance/rule-model), Active guardrails (https://presetai.dev/docs/compliance/active-guardrails) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Exceptions and escalation', description: 'How to handle policy exceptions without weakening governance. Controlled, traceable, and temporary by default.', type: 'guide', summary: 'Three exception levels (local, domain, system), explicit escalation triggers, and review cadence. No permanent exceptions by default.', last_updated: '2026-05-12', related: ['/compliance/rule-model', '/compliance/active-guardrails'], } export const sections = [ { title: 'Principle', id: 'principle' }, { title: 'Exception policy', id: 'exception-policy' }, { title: 'Exception levels', id: 'exception-levels' }, { title: 'Escalation triggers', id: 'escalation-triggers' }, { title: 'Escalation path', id: 'escalation-path' }, { title: 'AI-specific exception handling', id: 'ai-specific-exception-handling' }, { title: 'Review cadence', id: 'review-cadence' }, { title: 'Metrics to track', id: 'metrics-to-track' }, ] # Exceptions and escalation How to handle policy exceptions without weakening governance. ## Principle Exceptions should be controlled, traceable, and temporary. ## Exception policy Every exception must include: - **reason**: what's being exempted and why - **owner**: who's accountable - **scope**: what it applies to - **expiry date**: when it must be re-reviewed - **rollback or remediation plan**: how it gets cleaned up No permanent exceptions by default. ## Exception levels ### Level 1: Local exception - scoped to one artifact or file set - short expiry - no broad policy change ### Level 2: Domain exception - scoped to a rule domain (for example, token-naming migration) - steward approval required - explicit impact tracking ### Level 3: System exception - cross-domain or org-wide impact - governance lead approval required - mandatory review checkpoint ## Escalation triggers Escalate when any of the following occur: - repeated violations of the same rule category - increasing exception count over time - policy blocks critical delivery repeatedly - security, accessibility, or compliance-critical rules violated - conflicting ownership decisions ## Escalation path 1. Capture issue and context 2. Classify severity and blast radius 3. Assign governance owner 4. Choose immediate containment action 5. Decide rule adjustment, exception extension, or rejection 6. Document final decision and follow-up tasks ## AI-specific exception handling For AI-generated changes: - keep proposal artifacts when exceptions are requested - require explicit human approval in Guard / Enforce modes - log model, tool, and context for post-incident analysis ## Review cadence Run exception reviews at minimum: - **weekly** for active programs - **monthly** for mature, stable systems Review outcomes: - remove expired exceptions - convert recurring exceptions into updated policy - tighten policy where exception abuse appears ## Metrics to track - active exceptions by level - expired exceptions not remediated - repeat exceptions by rule - time-to-resolution by severity --- # Rule model Source: https://presetai.dev/docs/compliance/rule-model Type: reference Summary: Rule shape, severity model, evaluation lifecycle, and quality criteria. The contract underneath every guardrail and validation check. Last updated: 2026-05-12 Related: Active guardrails (https://presetai.dev/docs/compliance/active-guardrails), Validation and confidence (https://presetai.dev/docs/compliance/validation-and-confidence), Exceptions and escalation (https://presetai.dev/docs/compliance/exceptions-and-escalation) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Rule model', description: 'How preset AI expresses, evaluates, and evolves enforceable system rules: the contract for guardrails, validation, and policy gates.', type: 'reference', summary: 'Rule shape, severity model, evaluation lifecycle, and quality criteria. The contract underneath every guardrail and validation check.', last_updated: '2026-05-12', related: ['/compliance/active-guardrails', '/compliance/validation-and-confidence', '/compliance/exceptions-and-escalation'], } export const sections = [ { title: 'Why this exists', id: 'why-this-exists' }, { title: 'Rule shape', id: 'rule-shape' }, { title: 'Rule categories', id: 'rule-categories' }, { title: 'Severity model', id: 'severity-model' }, { title: 'Evaluation lifecycle', id: 'evaluation-lifecycle' }, { title: 'Rule evolution', id: 'rule-evolution' }, { title: 'Exceptions and overrides', id: 'exceptions-and-overrides' }, { title: 'Rule outputs', id: 'rule-outputs' }, { title: 'Rule quality criteria', id: 'rule-quality-criteria' }, ] # Rule model Defines how preset AI expresses, evaluates, and evolves enforceable system rules. ## Why this exists Rules are preset AI's enforcement layer. They convert design-system intent into machine-evaluable constraints for: - product workflows - CI and CLI checks - MCP read/write governance ## Rule shape At minimum, a rule encodes: - **intent**: the behavior or outcome it governs - **predicate**: the condition to evaluate - **severity**: impact level when violated - **scope**: where it applies (artifact, route, workspace, org) - **guidance / fix**: how to remediate ## Rule categories Common categories: - token usage and naming - preset usage and prop constraints - pattern composition rules - interaction and accessibility requirements - AI generation and write constraints ## Severity model Use consistent severity semantics: - **info**: informational, no action required - **warning**: should fix, doesn't block - **error**: should fix, signals real problem - **blocking**: policy-gated, must fix before merge or apply Severity is mode-aware. Same rule, different teeth depending on whether you're in Observe, Assist, Guard, or Enforce. ## Evaluation lifecycle Rules can be evaluated at multiple points: - **pre-generation**: AI constraints - **post-generation**: validate output - **pre-apply**: proposal gate - **CI / PR checks** - **periodic health and audit scans** ## Rule evolution Rules should evolve with system maturity: - start descriptive (guidance-heavy) - graduate to stricter enforcement when confidence is high - track exception volume and false-positive rates - sunset or split brittle rules ## Exceptions and overrides Exceptions should be: - explicit - time-bounded - owner-attributed - auditable Overrides should never silently disable baseline governance. See [Exceptions and escalation](/compliance/exceptions-and-escalation) for the full lifecycle. ## Rule outputs Every evaluation should produce machine- and human-usable output: - pass / fail result - severity and scope - violation location and context - recommended fix path ## Rule quality criteria A good rule is: - **unambiguous**: one interpretation, no edge cases the author meant differently - **testable**: outcome can be verified deterministically - **scoped**: applies only where intended - **explainable**: the violation message tells the reader what to do - **stable**: doesn't flag false positives in typical development workflows --- # Validation and confidence Source: https://presetai.dev/docs/compliance/validation-and-confidence Type: reference Summary: Validation asks Last updated: 2026-05-12 Related: Rule model (https://presetai.dev/docs/compliance/rule-model), Active guardrails (https://presetai.dev/docs/compliance/active-guardrails) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Validation and confidence', description: 'How preset AI evaluates quality and determines trust levels for automated guidance and enforcement.', type: 'reference', summary: 'Validation asks "is the output correct?" Confidence asks "how reliable is our interpretation?" Together they tune how much automation is safe.', last_updated: '2026-05-12', related: ['/compliance/rule-model', '/compliance/active-guardrails'], } export const sections = [ { title: 'Validation goals', id: 'validation-goals' }, { title: 'Confidence goals', id: 'confidence-goals' }, { title: 'Practical usage', id: 'practical-usage' }, { title: 'Operational guidance', id: 'operational-guidance' }, ] # Validation and confidence How preset AI evaluates quality and determines trust levels for automated guidance and enforcement. ## Validation goals Validation should answer: - Is the output structurally and semantically correct? - How severe are detected issues? - What fixes are safe and actionable? ## Confidence goals Confidence should answer: - How reliable is the system's interpretation or mapping? - How much automation is safe at this stage? - When should workflows require human review? ## Practical usage Validation and confidence work together: - **High validation confidence + low-risk scope** → faster apply paths - **Low confidence or ambiguous findings** → proposal + review path - **Repeated low-confidence zones** → improve taxonomy, rules, and metadata ## Operational guidance Track and use: - violation severity distribution - false-positive and false-negative signals - confidence trends by artifact type - remediation latency These should inform rule tuning and maturity-mode progression. See [Rule model](/compliance/rule-model) for the underlying rule contract and [Active guardrails](/compliance/active-guardrails) for how validation feeds the enforcement loop. --- # Set up enforcement Source: https://presetai.dev/docs/enforce Type: guide Summary: Install the MCP server and watch your first AI generation get redirected to a real preset. Last updated: 2026-05-11 Prerequisites: Scan your repo (https://presetai.dev/docs/scan), Review what was extracted (https://presetai.dev/docs/extract) Related: Agent resources (https://presetai.dev/docs/agent-resources) Install: claude mcp add --transport http preset https://mcp.presetai.dev/mcp --- owner: jschuyler updated: '2026-06-19' status: stable --- export const metadata = { title: 'Set up enforcement', description: 'Connect an AI coding tool, install the enforcement layer, and watch your first rejection land.', type: 'guide', summary: 'Install the MCP server and watch your first AI generation get redirected to a real preset.', last_updated: '2026-05-11', prerequisites: ['/scan', '/extract'], related: ['/agent-resources'], install_command: 'claude mcp add --transport http preset https://mcp.presetai.dev/mcp', } export const sections = [ { title: 'Pick a connection', id: 'pick-a-connection' }, { title: 'Install the MCP server', id: 'install-the-mcp-server' }, { title: 'Watch the first enforcement', id: 'watch-the-first-enforcement' }, { title: 'Raise the bar over time', id: 'raise-the-bar-over-time' }, { title: "What's next", id: 'whats-next' }, ] # Set up enforcement Your memory layer exists. Every AI tool in your stack is still ignoring it. This step changes that. ## Pick a connection preset AI exposes your memory layer to agents three ways. Pick the one that matches where you want enforcement to land: - **MCP server**: for Claude Code, Cursor, Windsurf, VS Code Agent Mode, and Zed. Enforces at generation time. Recommended for most teams. - **GitHub Action**: for PRs. Runs `preset validate` on every commit and posts a comment with violations and fixes. Good backstop even if some developers don't use MCP. - **CLI pre-commit hook**: for individual machines. Catches violations before they leave the developer's laptop. You can combine them. MCP for generation, GitHub Action for review, pre-commit as a belt-and-suspenders local gate. ## Install the MCP server For Claude Code (most common): ```bash claude mcp add --transport http preset https://mcp.presetai.dev/mcp ``` For Cursor, Windsurf, VS Code Agent, and Zed, see the [developer quickstarts](https://developers.presetai.dev/). Every client has its own one-command install. The MCP server runs over OAuth: no config files, no API keys to rotate. Your AI tool authenticates once; the memory layer becomes available immediately. ## Watch the first enforcement Open your AI tool and ask it to generate something your design system has a pattern for. A realistic first prompt: > Generate a destructive confirmation dialog for the delete account flow. A tool connected via MCP now sees your presets before it writes anything. You'll get a response that looks more like this: > Using `btn.destructive-confirm` from your preset (matched at 94% confidence). It requires a confirmation dialog: I'll include that too. Compare to the same prompt without preset AI, where the tool invents a button, guesses at a color, and calls the dialog whatever it felt like in the moment. If the tool tries something forbidden, `', component: 'button' }) // Returns missing states, violations, and recommendations ``` ## Common mistakes ### Using focus instead of focus-visible ```jsx // Problem: Ring shows on mouse click // Solution: Ring only on keyboard focus ``` ### Incomplete disabled states ```jsx // Problem: Hover still works when disabled // Solution: Disable pointer events ``` ### Static cards with hover effects ```jsx // Problem: Card looks clickable but isn't

Content

// Solution: No hover on non-interactive elements

Content

``` ## FAQ **When should I use focus vs focus-visible?** - **focus-visible**: buttons, links, cards, tabs (mouse users don't need focus indication) - **focus**: inputs, textareas, selects (users need to see which field is active) **Should all interactive elements have all four states?** Not necessarily: - **Buttons**: hover, focus-visible, active, disabled - **Inputs**: hover, focus, disabled (no active needed) - **Links**: hover, focus-visible (active optional) - **Static cards**: none (they're not interactive) **How dark should hover be?** 10% is the sweet spot. Use `/90` opacity in Tailwind: - `hover:bg-primary/90` (10% darker) - `hover:text-primary/90` (10% darker text) Going darker (e.g., `/70`) is too dramatic for most cases. --- # Motion tokens Source: https://presetai.dev/docs/product/rules/motion-tokens Type: reference Summary: Four duration tokens (instant/quick/normal/slow), five easing tokens (out-quart/out-expo/in-quart/in-out-quart/linear). Semantic intent, not arbitrary numbers. Last updated: 2026-05-12 Related: Transition patterns (https://presetai.dev/docs/product/rules/transition-patterns), Interaction states (https://presetai.dev/docs/product/rules/interaction-states) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Motion tokens', description: 'Consistent timing values for animations and transitions. Semantic duration + easing tokens instead of arbitrary values.', type: 'reference', summary: 'Four duration tokens (instant/quick/normal/slow), five easing tokens (out-quart/out-expo/in-quart/in-out-quart/linear). Semantic intent, not arbitrary numbers.', last_updated: '2026-05-12', related: ['/product/rules/transition-patterns', '/product/rules/interaction-states'], } export const sections = [ { title: 'Duration tokens', id: 'duration-tokens' }, { title: 'Easing tokens', id: 'easing-tokens' }, { title: 'Common combinations', id: 'common-combinations' }, { title: 'Using motion tokens', id: 'using-motion-tokens' }, { title: 'MCP tool', id: 'mcp-tool' }, { title: 'Accessibility', id: 'accessibility' }, ] # Motion tokens Motion tokens define consistent timing values for animations and transitions across your design system. Instead of using arbitrary values like `duration-300` or `ease-in-out`, use semantic tokens that convey meaning. Motion tokens come in two categories: - **Duration tokens**: how long an animation takes - **Easing tokens**: how an animation accelerates and decelerates ## Duration tokens | Token | Value | When to use | |---|---|---| | `instant` | 100ms | Micro-interactions like checkboxes, toggles, hover states | | `quick` | 200ms | UI feedback like button presses, dropdowns, tooltips | | `normal` | 300ms | Standard transitions like modals, sidebars, page changes | | `slow` | 500ms | Emphasis moments: onboarding, hero animations, celebrations | ### Duration selection guide - **Default to `quick`** (200ms) for most UI interactions - Use `instant` (100ms) when feedback needs to feel immediate - Use `normal` (300ms) for significant state changes users need to notice - Use `slow` (500ms) sparingly: only for moments that deserve emphasis ## Easing tokens | Token | Value | When to use | |---|---|---| | `out-quart` | `cubic-bezier(0.25, 1, 0.5, 1)` | Standard exits and settling into place | | `out-expo` | `cubic-bezier(0.16, 1, 0.3, 1)` | Snappy entrances, elements appearing | | `in-quart` | `cubic-bezier(0.5, 0, 0.75, 0)` | Exits that accelerate away, dismissals | | `in-out-quart` | `cubic-bezier(0.76, 0, 0.24, 1)` | Continuous motion, carousels | | `linear` | `linear` | Progress indicators, loading bars | ### Easing selection guide - **Default to `out-quart`** for most transitions - Use `out-expo` when elements need to "pop" into place - Use `in-quart` when elements are leaving or being dismissed - Use `in-out-quart` for continuous or looping animations - Use `linear` only for progress indicators where a constant rate conveys predictability ## Common combinations Recommended duration + easing pairs for common UI patterns: | Pattern | Duration | Easing | Example | |---|---|---|---| | Dropdown open | `quick` | `out-expo` | Menu appearing below button | | Modal enter | `normal` | `out-expo` | Dialog opening | | Modal exit | `quick` | `in-quart` | Dialog closing | | Tooltip show | `quick` | `out-quart` | Tooltip appearing on hover | | Page transition | `normal` | `out-quart` | Navigating between pages | ## Using motion tokens ### In CSS ```css :root { --motion-duration-instant: 100ms; --motion-duration-quick: 200ms; --motion-duration-normal: 300ms; --motion-duration-slow: 500ms; --motion-easing-out-quart: cubic-bezier(0.25, 1, 0.5, 1); --motion-easing-out-expo: cubic-bezier(0.16, 1, 0.3, 1); --motion-easing-in-quart: cubic-bezier(0.5, 0, 0.75, 0); --motion-easing-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1); --motion-easing-linear: linear; } .modal { transition: opacity var(--motion-duration-normal) var(--motion-easing-out-expo); } ``` ### In Tailwind CSS Add to your `tailwind.config.js`: ```js module.exports = { theme: { extend: { transitionDuration: { 'instant': '100ms', 'quick': '200ms', 'normal': '300ms', 'slow': '500ms', }, transitionTimingFunction: { 'out-quart': 'cubic-bezier(0.25, 1, 0.5, 1)', 'out-expo': 'cubic-bezier(0.16, 1, 0.3, 1)', 'in-quart': 'cubic-bezier(0.5, 0, 0.75, 0)', 'in-out-quart': 'cubic-bezier(0.76, 0, 0.24, 1)', }, }, }, } ``` Then use the classes: ```html
Modal content
``` ## MCP tool AI coding tools retrieve motion tokens via `get_motion_tokens`. Parameters: - `category` (optional): `'duration'`, `'easing'`, or `'all'` (default: `'all'`) - `format` (optional): `'tokens'`, `'css'`, or `'tailwind'` (default: `'tokens'`) ``` get_motion_tokens({ category: "duration" }) get_motion_tokens({ category: "easing", format: "css" }) get_motion_tokens({ format: "tailwind" }) ``` ## Accessibility Always respect user preferences for reduced motion: ```css @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } ``` Or in Tailwind: ```html
Content
``` ## FAQ **Why use semantic tokens instead of arbitrary values?** Semantic tokens like `quick` and `normal` communicate intent and ensure consistency. When you see `duration-quick`, you know it's for UI feedback. When you see `duration-300`, you have to guess. **How do I choose between out-quart and out-expo?** - `out-quart` is gentler: good for subtle transitions - `out-expo` is snappier: good for elements that need to "pop" When in doubt, start with `out-quart`. **What if 200ms feels too slow for my dropdown?** Trust the tokens first. If something feels slow, it might be a perception issue from other factors (layout shift, render delay). If after testing you truly need faster, consider whether `instant` (100ms) is appropriate for that interaction type. **Can I create custom duration/easing tokens?** Yes, but be deliberate. Every new token adds complexity. Before adding a custom token, ask: "Does this truly represent a new semantic category, or can I use an existing token?" --- # Responsive patterns Source: https://presetai.dev/docs/product/rules/responsive-patterns Type: reference Summary: Beyond hide/show. Six behavior types: layout-shift, variant-change, size-adaptation, content-truncation, component-swap, visibility. Mobile-first. Last updated: 2026-05-12 Related: Interaction states (https://presetai.dev/docs/product/rules/interaction-states) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Responsive patterns', description: 'How components adapt across screen sizes: layout shifts, variant changes, touch targets, component swaps.', type: 'reference', summary: 'Beyond hide/show. Six behavior types: layout-shift, variant-change, size-adaptation, content-truncation, component-swap, visibility. Mobile-first.', last_updated: '2026-05-12', related: ['/product/rules/interaction-states'], } export const sections = [ { title: 'Breakpoints', id: 'breakpoints' }, { title: 'Behavior types', id: 'behavior-types' }, { title: 'Core patterns', id: 'core-patterns' }, { title: 'Touch target guidelines', id: 'touch-target-guidelines' }, { title: 'Mobile-first development', id: 'mobile-first-development' }, { title: 'Common issues', id: 'common-issues' }, { title: 'MCP tool usage', id: 'mcp-tool-usage' }, { title: 'Validation checks', id: 'validation-checks' }, { title: 'Decision guide', id: 'decision-guide' }, ] # Responsive patterns Responsive patterns define how components adapt across screen sizes. Going beyond simple hide/show, these patterns cover layout shifts, variant changes, touch target adaptations, and component swaps. ## Breakpoints Standard Tailwind breakpoints: | Breakpoint | Min width | Devices | Tailwind | |---|---|---|---| | default | 0px | Mobile | (no prefix) | | sm | 640px | Large mobile, small tablet | `sm:` | | md | 768px | Tablet, small laptop | `md:` | | lg | 1024px | Laptop, small desktop | `lg:` | | xl | 1280px | Desktop | `xl:` | | 2xl | 1536px | Large desktop | `2xl:` | ## Behavior types | Type | Description | Example | |---|---|---| | **layout-shift** | Component rearranges layout | Sidebar → bottom nav | | **variant-change** | Component switches variant | Full button → icon-only | | **size-adaptation** | Dimensions change | Larger touch targets on mobile | | **content-truncation** | Content is shortened | Full text → 2-line truncation | | **component-swap** | Different component entirely | Table → card list | | **visibility** | Show / hide elements | Secondary actions hidden | ## Core patterns ### Navigation: sidebar to bottom Desktop sidebar becomes bottom navigation on mobile. ```jsx ``` **When to use:** - Primary app navigation - Apps with 3-5 main sections **When to avoid:** - Content-heavy sites - Simple marketing pages ### Button: icon collapse Full button on desktop becomes icon-only on mobile. ```jsx ``` **When to use:** - Toolbars with multiple actions - Compact mobile layouts **When to avoid:** - Primary CTAs - Single action that needs a clear label ### Button: stack to inline Buttons stack vertically on mobile, inline on desktop. ```jsx
``` **When to use:** - Form submit / cancel pairs - Confirmation dialogs ### Table: cards on mobile Table displays as cards on mobile. ```jsx {/* Desktop table */} ...{rows.map(...)}
{/* Mobile cards */}
{rows.map(row => ( {row.name} ... ))}
``` **When to use:** - Tables with many columns - Detail-rich data **When to avoid:** - Simple 2-3 column tables - Tables requiring side-by-side comparison ### Modal: fullscreen on mobile Modals expand to fullscreen on mobile. ```jsx {/* Dialog content */} ``` **When to use:** - Form dialogs - Detail views **When to avoid:** - Simple alerts ### Card grid: responsive columns ```jsx
{cards.map(...)}
``` ## Touch target guidelines **Minimum size: 44 × 44 pixels (`h-11 w-11`)** | Element | Mobile classes | |---|---| | Buttons | `min-h-11 min-w-11` | | Icon buttons | `h-11 w-11 p-2` | | Nav items | `min-h-11 py-3` | | List items | `min-h-11 py-2` | ```jsx // Good — meets touch target // Bad — too small ``` ## Mobile-first development **Always write mobile styles first, then add breakpoint overrides.** ```jsx // Mobile-first className="flex flex-col md:flex-row" className="w-full md:w-1/2" className="text-base md:text-sm" // Desktop-first (anti-pattern) className="hidden md:block" // Content hidden on mobile className="flex-row md:flex-col" // Reversed logic ``` ## Common issues ### Input zoom on iOS iOS Safari zooms when input text is smaller than 16px. ```jsx // Good — 16px on mobile prevents zoom // Bad — triggers zoom on mobile ``` ### Table overflow Tables overflow on narrow screens. ```jsx // Option 1: horizontal scroll
// Option 2: component swap
// Bad — overflows
``` ### Spacing differences Use larger touch-friendly spacing on mobile. ```jsx // Good — more padding on mobile className="p-4 md:p-3" className="gap-3 md:gap-2" // Bad — too cramped on touch className="p-1" className="gap-1" ``` ## MCP tool usage ### Get responsive behavior ```typescript // Get patterns for navigation get_responsive_behavior({ component: 'navigation' }) // Get all layout-shift patterns get_responsive_behavior({ behaviorType: 'layout-shift' }) // Include breakpoint definitions and rules get_responsive_behavior({ component: 'button', includeBreakpoints: true, includeRules: true }) ``` ### Validate implementation ```typescript validate_responsive_pattern({ code: '' }) // Returns: warning about small touch target validate_responsive_pattern({ code: '' }) // Returns: warning about desktop-first pattern ``` ## Validation checks | Issue | Severity | Fix | |---|---|---| | Small touch target | Warning | Use `min-h-11 min-w-11` | | Desktop-first hiding | Warning | Use mobile-first approach | | Small input text | Warning | Use `text-base md:text-sm` | | Table without scroll | Warning | Add `overflow-x-auto` or card swap | | Fixed width without responsive | Warning | Add breakpoint variants | ## Decision guide ``` Building component? ├── Does layout change at breakpoints? │ └── Yes → Use layout-shift pattern ├── Does variant change at breakpoints? │ └── Yes → Use variant-change pattern ├── Are there touch targets? │ └── Yes → Ensure 44px minimum on mobile ├── Is it a table with many columns? │ └── Yes → Use component-swap (cards) or scroll └── Is there text that might be too long? └── Yes → Consider content-truncation ``` --- # Transition patterns Source: https://presetai.dev/docs/product/rules/transition-patterns Type: reference Summary: Each transition conveys a specific spatial message. Pick by relationship: same thing morphs, peer content, hierarchy, overlay, in-place replace. Last updated: 2026-05-12 Related: Motion tokens (https://presetai.dev/docs/product/rules/motion-tokens), Interaction states (https://presetai.dev/docs/product/rules/interaction-states) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Transition patterns', description: 'Five core patterns, Container Transform, Shared Axis, Drill, Layer, Fade, each conveying a spatial relationship between states.', type: 'reference', summary: 'Each transition conveys a specific spatial message. Pick by relationship: same thing morphs, peer content, hierarchy, overlay, in-place replace.', last_updated: '2026-05-12', related: ['/product/rules/motion-tokens', '/product/rules/interaction-states'], } export const sections = [ { title: 'The 5 core patterns', id: 'the-5-core-patterns' }, { title: 'Pattern selection decision tree', id: 'pattern-selection-decision-tree' }, { title: 'Container Transform', id: 'container-transform' }, { title: 'Shared Axis', id: 'shared-axis' }, { title: 'Drill Forward / Back', id: 'drill-forward--back' }, { title: 'Layer', id: 'layer' }, { title: 'Fade', id: 'fade' }, { title: 'Common scenarios', id: 'common-scenarios' }, { title: 'Accessibility', id: 'accessibility' }, ] # Transition patterns Transition patterns define HOW content moves between states in your UI. Each pattern conveys a specific spatial relationship to the user, helping them understand where content came from and where it went. ## The 5 core patterns | Pattern | Spatial message | When to use | |---|---|---| | **Container Transform** | "This IS that" | Shared element morphs between states | | **Shared Axis** | "This is NEXT TO that" | Switching between peer content | | **Drill Forward/Back** | "This is INSIDE that" | Navigating up/down hierarchy | | **Layer** | "This is ON TOP of that" | Overlays, modals, dropdowns | | **Fade** | "This REPLACES that" | In-place content changes | ## Pattern selection decision tree When choosing a transition pattern, ask these questions in order: 1. **Is there a shared visual element that should morph?** - YES → **Container Transform** - NO → continue 2. **Is content appearing ON TOP (overlay)?** - YES → **Layer** - NO → continue 3. **Is this navigation between hierarchical levels?** - Going deeper (parent → child) → **Drill Forward** - Going back (child → parent) → **Drill Back** - NO → continue 4. **Is this switching between peer content (same level)?** - YES → **Shared Axis** - NO → continue 5. **Is content just changing in place?** - YES → **Fade** ## Container Transform **Spatial message:** "This IS that" The user perceives that one element has transformed into another, maintaining visual identity and continuity. ### When to use - Card thumbnail expanding to full image - List avatar morphing to profile header - Compact view expanding to detailed view - FAB transforming into a dialog ### When to avoid - No shared visual element exists between states - Elements are semantically different (not the same "thing") ### Implementation ```jsx // Enter: element grows from origin className="origin-center scale-95 opacity-0" // Active: element at full size className="origin-center scale-100 opacity-100" // Duration: normal (300ms), Easing: out-quart ``` ## Shared Axis **Spatial message:** "This is NEXT TO that" Content slides horizontally or vertically, indicating sibling/peer relationship at the same hierarchical level. ### When to use - Tab switching - Carousel / slider navigation - Segmented control switching - Pagination - Onboarding step progression ### When to avoid - Hierarchical navigation (use Drill) - Overlay content (use Layer) ### Direction rule - Going **forward / next**: content slides **LEFT** - Going **back / previous**: content slides **RIGHT** ### Implementation ```jsx // Enter from right (forward navigation) className="translate-x-4 opacity-0" // Exit to left className="-translate-x-4 opacity-0" // Duration: quick (200ms), Easing: out-quart ``` ## Drill Forward / Back **Spatial message:** "This is INSIDE that" Navigating deeper into or back up the information hierarchy. Like drilling into a folder structure. ### When to use Drill Forward - List item to detail view - Parent to child navigation - Breadcrumb drilling down - Folder to contents ### When to use Drill Back - Detail view back to list - Back button pressed - Breadcrumb clicking parent ### Key indicators - **Drill Forward**: breadcrumbs would ADD a level, URL path gets longer - **Drill Back**: breadcrumbs would REMOVE a level, URL path gets shorter ### Implementation ```jsx // Drill Forward — new content from right enterClass="translate-x-full opacity-0" exitClass="-translate-x-1/3 opacity-50" // Drill Back — parent returns from left enterClass="-translate-x-1/3 opacity-50" exitClass="translate-x-full opacity-0" // Duration: normal (300ms), Easing: out-expo ``` ## Layer **Spatial message:** "This is ON TOP of that" Content appears above existing content. The underlying content remains visible (often dimmed) to maintain context. ### When to use - Modal dialogs - Dropdown menus - Tooltips and popovers - Command palette (Cmd+K) - Bottom sheets - Context menus ### Key characteristics - Backdrop / scrim present - Dismissible by clicking outside - Escape key closes it - Does NOT change URL - Focus should be trapped inside ### When to avoid - Full page navigation (use Drill) - Content replacement (use Fade) ### Implementation ```jsx // Enter: scale up and fade in className="scale-95 opacity-0" // Active: full size and visible className="scale-100 opacity-100" // Duration: quick (200ms), Easing: out-quart ``` ## Fade **Spatial message:** "This REPLACES that" Content crossfades in place with no spatial movement. Used when there's no meaningful spatial relationship. ### When to use - Loading state to content - Skeleton to real data - Image swap - Toast notifications - State changes in place - Error to success state ### When to avoid - Navigation that implies direction (use Drill or Shared Axis) - When spatial relationship matters ### Implementation ```jsx // Enter and exit are just opacity enterClass="opacity-0" exitClass="opacity-100" // Duration: quick (200ms), Easing: out-quart // Keep it subtle — fade should feel almost instant ``` ## Common scenarios | Scenario | Pattern | Notes | |---|---|---| | Open modal from button | Layer | Standard overlay | | Open modal from card | Container Transform | If card morphs into modal | | Switch tabs | Shared Axis | Horizontal slide | | List item → detail | Drill Forward | Push from right | | Back button pressed | Drill Back | Return from left | | Skeleton → content | Fade | In-place replacement | | Show dropdown | Layer | Overlay near trigger | | Carousel next | Shared Axis | Slide left | | Toast appear | Fade | No spatial origin | ## Accessibility Always respect `prefers-reduced-motion`: ```css @media (prefers-reduced-motion: reduce) { * { transition-duration: 0.01ms !important; } } ``` For essential animations that convey meaning (like drill direction), consider showing them but making them instant rather than removing them entirely. ## FAQ **How do I choose between Container Transform and Drill?** - **Container Transform**: a specific element (thumbnail, avatar, card) morphs into the destination - **Drill**: the whole view transitions, no specific element continuity If you can point to "this element becomes that element," use Container Transform. If it's general navigation, use Drill. **Should dropdowns use Layer or Fade?** **Layer.** Dropdowns are overlays that appear on top of content. Fade is for in-place content replacement where there's no "on top of" relationship. **What duration should I use?** - **Quick (200ms)**: most UI feedback (dropdowns, tooltips, tabs) - **Normal (300ms)**: significant transitions (modals, page navigation) Use the motion tokens: `duration-quick`, `duration-normal`. **Can I combine patterns?** Generally no. Each transition should use one pattern. The pattern choice communicates spatial meaning; mixing patterns confuses users about the relationship between states. The exception is Container Transform, which may incorporate scaling/opacity similar to other patterns, but the differentiator is the shared element morph. --- # Color: setting up your system Source: https://presetai.dev/docs/product/studios/color Type: guide Summary: Four ways to start a color system, one staged review. Every candidate arrives named and scaled for light and dark; feeds to semantic roles are per-row opt-ins; contrast figures are measured, never estimated. Last updated: 2026-06-10 Related: Typography Studio (https://presetai.dev/docs/product/studios/typography), Importing design systems (https://presetai.dev/docs/importing-design-systems) --- owner: jschuyler updated: '2026-06-10' status: stable --- export const metadata = { title: 'Color: setting up your system', description: 'Create a color system from a template, a description, an import, or a single hex. Colors land named, scaled, and unassigned; nothing is written until you keep it.', type: 'guide', summary: 'Four ways to start a color system, one staged review. Every candidate arrives named and scaled for light and dark; feeds to semantic roles are per-row opt-ins; contrast figures are measured, never estimated.', last_updated: '2026-06-10', related: ['/product/studios/typography', '/importing-design-systems'], } export const sections = [ { title: 'The four ways to start', id: 'the-four-ways-to-start' }, { title: 'The staged review', id: 'the-staged-review' }, { title: 'What gets written', id: 'what-gets-written' }, { title: 'Names and scales', id: 'names-and-scales' }, { title: 'Tips', id: 'tips' }, ] # Color: setting up your system Before a color system exists, the **Color** page offers four ways to start. All four land in the same place: a staged review of candidate colors, where nothing is written until you keep it. ## The four ways to start | Lane | What it does | |---|---| | **Start from a template** | Pre-configured palettes (neutral first, brand forward, status complete) staged as candidates. | | **Describe it** | Say what the product should feel like; AI proposes seed colors. An optional brand hex anchors the proposal. | | **Import what exists** | Paste CSS custom properties, a Tailwind config, or a tokens JSON export; or choose a file. Your authored values become named, scaled candidates. | | **Start from a hex** | One brand color generates a palette skeleton: a near-neutral anchored to your hue, the brand scale, and the status set. | The lanes are equal: none of them is the "right" way, and every one ends in the same review. ## The staged review Each candidate arrives: - **Named.** A name is proposed from the color's hue family (like "iris" or "ember"). Rename anything inline; the name is the color's identity, and the system suggests alternatives without ever forcing one. - **Scaled.** Twelve steps for light mode and twelve for dark, generated with perceptual OKLCH math. Step 9 is the solid: the canonical expression of the color. - **Unassigned, with suggested feeds.** Some candidates carry a suggested role ("feed accent · 9"). Each suggestion is a per-row checkbox you can decline; a color without a feed simply lands in your palette, ready for later. Imported values are kept as-is and pinned to their nearest steps; pinned steps carry a dot and survive regeneration. Contrast figures shown in the review are measured against the app background, never estimated. Set aside anything that does not belong; bring it back if you change your mind. The footer states exactly what will be written before you commit. ## What gets written **Make this your palette** writes: - every kept color as a named palette color with both scales, and - a semantic role for each feed you opted into. Nothing else. Declined feeds and set-aside colors write nothing, and the baseline roles you did not feed wait in the studio with suggested feeds. ## Names and scales - Scales are **fixed at 12 steps for both modes**: a system property, shared by every color, so that "step 9" means the same thing everywhere. - Names are proposed at creation. If you later change a color's value across hue families, the studio suggests a rename and never forces one. ## Tips - The import lane accepts CSS variables, Tailwind configs, Figma variable exports, Tokens Studio files, and Style Dictionary output. Auto-detection picks the parser. - The describe lane proposes seeds only; every scale is generated locally with the same math as every other lane. - If you only have one brand color, the hex lane builds a complete working skeleton you can refine in the studio. --- # Icons Studio Source: https://presetai.dev/docs/product/studios/icons Type: guide Summary: Import icons from Phosphor/Lucide/Heroicons, define semantic roles (delete, save, edit), set size tokens, sync to MCP. Last updated: 2026-05-12 Related: Typography Studio (https://presetai.dev/docs/product/studios/typography), Agent resources (https://presetai.dev/docs/agent-resources) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Icons Studio', description: 'Manage your icon library and define semantic icon roles for consistent usage across your design system.', type: 'guide', summary: 'Import icons from Phosphor/Lucide/Heroicons, define semantic roles (delete, save, edit), set size tokens, sync to MCP.', last_updated: '2026-05-12', related: ['/product/studios/typography', '/agent-resources'], } export const sections = [ { title: 'Getting started', id: 'getting-started' }, { title: 'Icon sources', id: 'icon-sources' }, { title: 'Icon roles', id: 'icon-roles' }, { title: 'Size tokens', id: 'size-tokens' }, { title: 'Default weight', id: 'default-weight' }, { title: 'Preview tabs', id: 'preview-tabs' }, { title: 'Exporting', id: 'exporting' }, { title: 'Tips', id: 'tips' }, ] # Icons Studio Manage your icon library and define semantic icon roles for consistent usage across your design system. ## Getting started Icons Studio opens in **edit mode**: a focused workspace without the sidebar. Access it from the sidebar menu under **Icons**. ### Layout | Panel | Purpose | |---|---| | **Left** | Configuration: icon sources, roles summary, size tokens, weight | | **Right** | Preview and management: browse icons, manage roles, export code | | **Bottom** | Status, export, and save | ## Icon sources Import icons from popular libraries: | Library | Icons | Weights | |---|---|---| | **Phosphor Icons** | 1,248 | 6 (thin, light, regular, bold, fill, duotone) | | **Lucide Icons** | 1,400+ | Customizable stroke | | **Heroicons** | 300+ | Outline & solid | | **Custom SVG** | Your own | Varies | ### Adding an icon library 1. Click **Import existing** dropdown 2. Select a library (e.g., Phosphor Icons) 3. Library loads instantly with full icon manifest 4. Icons appear in the Browse tab You can import multiple libraries: useful when migrating or comparing options. ## Icon roles The core feature: map **semantic action names** to specific icons. This ensures: - consistency across your codebase - AI tools use the correct icons automatically - clear vocabulary for your team ### Example roles | Role | Icon | Description | |---|---|---| | `delete` | Trash | Permanently remove. Cannot be undone. | | `remove` | MinusCircle | Remove from list. Can be re-added. | | `cancel` | X | Stop operation, close dialog. | | `save` | FloppyDisk | Save changes. | | `edit` | PencilSimple | Edit content. | ### Categories Roles are organized by category: - **Destructive**: delete, remove, cancel, discard - **Save**: save, submit, confirm - **Navigation**: back, forward, menu, close - **Edit**: edit, copy, paste, duplicate - **User**: profile, settings, logout - **Status**: success, error, warning, info ### Managing roles 1. Click **Manage roles** in the left panel (or select **Icon Roles** tab) 2. Select a category from the sidebar 3. View existing roles as cards 4. Click **+ Add Role** to create a new mapping 5. Edit role details: name, icon, description, severity ### Severity levels Each role has a severity that affects icon color: | Severity | Color | Use for | |---|---|---| | **Permanent** | Red | Destructive, irreversible actions | | **Reversible** | Amber | Actions that can be undone | | **Neutral** | Default | Standard actions | ## Size tokens Define standard icon sizes: | Token | Default | Use case | |---|---|---| | `xs` | 12px | Inline indicators, badges | | `sm` | 16px | Buttons, form inputs | | `md` | 20px | Default size | | `lg` | 24px | Headers, emphasis | | `xl` | 32px | Hero sections, empty states | Edit sizes in the left panel. Values export as CSS custom properties. ## Default weight Set the default weight for all icons: | Weight | Style | |---|---| | **Thin** | Lightest stroke | | **Light** | Subtle | | **Regular** | Balanced (recommended) | | **Bold** | Emphasis | | **Fill** | Solid shapes | | **Duotone** | Two-tone effect | Individual roles can override the default weight. ## Preview tabs | Tab | Purpose | |---|---| | **Browse** | Search and browse all icons in your library | | **Icon Roles** | Manage semantic mappings by category | | **In Context** | See icons in realistic UI patterns | | **Code** | Export configurations | ## Exporting Download icon configurations: - **CSS Variables**: size tokens as custom properties - **JSON Tokens**: full configuration in token format Exports are available from the **Export** dropdown in the bottom toolbar. ### AI integration Icon roles automatically sync to your MCP server. AI coding tools (Claude Code, Cursor, Windsurf) will: - use `delete` role → Trash icon - use `save` role → FloppyDisk icon - apply correct size tokens - respect weight settings No manual configuration needed in AI tools. See [Agent resources](/agent-resources) for how this surfaces. ## Tips 1. **Start with one library**: Phosphor is recommended for its 6 weights 2. **Define roles early**: establish vocabulary before building UI 3. **Use categories**: group related actions for easier management 4. **Test in context**: use "In Context" tab to see icons in real UI 5. **Keep it simple**: 20-30 roles cover most applications 6. **Document severity**: help your team understand when to use destructive styling --- # Typography Studio Source: https://presetai.dev/docs/product/studios/typography Type: guide Summary: Add fonts (Google/URL/upload/system), map families to semantic roles, set scale ratio and fluid sizing, preview in Article/Dashboard/Marketing contexts. Last updated: 2026-05-12 Related: Icons Studio (https://presetai.dev/docs/product/studios/icons), Typography health audit (https://presetai.dev/docs/product/health/typography-audit) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Typography Studio', description: 'Configure your design system\'s typography with real-time preview: fonts, families, scale, contexts.', type: 'guide', summary: 'Add fonts (Google/URL/upload/system), map families to semantic roles, set scale ratio and fluid sizing, preview in Article/Dashboard/Marketing contexts.', last_updated: '2026-05-12', related: ['/product/studios/icons', '/product/health/typography-audit'], } export const sections = [ { title: 'Getting started', id: 'getting-started' }, { title: 'Font sources', id: 'font-sources' }, { title: 'Families', id: 'families' }, { title: 'Scale', id: 'scale' }, { title: 'Preview', id: 'preview' }, { title: 'Saving and exporting', id: 'saving-and-exporting' }, { title: 'Contexts', id: 'contexts' }, { title: 'Tips', id: 'tips' }, ] # Typography Studio Configure your design system's typography with real-time preview. ## Getting started Typography Studio opens in **edit mode**: a focused workspace without the sidebar. Access it from the sidebar menu under **Typography**. ### Layout | Panel | Purpose | |---|---| | **Left** | Configuration: font sources, families, scale, text styles | | **Right** | Preview: see typography in realistic contexts | | **Bottom** | Status, export, and save | ## Font sources Add fonts from multiple sources: - **Google Fonts**: search 1,500+ free fonts - **URL / CDN**: Adobe Fonts, Fontshare, or custom CDN - **Upload**: self-hosted `.woff2`, `.woff`, `.ttf` files - **System Fonts**: native fonts with no loading time ### Adding Google Fonts 1. Click **+ Add font** in the Font Sources section 2. Select **Google Fonts** 3. Search by name or browse categories 4. Select weights to include (400, 500, 600, 700) 5. Click **Add**: font loads immediately ## Families Map fonts to semantic roles: | Role | Description | Example | |---|---|---| | **Headings** | H1, H6 text | Fraunces | | **Body** | Paragraphs, UI text | Inter | | **Mono** | Code blocks | JetBrains Mono | | **Display** | Hero headlines | Fraunces | | **UI** | Buttons, labels | Inter | | **Accent** | Special emphasis | Fraunces | **Tip:** Enable "Single font family" to use one font for all roles: common for minimal designs. ## Scale Configure your type scale. ### Base size The foundation: typically 16px for web. All other sizes derive from this. ### Scale ratio How sizes grow between steps: | Ratio | Name | Best for | |---|---|---| | 1.125 | Major Second | Dashboards, data-dense UIs | | 1.200 | Minor Third | General apps | | 1.250 | Major Third | Most websites (recommended) | | 1.333 | Perfect Fourth | Editorial, marketing | | 1.414 | Augmented Fourth | Landing pages | | 1.618 | Golden Ratio | Maximum expression | ### Fluid sizing Enable to automatically scale typography between viewport sizes. Typography smoothly transitions from mobile to desktop without breakpoints. ## Preview The right panel shows your typography in context: | Tab | Shows | |---|---| | **Article** | Long-form content with headings, body, and captions | | **Dashboard** | Stats, tables, and UI elements | | **Marketing** | Hero sections and feature grids | ### Preview controls - **Light/Dark**: toggle background color - **Mobile/Desktop**: test responsive sizing - **Grid**: show baseline alignment ## Saving and exporting ### Save draft Saves to your design system. Other team members won't see changes until published. ### Publish Makes changes live for all team members and exports to connected tools. ### Export Download typography as: - **CSS Variables**: custom properties for web - **JSON Tokens**: design token format for tools like Tokens Studio ## Contexts Contexts let one design system vary by surface: Marketing, Editorial, Slides, Email: while staying the same brand. The selector in the studio header switches between them: - **Base** is your brand truth. Editing on Base changes the design system itself. - **Other contexts inherit from Base live.** A context stores only what you override there; everything else follows Base automatically: change a Base font and every context that didn't override it updates too. - **Setting a value back to its Base value removes the override**, so the context resumes inheriting. The switch is design-system-wide, not per-studio: picking a context here moves Typography, Color, and Icons (and token views) to the same lens. Use **Add context** in the selector to create a new one: it starts as a transparent overlay on Base with no overrides. ## Tips 1. **Start with presets**: use "Import existing" to load curated starting points 2. **Preview often**: switch between Article/Dashboard/Marketing to catch issues 3. **Test both themes**: check light and dark mode 4. **Use fluid sizing**: eliminates most responsive typography issues 5. **Limit fonts**: 2-3 fonts maximum for cohesion --- # Workspace Home Source: https://presetai.dev/docs/product/workspace-home Type: reference Summary: Home answers three questions: where am I, what should I do next, is anything broken or disconnected? Last updated: 2026-05-12 Related: Typography health audit (https://presetai.dev/docs/product/health/typography-audit), Key concepts (https://presetai.dev/docs/key-concepts) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Workspace Home', description: 'The Home surface as a lightweight workspace launchpad for a design system. Recent work, create CTAs, system status.', type: 'reference', summary: 'Home answers three questions: where am I, what should I do next, is anything broken or disconnected?', last_updated: '2026-05-12', related: ['/product/health/typography-audit', '/key-concepts'], } export const sections = [ { title: 'Purpose', id: 'purpose' }, { title: 'Experience model', id: 'experience-model' }, { title: 'What Home should not do', id: 'what-home-should-not-do' }, { title: 'Routing expectations', id: 'routing-expectations' }, { title: 'Data requirements', id: 'data-requirements' }, ] # Workspace Home The Home surface is a lightweight workspace launchpad for a design system. ## Purpose Home should answer three questions quickly: 1. Where am I? 2. What should I do next? 3. Is anything broken or disconnected? Home is not a full dashboard, integrations setup flow, or documentation hub. ## Experience model ### Primary zones **1. Continue working** - recent artifacts (last edited) - in-progress items and drafts (when available) - link to full activity / browse view **2. Create** - create token - create preset - create pattern **3. System status (signals only)** - health score + link to issues and audits - MCP connection status + link to Connect - code/repo connection status + link to Connect **4. Context links** - principles - about - team / contributors **5. Other design systems (optional)** - either bottom section in Home, or centralized switcher ## What Home should not do - host full analytics workflows (Health owns this) - host integration configuration flows (Integrate owns this) - become a docs content index (Use / Docs owns this) ## Routing expectations Home should link out to deeper workflows: - continue item → artifact-specific editor / browse route - create CTA → creation route - health signal → Health Dashboard / Audits - connection signals → Connect / Integrate routes ## Data requirements Home needs fast summary data: - design system identity (name, optional description) - counts (presets, tokens, patterns) - recent artifacts with type + timestamp (+ draft/published where supported) - health score and top issue count - MCP connection status - code connection status --- # Scan your repo Source: https://presetai.dev/docs/scan Type: guide Summary: Run the scanner on your codebase. Extract tokens, patterns, and candidate presets. Last updated: 2026-05-11 Related: Review what was extracted (https://presetai.dev/docs/extract), Why the memory layer matters (https://presetai.dev/docs/memory-layer) Install: preset scan --- owner: jschuyler updated: '2026-06-20' status: stable --- export const metadata = { title: 'Scan your repo', description: 'Run the scanner on your codebase. preset AI extracts tokens, patterns, and candidate presets without touching your code.', type: 'guide', summary: 'Run the scanner on your codebase. Extract tokens, patterns, and candidate presets.', last_updated: '2026-05-11', related: ['/extract', '/memory-layer'], install_command: 'preset scan', } export const sections = [ { title: 'Before you start', id: 'before-you-start' }, { title: 'Run the scanner', id: 'run-the-scanner' }, { title: 'What it found', id: 'what-it-found' }, { title: "What's next", id: 'whats-next' }, ] # Scan your repo Point preset AI at your codebase. The scanner reads your component tree, extracts tokens and patterns, and writes a first-draft `preset.yaml` you can review. Nothing is modified; nothing is committed. ## Before you start You need Node 20 or later and a repo with a component library. preset AI recognizes: - **Component libraries**: shadcn/ui, Radix, Chakra, Material UI, Ant Design, HeroUI, DaisyUI. - **Token sources**: Tailwind config, CSS custom properties, Style Dictionary output, Figma Variables exports. - **Pattern inputs**: Storybook stories, your own MDX documentation, fixture files. The scanner is read-only. It does not write into your `src/` tree. The only file it creates is `preset.yaml` at the repo root: which you can delete or move if you want it elsewhere. ## Run the scanner From your repo root: ```bash preset scan ``` On the first run the CLI bootstraps its cache under `.preset/` (added to `.gitignore` automatically) and writes `preset.yaml`. Typical output: ``` ✓ Scanning ./src/components .......... 42 components ✓ Extracting tokens ................... 128 tokens ✓ Identifying patterns ................ 17 patterns ✓ Writing preset.yaml ................. done Review at https://presetai.dev/dashboard ``` For a detailed scan with per-component breakdowns, pass `--verbose`. To restrict to one component, `--component Button`. Every flag is documented in the [CLI reference](https://developers.presetai.dev/cli/scan). The scanner uses static analysis, not AI. It reads your code as an AST and matches known shapes. That means it is fast, deterministic, and free to run: no API key required for the scan itself. ## What it found `preset.yaml` is the human-readable output. It has three top-level sections: - `tokens`: colors, spacing, typography, radii, and shadows, grouped by category with confidence scores. - `patterns`: recurring shapes in your component tree (e.g. "button + icon", "form field with label + helper + error"). - `proposals`: presets the scanner suggests based on patterns that appeared three or more times. Confidence is a number between 0 and 1. High-confidence entries are ones the scanner is sure about: exact matches on known library patterns, for example. Low-confidence entries are candidates that need your eyes. You don't have to accept anything. The next step is where you decide what becomes part of your memory layer. ## What's next
Guide
Review what was extracted

Confirm, edit, or reject. Decide what becomes canonical.

Reference
preset scan (all flags)

Every flag documented on the developers site.

--- # Snapshot a PDF Source: https://presetai.dev/docs/snapshot-pdf Type: guide Summary: Scan a brand-guidelines PDF to extract its declared tokens. Useful for agencies onboarding a client. Last updated: 2026-05-25 Related: Snapshot a URL (https://presetai.dev/docs/snapshot-url), Scan your repo (https://presetai.dev/docs/scan), Review what was extracted (https://presetai.dev/docs/extract) Install: preset snapshot --pdf brand-guidelines.pdf --- owner: jschuyler updated: '2026-06-20' status: stable --- export const metadata = { title: 'Snapshot a PDF', description: 'Bootstrap a starter design system from a brand-guidelines PDF. preset AI reads declared token literals from the text and infers the rest per page via vision.', type: 'guide', summary: 'Scan a brand-guidelines PDF to extract its declared tokens. Useful for agencies onboarding a client.', last_updated: '2026-05-25', related: ['/snapshot-url', '/scan', '/extract'], install_command: 'preset snapshot --pdf brand-guidelines.pdf', } export const sections = [ { title: 'When to use the PDF lane', id: 'when-to-use' }, { title: 'Run the snapshot', id: 'run-the-snapshot' }, { title: 'What the scanner captures', id: 'what-it-captures' }, { title: 'What it cannot capture', id: 'what-it-cannot-capture' }, { title: 'Accuracy expectations', id: 'accuracy-expectations' }, { title: 'How the four lanes compare', id: 'comparing-lanes' }, { title: "What's next", id: 'whats-next' }, ] # Snapshot a PDF Point preset AI at a brand-guidelines PDF. The scanner reads the text for declared hex literals ("Cobalt, #1F47FF"), rasterizes each page, and runs vision-per-page to infer everything the text doesn't declare. The result is the same `DesignSystemSnapshot` shape the other lanes produce, primitives, semantic tokens, type styles, spacing rhythm, ready to refine into your own system. ## When to use the PDF lane The PDF lane is the right starting point when: - You're an agency onboarding a client who has a brand-guidelines PDF but no public site or codebase yet. - You have a brand book that declares colors, type, and spacing in text alongside the visual examples. - You want exact hex values, not vision-inferred approximations, where the document declares them. If you have a repo, prefer the [codebase lane](/scan). If you have a live site, prefer the [URL lane](/snapshot-url). The PDF lane is best for the brand-book-handoff case. ## Run the snapshot From your terminal: ```bash preset snapshot --pdf brand-guidelines.pdf ``` Typical output: ``` ✓ Reading brand-guidelines.pdf and capturing tokens per page... ✓ Snapshot generated in 42,180ms Coherence score: 71 / 100 Colors: 14 primitives, 6 semantic roles Typography: 4 type styles Spacing: 6 distinct values ``` ### Flags | Flag | Default | What it does | | -- | -- | -- | | `--pdf ` | required | The PDF file to snapshot. | | `--output ` | stdout | Write the snapshot JSON or narrative to a file instead of stdout. | | `--format ` | `narrative` | `narrative` for a readable summary, `json` for the full snapshot. | | `--vision-model ` | `gemini-2.5-pro` | Vision model for the per-page inference. Same model set as the [image lane](#what-it-captures). | | `--threshold ` | `1` | Minimum usage count to keep a token. | | `--color-threshold ` | `0.005` | Cluster distance threshold (0-1). | | `-v, --verbose` | off | Print per-stage timing and observation counts. | The PDF lane is also available from the workspace dashboard at **Bootstrap → Source**. The same scanner runs server-side; you don't need a local pdfjs install for the dashboard flow. ## What the scanner captures The PDF lane runs two passes and merges them: 1. **Text mining.** The scanner extracts every text run, looks for `#RRGGBB` and `#RGB` literals, and walks the immediately-preceding words for a label. A run like "Cobalt, #1F47FF" gives a token named `cobalt` with exact value `#1F47FF`, surfaced as `pdfDeclaredNames` on the snapshot. Declared values are authoritative, they aren't re-inferred from pixels. 2. **Per-page vision.** Each page is rasterized at 144 DPI and passed through the image lane's vision-LLM + pixel-histogram pipeline. The model identifies palette, type styles, and spacing rhythm visible on the page. The pixel histogram grounds the LLM's color claims against actual page pixels. The two passes are merged field-by-field: text-declared tokens win on hex values; vision-inferred tokens fill in everything the text didn't claim. ### Page cap By default, the scanner processes the first 15 pages and stops. A typical brand book is 20-40 pages; the first 15 carry the brand-system content (palette, type, logo). Cover pages and voice/copy pages add no token signal. ### Vision-per-page cost Each page makes one LLM call. On Gemini 2.5 Flash that's ~$0.005 per page; on Gemini 2.5 Pro it's higher (the default favors quality over cost). For a 15-page PDF, expect ~$0.07 on Pro or ~$0.075 total on Flash. The CLI never sends pages to a model you didn't pick. ## What it cannot capture | Limitation | Why | Workaround | | -- | -- | -- | | Scanned/OCR-only PDFs | Text mining needs real text runs; OCR-on-rendering is unreliable | Use a vector-PDF source (export from Figma, Keynote, or InDesign) | | Encrypted PDFs | pdfjs can't read encrypted streams | Unlock the file before snapshotting | | Multi-PDF inputs | V1 processes one PDF per command | Run twice and merge by hand, or pick the canonical brand book | | Component identity | The scanner sees pages, not components | Use the [codebase lane](/scan) once the system has a codebase | | Animations, interactions | A PDF is a static document | Use the [URL lane](/snapshot-url) once there's a built product | ## Accuracy expectations The PDF lane mixes two signal qualities. Trust them differently: 1. **Text-declared hexes are exact.** If the PDF says `#1F47FF`, the snapshot value is `#1F47FF`. The label recovered from the surrounding words ("Cobalt", "Primary Blue") is also high-confidence: it's literally what the brand team wrote. 2. **Vision-inferred tokens carry the image lane's caveats.** Vision is good at "what palette is on this page" and "what type styles appear"; it's noisier on exact spacing values and unable to capture component identity. Treat vision-inferred values as starting points to confirm, not as ground truth. 3. **Coherence scores apply per-document, not across documents.** A 71/100 from one brand book isn't directly comparable to a 71/100 from another. The score reflects internal consistency of what the scanner observed, not absolute design-system maturity. For most brand-book bootstraps, the PDF lane gives you a workable starter system in ~30-60 seconds for a 15-page document. ## How the four lanes compare | | Codebase | URL | Image | PDF | | -- | -- | -- | -- | -- | | **Input** | Repo directory | `https://...` | PNG, JPG, or screenshot | `brand.pdf` | | **What it reads** | AST of components + token sources | Computed styles of every visible element | Pixels via vision LLM + histogram | Text-declared hexes + per-page vision | | **Symbolic names** | Direct from source | Recovered from stylesheets (best effort) | Inferred from labels in the image | Mined from text adjacent to hex literals | | **Component identity** | Yes | No | No | No | | **Coherence scores** | Source-level (truth) | Render-level (observation) | Inference-level (estimate) | Mixed (text exact, vision estimate) | | **Best for** | Your own product, deep audit | Reference products, agency onboarding | Brand decks, moodboards, single screens | Brand guidelines, agency client onboarding | | **Speed** | ~5s for a mid-size repo | 10-30s per page | 5-10s per image | ~30-60s for 15 pages | | **Cost** | Free | Free locally; Browserless quota on the dashboard | LLM tokens (~$0.001 per scan with Gemini Flash) | LLM tokens (~$0.005/page on Flash, hard cap at 15 pages) | ## What's next --- # Snapshot a URL Source: https://presetai.dev/docs/snapshot-url Type: guide Summary: Scan a live URL to extract its computed design tokens. Useful when there is no codebase to scan. Last updated: 2026-05-24 Related: Scan your repo (https://presetai.dev/docs/scan), Review what was extracted (https://presetai.dev/docs/extract) Install: preset snapshot --url https://example.com --- owner: jschuyler updated: '2026-06-20' status: stable --- export const metadata = { title: 'Snapshot a URL', description: 'Bootstrap a starter design system from a rendered web page. preset AI captures the computed-style fingerprint of any public URL and turns it into tokens you can refine.', type: 'guide', summary: 'Scan a live URL to extract its computed design tokens. Useful when there is no codebase to scan.', last_updated: '2026-05-24', related: ['/scan', '/extract'], install_command: 'preset snapshot --url https://example.com', } export const sections = [ { title: 'When to use the URL lane', id: 'when-to-use' }, { title: 'Run the snapshot', id: 'run-the-snapshot' }, { title: 'What the scanner captures', id: 'what-it-captures' }, { title: 'What it cannot capture', id: 'what-it-cannot-capture' }, { title: 'Accuracy expectations', id: 'accuracy-expectations' }, { title: 'robots.txt and the user agent', id: 'robots-and-ua' }, { title: 'How the three lanes compare', id: 'comparing-lanes' }, { title: "What's next", id: 'whats-next' }, ] # Snapshot a URL Point preset AI at a public URL. The scanner renders the page in headless Chromium, walks every visible element, and synthesizes a `DesignSystemSnapshot` you can refine into your own design system. Useful when you do not have a codebase to scan: agencies onboarding from a client's live product, brand teams capturing a launched site, designers extracting tokens from a reference. ## When to use the URL lane | You have | Pick | | -- | -- | | A repo with components and tokens in source | The [codebase lane](/scan) | | A live URL but no source access | The URL lane (this page) | | A brand-guidelines PDF | The [PDF lane](/snapshot-pdf) | | A screenshot or moodboard image | The image lane (see [comparison](#comparing-lanes)) | The four lanes produce the same shape of output. They differ in what signal they can reach. The URL lane is the only one that captures **rendered** values: what the browser actually paints, including resolved CSS variables, theme overrides, and runtime-computed styles. ## Run the snapshot From your terminal: ```bash preset snapshot --url https://stripe.com ``` The first run downloads Chromium via Playwright (~120MB, one-time). After that, a snapshot typically completes in 10-30 seconds depending on the page. Typical output: ``` ✓ Rendering stripe.com and capturing computed styles... ✓ Snapshot generated in 18,420ms (3,847 nodes visited) Coherence score: 67 / 100 Colors: 24 primitives, 8 semantic roles Typography: 6 type styles Spacing: 8 distinct values Components: 37 candidate patterns ``` ### Flags | Flag | Default | What it does | | -- | -- | -- | | `--url ` | required | The URL to snapshot. Must start with `http://` or `https://`. | | `--output ` | stdout | Write the snapshot JSON or narrative to a file instead of stdout. | | `--format ` | `narrative` | `narrative` for a readable summary, `json` for the full snapshot. | | `--threshold ` | `1` | Minimum usage count to keep a token. Filters out one-off observations. | | `--color-threshold ` | `0.005` | Cluster distance threshold (0-1). Lower = more granular palette. | | `--ignore-robots` | off | Skip the robots.txt pre-flight. Use only for sites you own. | | `-v, --verbose` | off | Print per-stage timing and observation counts. | The URL lane is also available from the workspace dashboard at **Bootstrap → Source**. The same scanner runs server-side via Browserless; you don't need a local Chromium for the dashboard flow. ## What the scanner captures For every visible element on the page, the scanner reads the computed-style values for these properties: - **Color**: `color`, `background-color`, the four `border-*-color` channels, plus SVG `fill` and `stroke` (filtered to elements actually inside an `` so unrelated nodes don't pollute the palette). - **Radius**: the four `border-*-radius` corners. - **Typography**: `font-family`, `font-size`, `font-weight`, `line-height`, `letter-spacing`. - **Spacing**: `padding-top/right/bottom/left`, `margin-top/right/bottom/left`, `gap`, `row-gap`, `column-gap`. - **Effects**: `box-shadow`. Each observation carries a **surface context**, element tag, parent tag, class list, ARIA role, position type, viewport coverage, which the surface-type classifier uses downstream to distinguish core-UI tokens from illustration, brand, marketing, and data-viz palettes. The primitive palette comes from core-UI observations only, so a brand wordmark or a chart's color scheme cannot accidentally become a primitive. ### Visibility filter Hidden elements are skipped. An element is visible if it has `display !== 'none'`, `visibility !== 'hidden'`, `opacity > 0`, and a non-zero bounding box. ### Scroll-and-wait After initial network-idle, the scanner scrolls the page in 200px increments (up to 6 seconds) to fire lazy-loaded content, then settles for 1.5s before sampling. Pages with heavy hero animations or `IntersectionObserver`-driven content reveal will still be captured. ### CSS-variable name recovery The scanner also reads every accessible stylesheet's source CSS and recovers symbolic variable names (`--brand-primary`, `--surface-bg`) so that a captured `rgb(99, 102, 241)` traces back to its declared name. Cross-origin stylesheets are fetched server-side. Sites that declare tokens on `:root` (shadcn/ui, most design-token codebases) get high recovery rates. ## What it cannot capture | Limitation | Why | Workaround | | -- | -- | -- | | Auth-gated pages | The scanner has no session cookies | Snapshot a public page on the same product, or use the codebase lane | | Content inside ` --- # Updating design systems Source: https://presetai.dev/docs/updating-design-systems Type: guide Summary: Re-scan a source you already imported; preset AI shows a diff of added, modified, and removed tokens before applying. Last updated: 2026-05-12 Prerequisites: Importing design systems (https://presetai.dev/docs/importing-design-systems) Related: Importing design systems (https://presetai.dev/docs/importing-design-systems) --- owner: jschuyler updated: '2026-05-12' status: stable --- export const metadata = { title: 'Updating design systems', description: 'Re-import to see exactly what changed before applying updates. Diff added, modified, and removed tokens before they land.', type: 'guide', summary: 'Re-scan a source you already imported; preset AI shows a diff of added, modified, and removed tokens before applying.', last_updated: '2026-05-12', prerequisites: ['/importing-design-systems'], related: ['/importing-design-systems'], } export const sections = [ { title: 'Overview', id: 'overview' }, { title: 'Updating from source', id: 'updating-from-source' }, { title: 'Understanding the diff', id: 'understanding-the-diff' }, { title: 'Resolving conflicts', id: 'resolving-conflicts' }, { title: 'Partial updates', id: 'partial-updates' }, { title: 'Best practices', id: 'best-practices' }, { title: 'Troubleshooting', id: 'troubleshooting' }, { title: 'FAQ', id: 'faq' }, ] # Updating design systems Keep your design system in sync with its source. When your team updates tokens, colors, or typography, re-import to see exactly what changed before applying. ## Overview Instead of blindly replacing tokens, preset AI shows you a diff of all changes: - **Added**: new tokens in the source - **Modified**: tokens with changed values - **Removed**: tokens no longer in the source - **Unchanged**: tokens that match exactly You choose which changes to apply. Local customizations are preserved. ## Updating from source 1. Go to **Design Systems** in the sidebar 2. Open the design system you want to update 3. Click **Update from Source** 4. Select your source (GitHub, GitLab, or upload) 5. Enter the same repository URL or upload an updated zip 6. Click **Scan for Changes** 7. Review the diff 8. Select changes to apply 9. Click **Apply Changes** ## Understanding the diff ### Summary view At the top you'll see a summary of all changes: ``` + 3 new tokens ~ 5 modified tokens - 2 removed tokens = 18 unchanged tokens ``` ### Added tokens Tokens that exist in the source but not in your design system. | Action | Result | |---|---| | **Include** (default) | Token will be added | | **Exclude** | Token will not be imported | ### Modified tokens Tokens that exist in both but with different values. | Action | Result | |---|---| | **Use source** | Update to the new value from source | | **Keep current** | Keep your existing value | | **Custom** | Enter a different value | Example: ``` primary Current: #3b82f6 Source: #2563eb ``` ### Removed tokens Tokens in your design system that no longer exist in the source. | Action | Result | |---|---| | **Remove** | Delete the token | | **Keep** (default) | Preserve the token | | **Deprecate** | Mark as deprecated but keep | preset AI warns you if a removed token is used by any presets: removing it may break those presets. ### Unchanged tokens Tokens with identical values in both. Collapsed by default since no action is needed. Click **Show unchanged** to expand the full list. ## Resolving conflicts A conflict occurs when a token has been modified both locally (in preset AI) and in the source: ``` Conflict: primary Original (at last import): #3b82f6 Your changes: #2563eb (darker) Source changes: #0ea5e9 (different hue) ``` ### Resolution options | Option | When to use | |---|---| | **Use source** | Source value should override your changes | | **Keep yours** | Your local modification should be preserved | | **Use custom value** | You want a different value than either | preset AI tracks the original imported value, so it can detect when both sides have changed. ## Partial updates You don't have to apply all changes at once. ### Accept only additions 1. Uncheck all modified and removed tokens 2. Keep all added tokens checked 3. Apply to get new tokens without affecting existing ones ### Review modifications individually 1. Expand each modified token 2. Compare current vs source values 3. Decide each one based on which value is correct ### Keep all local changes 1. Uncheck all changes 2. Cancel the update 3. Your design system remains unchanged ## Best practices ### Before updating - **Note your customizations**: if you've made local changes, write them down so you can make informed decisions during the diff review - **Check preset usage**: if removing tokens, check which presets use them first ### During review - **Review modified tokens carefully**: value changes can be subtle but important - **Check dark mode values**: a token might be unchanged in light mode but different in dark mode - **Read the change type**: "value" means the color changed; "both-modes" means light and dark both changed ### After updating - **Verify presets**: check that your presets still look correct with the new tokens - **Export if needed**: re-export your design system to update your codebase ## Troubleshooting ### "No changes detected" The source tokens are identical to your current design system. - Verify you're scanning the correct repository/branch - Check if the source was actually updated - Look at the "Unchanged" section to confirm tokens match ### "Conflict not detected" preset AI may not have recorded the original value at import time. - This typically only affects tokens imported before provenance tracking was added - Manually compare values and choose the correct one ### "Removed token is used by presets" You're about to remove a token that presets depend on. - Update the presets to use a different token first - Keep the token instead of removing it - Replace the token with an equivalent value ## FAQ ### Does updating overwrite my entire design system? No. Only the changes you select are applied. Unselected changes are ignored. ### Can I undo an update? There's no automatic undo. We recommend noting your current values before making significant changes. ### What if I want to reset to the source exactly? Select all added, modified, and removed tokens (including removals), then apply. Your design system matches the source exactly. ### How does preset AI know which tokens I modified locally? preset AI tracks "provenance": the original value at import time. When you edit a token, it compares against this original to detect local modifications. ### Can I update from a different source than I originally imported? Yes, but the diff will compare against your current tokens regardless of where they came from. This can result in more "added" and "removed" tokens than expected.