Skip to content

Design SOP

Role: Designer
Prerequisites: Complete the Meta SOP first
Visual reference: Whimsical Flowchart

You are a code-first designer. You work directly in the codebase, not in Figma. You own Storybook, you own the visual quality of the app, and you fix what you see broken every day. No tickets required to make the app better. No Figma before you've tried Claude. When PM creates a FE PR, you pull the branch locally and refine the UI/UX in code — making the feedback loop drastically faster than any design-to-handoff workflow.


The Figma Rule

Say it out loud before you open Figma:

"Have I genuinely tried to build this with Claude and hit a wall?"

If no — close Figma, open Cursor.
If yes, and it's a net-new component that doesn't exist in Storybook — open Figma, build the spec, add it to Storybook.

The only other exception: you can't achieve the result in Cursor and it's faster to mock it up in Figma and screenshot it in as a reference. That's fine — but the goal is still to build the real thing in code, not to create a Figma deliverable.

Figma is for new Storybook components only. Not for feature flows. Not for redesigns. Not for handoff documents. The component gets built once, lives in Storybook, and is used from there forever.

Figma-to-Code plugin: If you've designed a component in Figma, use the Figma-to-Code plugin to export React code. Paste that code into Cursor as a reference — the agent will use it as a starting point. This is faster than describing the component in text.


Design Power Stack

These four tools form the design-to-code pipeline. All are used through Cursor (set up per Meta SOP prerequisites).

flowchart TD
  Stitch["Stitch — generate screens (Cursor MCP)"] --> NanoBanana["Nano Banana — refine visual mockups (Cursor skill / CLI)"]
  NanoBanana --> ProMax["UI/UX Pro Max — generate design system (Cursor skill)"]
  ProMax --> TwentyFirst["21st.dev — pull production components (Cursor MCP)"]
  TwentyFirst --> Cursor["Cursor assembles everything"]

Stitch — generate full UI screens from text:

  • "Generate a dashboard screen for a SaaS analytics product with dark theme and glassmorphism"
  • "Extract the design context from that screen"
  • "Fetch the HTML code and adapt it to our React/Tailwind stack"

Nano Banana — generate high-fidelity mockups:

  • "Generate a mockup of a dashboard with dark theme and data visualizations"
  • Supports -s 2K/4K for resolution, -a 16:9 for aspect ratio, -r existing-screen.png for style transfer, -t for transparent backgrounds

UI/UX Pro Max — design intelligence (activates automatically on design requests):

  • Can also be queried directly: python3 .cursor/skills/ui-ux-pro-max/scripts/search.py "B2B SaaS" --design-system -p "CRED"

21st.dev — pull pre-built components:

  • Prefix with /ui in Cursor chat or just describe what you need

Cursor Design Mode

Toggle in the bottom-right corner of Cursor (first icon from the right). This is the Figma-like experience inside Cursor — use it for visual refinement instead of opening Figma.

  1. Select any component to see its style properties
  2. Tweak visually: border color, line height, spacing, colors
  3. Click Apply to generate a prompt and apply changes
  4. Say "apply this to all components that use this" to cascade changes across the codebase

Component Rules

These rules apply to all front-end work. Add them to your Cursor rules (see Meta SOP).

  • Always use exact ShadCN component names (e.g., "InputGroup", "Badge", "Accordion") — not "input box" or "dropdown". Reference component.gallery for correct names.
  • Always use only existing Storybook components. If one doesn't exist, flag it — do not create one-off styled components.
  • Use design token names in prompts (e.g., "use accent-foreground for the text color", "use popover-background") — not color descriptions. If a token is missing from CSS, add it.
  • When restyling an existing component, keep all event logic. Only change the visual styling — do not replace the component with a ShadCN primitive, as this will break event bindings. Add this to your prompts: "retain all existing event logic and only change the styling."
  • If Cursor uses the wrong component or invents one, screenshot the correct component from Figma or Storybook and paste it into the Cursor chat as a visual reference.

Design System Cursor Rules

You (Design team) are responsible for writing and maintaining the natural language design system description as a Cursor rule. This rule should be shared in the design channel so the whole team adds it. Include patterns like:

  • "Use sidebar panels for all action/input flows"
  • "Use tab bars for sub-views within a page"
  • "Radio buttons for single-select, checkboxes for multi-select"
  • "Use the existing breadcrumb component for navigation hierarchy"

Track 1 — Daily App Improvement

Every day, use the live app as a real user. Fix what you find broken, awkward, or visually inconsistent. No ticket. No approval. Just fix it and send a PR to Tom.

The Workflow

  1. Open the app and use it properly — navigate as a customer would. Look for:

    • Spacing and alignment inconsistencies
    • Copy that's confusing, wrong, or off-brand
    • Components used in the wrong context
    • Missing or broken loading, empty, or error states
    • Flows that are harder to navigate than they should be
    • Responsiveness issues at standard breakpoints
  2. Branch off develop — one branch per fix:

git checkout develop
git pull
git checkout -b design/fix-[brief-description]
  1. Open Cursor with web-commercial in the workspace and fix the issue:
Plan a fix for the following visual/usability issue in web-commercial: 
[describe]

Use only existing Storybook components. Follow the existing 
design system patterns in this codebase.
Show me the plan before writing any code.

Review the plan, then tell Cursor to implement it.

  1. Test locally — use Google Chrome with code and localhost windows side by side for fastest iteration. If you're restyling something that already works, you must test that it still works — click through the flow, confirm events fire, check edge cases. You are a developer. New UI with no APIs just needs a visual check. Not seeing changes? Open an incognito tab — cache is almost always the issue.

  2. Wait for regression tests to pass (Rainforest QA green)

  3. Manually verify the fix — walk through the affected flow end-to-end and confirm the original issue is resolved without breaking anything nearby

  4. To update an existing PR with new changes, just tell Cursor: "commit these changes." It will push to the same branch and update the PR. You do not need to create a new PR for every change.

  5. Open a PR:

    • Title: [Design] Fix [brief description]
    • Description: one or two sentences — what was wrong and what you changed
  6. Merge once tests pass and you've verified it works

  7. Create a Linear ticket after the fact to record what you fixed:

Using the Linear MCP, create a ticket for the design fix I just merged.

Title: [Design] [brief description]
Description: [what was wrong and what was changed]
Status: Done
Link the PR: [PR URL]

In most cases you fix first, ticket after — the work is already done, the ticket is just the record.

What's Fair Game Without a Ticket

  • Visual inconsistencies (spacing, alignment, colour, typography)
  • Confusing, inconsistent, or incorrect copy
  • Components used in the wrong context
  • Missing or broken loading, empty, or error states
  • Unnecessarily confusing navigation
  • Responsiveness issues at standard breakpoints (mobile, tablet, desktop)

What Needs a Conversation with Tom First

  • Changes to how a core user flow fundamentally works
  • Removing or significantly restructuring existing functionality
  • Anything that affects data or API behaviour
  • Net-new pages or features (go through the PM PR process instead)

Separate PRs for Component Fixes

If you notice a UI component needs fixing while working on a feature, create a separate PR for the component fix. Do not bundle fixes with feature work. After merging the fix, tell Cursor to create a Linear ticket for the fix and mark it as completed.


Data-Driven Design Improvements

Use customer data to guide proactive usability improvements. Ask Tom for access to: automated transcript analysis, closed/lost deal reasons, customer complaints and frustrations. Chat with this data in Claude first — ask it to identify UX pain points and suggest improvements. Then implement the best ideas in Cursor.


Track 2 — FE Refinement on Feature PRs

When PM asks, you are responsible for making their FE PRs more beautiful, polished, and consistent with the design system. PM builds the initial scaffolding — your job is to elevate the UI and UX before the engineer locks in the back-end around it.

The Workflow

  1. Pull the branch:
git checkout [branch name]
git pull
  1. Open Cursor with all five repos in the workspace

  2. Walk through the user journey first — before changing anything, understand what PM was trying to achieve. If it's unclear, Slack PM before making structural changes.

  3. Plan improvements in Claude first — let Claude suggest UX improvements and research competitor patterns:

I'm refining the UX and UI for [feature name]. Here's what 
the current flow looks like: [describe the current state].

First, research how competitors handle this type of feature — 
what UX patterns work well in similar B2B SaaS products?

Then suggest improvements to the layout, flow, and visual 
consistency. Focus on user experience, not technical implementation.

Review Claude's suggestions. Use them to inform what you change in Cursor.

  1. Refine with Cursor:
Plan improvements to the UX and UI for [feature name] in 
web-commercial on this branch. Specifically:

- [e.g. The empty state is missing — add one using the existing empty state component]
- [e.g. The spacing between the table rows and the header is inconsistent with the rest of the app]
- [e.g. The flow jumps from step 1 directly to step 3 — add a confirmation step]

Use only existing Storybook components. Follow design system patterns.
Show me the plan before writing any code.

Review the plan, then tell Cursor to implement it.

  1. Test locally — walk the full user journey including edge cases (empty states, error states, mobile viewport)

  2. Push the branch and hand to the Engineer:

git push origin [branch name]

Slack the engineer: brief summary of what you changed and why, and anything you flagged but didn't fix (so they know what to watch for on the BE side).

Present via localhost: Design presentations and reviews are done via localhost, not Figma. Run your branch locally and walk through the live UI during review calls.

Review transcripts: Before refining a PR, check if there are design session transcripts relevant to the feature. Use them for context on intent and decisions made.

What You Do and Don't Own Here

You own: the UX flow, component choices, visual consistency, copy, loading/empty/error states, responsiveness.

You do not own: whether the feature is the right thing to build (that's PM), or how the back-end is wired (that's Engineering). If you have concerns about either, raise them — but don't block the PR over them.


Feature Flagging Before Merge

Before merging any FE work where APIs are not yet hooked up:

  1. Feature flag all non-working UI elements — provide PostHog documentation to the agent and ask it to add a feature flag
  2. Also add PostHog analytics events to every interactive element in the same PR (same piece of work)
  3. Merge to develop, then go to PostHog and toggle the flag off
  4. Reload dev and verify the flagged elements are hidden
  5. If you cannot feature flag a change (e.g., entire layout restructure with no discrete toggleable elements), keep it as an open PR — do not merge. Message Tom first.
  6. Feature flags are temporary — once APIs are wired and it works, remove the flag from code and delete from PostHog

Always merge to develop. Long-lived branches diverge and cause conflicts. The only exception is when a change fundamentally restructures a layout and cannot be feature-flagged — in that case, keep it as an open PR.


Storybook Ownership

You are responsible for Storybook staying accurate and useful.

Storybook documentation lives as markdown in the repo (versioned with Git, not a separate wiki). Components must be labeled with clear, descriptive names that match what the AI would search for (e.g., "InputGroup" not "TextBox1"). Coordinate with Misha on what was already migrated from the ShadCN migration.

Expose Storybook as a website for the team to visually browse and screenshot from. When Cursor invents a component, check if it should be in Storybook — if so, add it.

Ensure all Figma design tokens (color variables like caution-foreground, accent-foreground, popover-background) are defined in the project CSS/Tailwind config so Cursor can reference them by name.

When a net-new component is genuinely needed:

  1. Try to build it with Claude in Cursor first — iterate until it's right or you've hit a genuine wall
  2. If Claude can't achieve it: open Figma, design the component spec
  3. Build the component and add it to Storybook
  4. The component lives in Storybook from now on — everyone uses it from there

Never build one-off styled components in web-commercial directly. If you see one that someone else built: move it to Storybook and replace the one-off with the Storybook component.


Troubleshooting

Problem Fix
Not sure if a change needs a ticket Visual or usability fix: branch and fix it. Changes how a feature fundamentally works: Slack Tom first.
Claude can't achieve the component Document what you tried, open Figma, design the spec, add it to Storybook.
Build errors, conflicts, or code review comments Ask Cursor: "Resolve all build errors, merge conflicts, and code review comments on this PR." Do not fix manually.
Not sure which Storybook component to use Ask Cursor: "What is the correct Storybook component to use for [describe use case] in this codebase?"
Not seeing changes on localhost Open an incognito tab — browser cache is almost always the issue. Use Google Chrome with code and localhost windows side by side for ~5x faster iteration.
Cursor uses the wrong component or invents one Screenshot the correct component from Figma or Storybook and paste it into the Cursor chat as a visual reference. Use exact ShadCN component names.