seedflip
Archive
Mixtapes
Pricing
Sign in

Windsurf + Design Tokens: Keeping Your AI Agent On-Brand

Your Windsurf agent keeps generating UI that looks slightly different every time. The button was violet yesterday and blue today. The card radius changed between files. You're not imagining it. Without explicit design constraints in your .windsurfrules, Windsurf makes new aesthetic decisions on every generation. Here's how to lock it down.

Get design tokens for Windsurf →

Why your agent drifts

Windsurf is context-aware. It reads your files, understands your project structure, and tries to match existing patterns. But "matching existing patterns" only works when those patterns are consistent in the first place. If your codebase has three different shades of gray across ten components (because the AI picked slightly different values each time), Windsurf will dutifully match one of them. Which one? It depends on which files are in context that day.

This is the design drift problem. It's not a bug. It's the absence of design constraints. You suspected your AI was going off-brand. You were right. But it's going off-brand because you never told it what "on-brand" means in concrete terms.

The .windsurfrules file

Windsurf supports a .windsurfrules file at your project root. It functions like a persistent system prompt. Everything in this file shapes how Windsurf generates and modifies code. Most tutorials show it used for coding conventions. We're using it for design.

# .windsurfrules ## Design System This project uses a strict design token system. All UI code must reference these tokens. No exceptions. ### Color Palette - --background: #FAFAF9 (page background) - --surface: #FFFFFF (card/panel background) - --text-primary: #1C1917 (headings, important text) - --text-secondary: #78716C (body text, descriptions) - --text-tertiary: #A8A29E (placeholders, hints) - --border: #E7E5E4 (dividers, card borders) - --accent: #EA580C (buttons, links, active states) - --accent-hover: #C2410C (hover state for accent) - --destructive: #DC2626 (error states, delete actions) ### Typography - Headings: "Plus Jakarta Sans", weight 600-700 - Body: "Inter", weight 400-500 - Mono: "JetBrains Mono" ### Spacing & Shape - Border radius: 12px (cards), 8px (buttons/inputs) - Card padding: 24px - Section gap: 32px - Component gap: 12px ### Rules - NEVER use arbitrary hex values outside this palette - NEVER change font families - ALWAYS use CSS variables for colors, not Tailwind defaults - Shadows: shadow-sm only. No shadow-md, shadow-lg.

Every value is explicit. Every constraint is stated in the negative ("NEVER use arbitrary hex values"). This is what "on-brand" looks like to an AI agent: a list of decisions that have already been made.

Windsurf's cascade system

Windsurf supports a cascade of rules files, which gives you layered control over design constraints. You can have global rules, project rules, and even directory-specific rules.

# Global: ~/.windsurfrules (applies to all projects) - Prefer CSS variables over Tailwind color classes - Always use semantic color names (--text-primary, not --gray-900) # Project: .windsurfrules (project root) - Full design token set (colors, fonts, spacing) - Component-specific patterns # Directory: src/components/.windsurfrules - Component composition rules - Import patterns for this directory

The cascade means your global preferences (like "always use CSS variables") apply everywhere, while project-specific tokens override for individual codebases. This is particularly useful if you work across multiple projects with different brands.

Structuring tokens for maximum compliance

Through testing, we've found specific patterns that make Windsurf follow design tokens more reliably.

Name the role, not the color

--accent: #EA580C is better than --orange: #EA580C. When you use role-based names, Windsurf understands when to apply them. It knows "accent" goes on interactive elements. It doesn't know when "orange" is appropriate versus when it should use "blue."

Include the usage context

Don't just list the token. Explain where it goes.

# Good: context included - --surface: #FFFFFF (card backgrounds, modal backgrounds, dropdown panels) - --border: #E7E5E4 (card borders, input borders, divider lines) # Bad: just the value - --surface: #FFFFFF - --border: #E7E5E4

The parenthetical context gives Windsurf clear guidance on which token to pick for a given UI element. Without it, the agent guesses.

Define the forbidden list

Negative constraints are more powerful than positive ones for AI agents. A list of "never do this" closes escape hatches that "always do this" leaves open.

# Forbidden patterns - Never use bg-gray-*, bg-slate-*, bg-zinc-* Tailwind classes - Never use text-gray-*, text-slate-* Tailwind classes - Never hardcode hex values in className strings - Never add new color variables without explicit approval - Never use box-shadow utilities other than shadow-sm

Getting your design tokens

The hardest part of this process is not configuring Windsurf. It's having a design system to configure it with. Most solo developers and small teams don't have a design file with exported tokens. They have a rough idea of their brand colors and a Tailwind config they've been meaning to clean up.

SeedFlip solves this by giving you a complete, curated design system in one step. Each seed includes colors, fonts, spacing, shadows, and radius values that work together as a cohesive system. You can export them as CSS variables and paste them directly into .windsurfrules.

# SeedFlip MCP query from within Windsurf > get_design_seed({ query: "warm editorial light theme", format: "css" }) # Returns ready-to-use CSS variables :root { --background: #FAFAF9; --surface: #FFFFFF; --text-primary: #1C1917; --text-secondary: #78716C; --accent: #EA580C; --border: #E7E5E4; --radius: 12px; --shadow: 0 1px 3px rgba(0,0,0,0.08); }

Copy the output into your .windsurfrules, add the usage context and forbidden patterns from the sections above, and you have a complete design constraint system. Ten minutes of setup. Permanent consistency.

Testing your constraints

After setting up .windsurfrules, test it by asking Windsurf to build something from scratch:

"Build a user profile card with avatar, name, email, role badge, and an edit button."

Check the output against your tokens. Are the colors right? Is the font stack correct? Did it use your border-radius values? If anything is off, tighten the relevant constraint in .windsurfrules. The goal is zero manual correction on the first generation.


Design drift is not inevitable. It's the result of missing constraints. Your .windsurfrules file is where those constraints live. Define your tokens, state your forbidden patterns, and Windsurf stops guessing. For more on design tokens across AI coding tools, read Design Variables That Actually Matter. For the broader AI design system strategy, see Design Systems for Cursor, Claude, and Windsurf.

Ready to stop guessing?

One flip. Complete design system. Free CSS export.

Get design tokens for Windsurf →