Last active
April 2, 2026 16:16
-
-
Save jessicaldale/0239b2a114e4c7e5d16040c41d5d89eb to your computer and use it in GitHub Desktop.
Prototyping with Cursor at Gusto - workflow, rules, and tools explainer for designers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Prototyping with Cursor at Gusto</title> | |
| <style> | |
| :root { | |
| --teal: #0A8080; | |
| --teal-light: #E6F5F5; | |
| --teal-mid: #B2DFDF; | |
| --navy: #1F2937; | |
| --gray-50: #F9FAFB; | |
| --gray-100: #F3F4F6; | |
| --gray-200: #E5E7EB; | |
| --gray-300: #D1D5DB; | |
| --gray-500: #6B7280; | |
| --gray-700: #374151; | |
| --gray-900: #111827; | |
| --green: #059669; | |
| --green-light: #ECFDF5; | |
| --amber: #D97706; | |
| --amber-light: #FFFBEB; | |
| --red: #DC2626; | |
| --red-light: #FEF2F2; | |
| --purple: #7C3AED; | |
| --purple-light: #F5F3FF; | |
| --radius: 12px; | |
| --shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06); | |
| --shadow-lg: 0 4px 12px rgba(0,0,0,0.1); | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| color: var(--gray-900); | |
| line-height: 1.6; | |
| background: #fff; | |
| } | |
| nav { | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| background: rgba(255,255,255,0.95); | |
| backdrop-filter: blur(8px); | |
| border-bottom: 1px solid var(--gray-200); | |
| padding: 0 2rem; | |
| } | |
| nav ul { | |
| display: flex; | |
| gap: 0.25rem; | |
| list-style: none; | |
| max-width: 1100px; | |
| margin: 0 auto; | |
| overflow-x: auto; | |
| } | |
| nav a { | |
| display: block; | |
| padding: 0.75rem 0.75rem; | |
| color: var(--gray-500); | |
| text-decoration: none; | |
| font-size: 0.85rem; | |
| font-weight: 500; | |
| white-space: nowrap; | |
| border-bottom: 2px solid transparent; | |
| transition: color 0.2s, border-color 0.2s; | |
| } | |
| nav a:hover, nav a.active { | |
| color: var(--teal); | |
| border-bottom-color: var(--teal); | |
| } | |
| .container { max-width: 1100px; margin: 0 auto; padding: 0 2rem; } | |
| section { padding: 4rem 0; } | |
| section + section { border-top: 1px solid var(--gray-200); } | |
| h1 { font-size: 2.5rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; } | |
| h2 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 1rem; } | |
| h3 { font-size: 1.15rem; font-weight: 600; margin-bottom: 0.5rem; } | |
| p { color: var(--gray-700); max-width: 680px; } | |
| p + p { margin-top: 1rem; } | |
| .subtitle { | |
| font-size: 1.15rem; | |
| color: var(--gray-500); | |
| margin-top: 0.75rem; | |
| max-width: 600px; | |
| } | |
| .hero { | |
| padding: 5rem 0 4rem; | |
| border-bottom: 1px solid var(--gray-200); | |
| } | |
| .hero-badge { | |
| display: inline-block; | |
| background: var(--teal-light); | |
| color: var(--teal); | |
| font-size: 0.8rem; | |
| font-weight: 600; | |
| padding: 0.3rem 0.75rem; | |
| border-radius: 100px; | |
| margin-bottom: 1.25rem; | |
| } | |
| .flow { | |
| display: flex; | |
| align-items: stretch; | |
| gap: 0; | |
| margin: 2rem 0; | |
| flex-wrap: wrap; | |
| } | |
| .flow-step { | |
| flex: 1; | |
| min-width: 200px; | |
| padding: 1.5rem; | |
| text-align: center; | |
| position: relative; | |
| border: 1px solid var(--gray-200); | |
| background: var(--gray-50); | |
| } | |
| .flow-step:first-child { border-radius: var(--radius) 0 0 var(--radius); } | |
| .flow-step:last-child { border-radius: 0 var(--radius) var(--radius) 0; } | |
| .flow-step:not(:last-child)::after { | |
| content: ''; | |
| position: absolute; | |
| right: -10px; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| width: 0; height: 0; | |
| border: 10px solid transparent; | |
| border-left-color: var(--gray-200); | |
| z-index: 2; | |
| } | |
| .flow-step:not(:last-child)::before { | |
| content: ''; | |
| position: absolute; | |
| right: -9px; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| width: 0; height: 0; | |
| border: 10px solid transparent; | |
| border-left-color: var(--gray-50); | |
| z-index: 3; | |
| } | |
| .flow-num { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 28px; height: 28px; | |
| border-radius: 50%; | |
| background: var(--teal); | |
| color: #fff; | |
| font-size: 0.8rem; | |
| font-weight: 700; | |
| margin-bottom: 0.5rem; | |
| } | |
| .flow-label { font-weight: 600; font-size: 0.95rem; margin-bottom: 0.25rem; } | |
| .flow-desc { font-size: 0.8rem; color: var(--gray-500); } | |
| .card-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); | |
| gap: 1rem; | |
| margin-top: 1.5rem; | |
| } | |
| .card { | |
| border: 1px solid var(--gray-200); | |
| border-radius: var(--radius); | |
| padding: 1.5rem; | |
| background: #fff; | |
| transition: box-shadow 0.2s; | |
| } | |
| .card:hover { box-shadow: var(--shadow-lg); } | |
| .card-tag { | |
| display: inline-block; | |
| font-size: 0.7rem; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.05em; | |
| padding: 0.2rem 0.5rem; | |
| border-radius: 4px; | |
| margin-bottom: 0.75rem; | |
| } | |
| .tag-rule { background: var(--teal-light); color: var(--teal); } | |
| .tag-skill { background: var(--purple-light); color: var(--purple); } | |
| .tag-artifact { background: var(--amber-light); color: var(--amber); } | |
| .card p { font-size: 0.9rem; margin-top: 0.5rem; } | |
| .card-key { | |
| margin-top: 0.75rem; | |
| padding-top: 0.75rem; | |
| border-top: 1px solid var(--gray-100); | |
| font-size: 0.85rem; | |
| color: var(--gray-500); | |
| } | |
| .card-key strong { color: var(--gray-700); } | |
| .compare { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin-top: 1.5rem; | |
| font-size: 0.9rem; | |
| } | |
| .compare th { | |
| text-align: left; | |
| padding: 0.75rem 1rem; | |
| background: var(--gray-50); | |
| border: 1px solid var(--gray-200); | |
| font-weight: 600; | |
| } | |
| .compare td { | |
| padding: 0.75rem 1rem; | |
| border: 1px solid var(--gray-200); | |
| color: var(--gray-700); | |
| } | |
| .compare tr:hover td { background: var(--gray-50); } | |
| .diff-table { margin-top: 1.5rem; } | |
| .diff-row { | |
| display: grid; | |
| grid-template-columns: 140px 1fr 1fr; | |
| border-bottom: 1px solid var(--gray-200); | |
| } | |
| .diff-row:first-child { | |
| background: var(--gray-50); | |
| font-weight: 600; | |
| font-size: 0.8rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.03em; | |
| color: var(--gray-500); | |
| } | |
| .diff-cell { padding: 0.75rem 1rem; font-size: 0.9rem; } | |
| .code-block { | |
| background: var(--gray-900); | |
| color: #E5E7EB; | |
| border-radius: 8px; | |
| padding: 1.25rem 1.5rem; | |
| font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace; | |
| font-size: 0.85rem; | |
| line-height: 1.7; | |
| overflow-x: auto; | |
| margin-top: 1rem; | |
| } | |
| .code-comment { color: var(--gray-500); } | |
| .code-keyword { color: #C084FC; } | |
| .code-string { color: #6EE7B7; } | |
| .code-component { color: #67E8F9; } | |
| details { margin-top: 1rem; } | |
| summary { | |
| cursor: pointer; | |
| font-weight: 600; | |
| font-size: 0.95rem; | |
| color: var(--teal); | |
| padding: 0.75rem 0; | |
| list-style: none; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| summary::before { | |
| content: '+'; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 22px; height: 22px; | |
| border-radius: 50%; | |
| background: var(--teal-light); | |
| color: var(--teal); | |
| font-size: 0.9rem; | |
| font-weight: 700; | |
| flex-shrink: 0; | |
| transition: transform 0.2s; | |
| } | |
| details[open] > summary::before { content: '\2212'; } | |
| summary::-webkit-details-marker { display: none; } | |
| details .detail-content { | |
| padding: 0 0 1rem 2rem; | |
| color: var(--gray-700); | |
| font-size: 0.9rem; | |
| } | |
| details .detail-content p { margin-bottom: 0.75rem; } | |
| .cheat { | |
| display: grid; | |
| grid-template-columns: 1fr auto 1fr; | |
| gap: 0; | |
| margin-top: 1.5rem; | |
| border: 1px solid var(--gray-200); | |
| border-radius: var(--radius); | |
| overflow: hidden; | |
| } | |
| .cheat-row { display: contents; } | |
| .cheat-row:hover > * { background: var(--gray-50); } | |
| .cheat-say, .cheat-do { | |
| padding: 1rem 1.25rem; | |
| font-size: 0.9rem; | |
| border-bottom: 1px solid var(--gray-200); | |
| } | |
| .cheat-say { | |
| font-family: 'SF Mono', 'Fira Code', monospace; | |
| font-size: 0.85rem; | |
| color: var(--teal); | |
| } | |
| .cheat-arrow { | |
| padding: 1rem 0.5rem; | |
| color: var(--gray-300); | |
| font-size: 1.2rem; | |
| border-bottom: 1px solid var(--gray-200); | |
| text-align: center; | |
| } | |
| .cheat-do { color: var(--gray-700); } | |
| .cheat-header > * { | |
| background: var(--gray-50); | |
| font-weight: 600; | |
| font-size: 0.8rem; | |
| text-transform: uppercase; | |
| letter-spacing: 0.03em; | |
| color: var(--gray-500); | |
| padding: 0.6rem 1.25rem; | |
| border-bottom: 1px solid var(--gray-200); | |
| } | |
| .toolbar-mock { | |
| background: var(--navy); | |
| border-radius: 10px; | |
| padding: 0.5rem 1rem; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 0.75rem; | |
| margin-top: 1.5rem; | |
| box-shadow: var(--shadow-lg); | |
| font-family: 'SF Mono', 'Fira Code', monospace; | |
| font-size: 0.75rem; | |
| } | |
| .tb-label { color: #6B7280; } | |
| .tb-btn { | |
| padding: 0.3rem 0.65rem; | |
| border-radius: 6px; | |
| border: none; | |
| font-family: inherit; | |
| font-size: 0.75rem; | |
| cursor: default; | |
| } | |
| .tb-active { background: #F9FAFB; color: var(--gray-900); font-weight: 600; } | |
| .tb-inactive { background: transparent; color: #9CA3AF; } | |
| .tb-divider { width: 1px; height: 16px; background: #374151; } | |
| .tb-persona { color: #93C5FD; background: #1E3A5F; padding: 0.3rem 0.65rem; border-radius: 6px; } | |
| .tb-qa { color: #C4B5FD; } | |
| .callout { | |
| background: var(--teal-light); | |
| border-left: 3px solid var(--teal); | |
| border-radius: 0 8px 8px 0; | |
| padding: 1rem 1.25rem; | |
| margin-top: 1.5rem; | |
| font-size: 0.9rem; | |
| color: var(--gray-700); | |
| } | |
| .callout strong { color: var(--teal); } | |
| .badge { | |
| display: inline-block; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| padding: 0.15rem 0.45rem; | |
| border-radius: 4px; | |
| vertical-align: middle; | |
| } | |
| .badge-auto { background: var(--teal-light); color: var(--teal); } | |
| .badge-manual { background: var(--purple-light); color: var(--purple); } | |
| .steps { margin-top: 1.5rem; } | |
| .step { | |
| display: flex; | |
| gap: 1rem; | |
| padding: 1rem 0; | |
| } | |
| .step + .step { border-top: 1px solid var(--gray-100); } | |
| .step-num { | |
| flex-shrink: 0; | |
| width: 32px; height: 32px; | |
| border-radius: 50%; | |
| background: var(--teal); | |
| color: #fff; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 700; | |
| font-size: 0.85rem; | |
| } | |
| .step-body h3 { margin-bottom: 0.25rem; } | |
| .step-body p { font-size: 0.9rem; } | |
| .two-col { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 1rem; | |
| margin-top: 1.5rem; | |
| } | |
| footer { | |
| text-align: center; | |
| padding: 3rem 2rem; | |
| color: var(--gray-500); | |
| font-size: 0.85rem; | |
| border-top: 1px solid var(--gray-200); | |
| } | |
| @media (max-width: 768px) { | |
| h1 { font-size: 1.75rem; } | |
| .flow { flex-direction: column; } | |
| .flow-step { border-radius: var(--radius) !important; } | |
| .flow-step::after, .flow-step::before { display: none !important; } | |
| .card-grid { grid-template-columns: 1fr; } | |
| .cheat { grid-template-columns: 1fr; } | |
| .cheat-arrow { display: none; } | |
| .diff-row { grid-template-columns: 1fr 1fr; } | |
| .diff-row .diff-cell:first-child { grid-column: 1 / -1; font-weight: 600; padding-bottom: 0; } | |
| .two-col { grid-template-columns: 1fr; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <nav> | |
| <ul> | |
| <li><a href="#big-picture">Big Picture</a></li> | |
| <li><a href="#getting-started">Getting Started</a></li> | |
| <li><a href="#how-ai-knows">How the AI Knows</a></li> | |
| <li><a href="#how-to-build">How to Build</a></li> | |
| <li><a href="#before-after">Before / After</a></li> | |
| <li><a href="#evaluate">Evaluate</a></li> | |
| <li><a href="#tools-compared">Tools Compared</a></li> | |
| <li><a href="#cheat-sheet">Cheat Sheet</a></li> | |
| </ul> | |
| </nav> | |
| <div class="hero"> | |
| <div class="container"> | |
| <span class="hero-badge">Gusto Design Prototyping</span> | |
| <h1>Prototyping with Cursor</h1> | |
| <p class="subtitle">A guide to the rules, tools, and workflow that power AI-assisted prototyping in the Gusto Sandbox.</p> | |
| </div> | |
| </div> | |
| <section id="big-picture"> | |
| <div class="container"> | |
| <h2>The Big Picture</h2> | |
| <p>Every prototype follows the same lifecycle. Rules and tools support each stage automatically.</p> | |
| <div class="flow"> | |
| <div class="flow-step"> | |
| <div class="flow-num">1</div> | |
| <div class="flow-label">Write Stories</div> | |
| <div class="flow-desc">Define what the user should experience using acceptance criteria</div> | |
| </div> | |
| <div class="flow-step"> | |
| <div class="flow-num">2</div> | |
| <div class="flow-label">Build</div> | |
| <div class="flow-desc">Cursor writes code using Workbench components, guided by your rules</div> | |
| </div> | |
| <div class="flow-step"> | |
| <div class="flow-num">3</div> | |
| <div class="flow-label">Review</div> | |
| <div class="flow-desc">Evaluate quality with design review, UX checklist, or both</div> | |
| </div> | |
| <div class="flow-step"> | |
| <div class="flow-num">4</div> | |
| <div class="flow-label">Ship or Iterate</div> | |
| <div class="flow-desc">Fix findings in batched PRs, re-evaluate, then share</div> | |
| </div> | |
| </div> | |
| <div class="callout"> | |
| <strong>Two kinds of tools:</strong> | |
| <strong>Rules</strong> fire automatically every time you edit code — you don’t need to remember them. | |
| <strong>Skills</strong> are commands you run on demand when you need a specific evaluation or generator. | |
| </div> | |
| </div> | |
| </section> | |
| <section id="getting-started"> | |
| <div class="container"> | |
| <h2>Getting Started</h2> | |
| <p>The Gusto Sandbox is a safe prototyping environment. It looks and feels like the real Gusto app, but nothing you build here touches production.</p> | |
| <div class="diff-table"> | |
| <div class="diff-row"> | |
| <div class="diff-cell"></div> | |
| <div class="diff-cell">Production</div> | |
| <div class="diff-cell">Sandbox</div> | |
| </div> | |
| <div class="diff-row"> | |
| <div class="diff-cell"><strong>Data</strong></div> | |
| <div class="diff-cell">Real APIs & GraphQL</div> | |
| <div class="diff-cell">Mock data you define</div> | |
| </div> | |
| <div class="diff-row"> | |
| <div class="diff-cell"><strong>Auth</strong></div> | |
| <div class="diff-cell">Real login required</div> | |
| <div class="diff-cell">Assume logged in</div> | |
| </div> | |
| <div class="diff-row"> | |
| <div class="diff-cell"><strong>Analytics</strong></div> | |
| <div class="diff-cell">Track events</div> | |
| <div class="diff-cell">Skip tracking</div> | |
| </div> | |
| <div class="diff-row"> | |
| <div class="diff-cell"><strong>Errors</strong></div> | |
| <div class="diff-cell">Full error handling</div> | |
| <div class="diff-cell">Basic or none</div> | |
| </div> | |
| <div class="diff-row"> | |
| <div class="diff-cell"><strong>Testing</strong></div> | |
| <div class="diff-cell">Required</div> | |
| <div class="diff-cell">TDD when building</div> | |
| </div> | |
| </div> | |
| <h3 style="margin-top: 2rem;">Creating a prototype</h3> | |
| <p>Tell Cursor where you want your prototype to live in the app’s navigation. It creates the folder and files for you. Routes are auto-discovered — no wiring needed.</p> | |
| <div class="code-block"> | |
| <span class="code-comment">// Your prototype lives here:</span><br> | |
| src/apps/gusto/prototypes/<span class="code-string">your-prototype</span>/page.tsx<br><br> | |
| <span class="code-comment">// Run the sandbox:</span><br> | |
| cd apps/gusto-sandbox && yarn dev<br><br> | |
| <span class="code-comment">// Open in browser:</span><br> | |
| http://localhost:3000/<span class="code-string">your-prototype</span> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="how-ai-knows"> | |
| <div class="container"> | |
| <h2>How the AI Knows What to Do</h2> | |
| <p>Seven rules run automatically every time you chat with Cursor. You don’t need to remember them — they’re always on.</p> | |
| <div class="card-grid"> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · Always On</span> | |
| <h3>Context Refresh</h3> | |
| <p>Every new chat, the AI re-reads your project docs, rules, and user stories so it doesn’t start from stale assumptions.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> You can start a fresh chat and the AI picks up where the project left off.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · Always On</span> | |
| <h3>Workbench Check</h3> | |
| <p>Before writing any UI, the AI looks up which Gusto design system components already exist using the Workbench MCP.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> The AI won’t reinvent a button or card that Workbench already provides.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · On Gusto Files</span> | |
| <h3>Gusto Workbench</h3> | |
| <p>Coding standards for Workbench: use design tokens for colors and spacing, prefer domain components like PageLayout and DataView, never guess at APIs.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> Your prototype looks and feels like the real Gusto app automatically.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · On Sandbox Files</span> | |
| <h3>Sandbox Rules</h3> | |
| <p>Your prototyping preferences: TDD workflow, deviation tracking, Before/After patterns, and Prototype Controller setup.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> The AI follows your preferred prototyping methodology.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · On Demand</span> | |
| <h3>Design Review</h3> | |
| <p>Ask the AI to critique your prototype. It produces a prioritized list of UX improvements with effort estimates and creative ideas.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> Like getting feedback from a senior designer, ranked by impact.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · Always On</span> | |
| <h3>Plan</h3> | |
| <p>When making changes, the AI batches them into small, reviewable PRs (max 5 files each). Low-risk changes go first.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> Changes are easy to review and safe to roll back.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule · Always On</span> | |
| <h3>Git Safety</h3> | |
| <p>Prevents the AI from accidentally deleting your uncommitted work. Always checks for untracked files before switching branches.</p> | |
| <div class="card-key"><strong>What it means for you:</strong> You won’t lose prototype work to a careless git operation.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="how-to-build"> | |
| <div class="container"> | |
| <h2>How to Build a Prototype</h2> | |
| <p>The recommended workflow from idea to working prototype.</p> | |
| <div class="steps"> | |
| <div class="step"> | |
| <div class="step-num">1</div> | |
| <div class="step-body"> | |
| <h3>Start with user stories</h3> | |
| <p>Write what the user should experience as acceptance criteria. These become the source of truth for everything — the AI audits against them, tests derive from them, and reviews reference them.</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">2</div> | |
| <div class="step-body"> | |
| <h3>Build with TDD</h3> | |
| <p>The AI writes tests from your stories first, then implements code to pass them. This means features are verified as they’re built, not after. Stories define <em>what</em> to build; TDD defines <em>how</em>.</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">3</div> | |
| <div class="step-body"> | |
| <h3>Use Workbench components</h3> | |
| <p>The AI checks the Workbench MCP before writing any component. If Gusto already has a DataView, PageLayout, or Button, the AI uses it — so your prototype matches the real product.</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">4</div> | |
| <div class="step-body"> | |
| <h3>Deviate intentionally</h3> | |
| <p>When Workbench doesn’t have what you need, the AI builds it using design tokens and logs the deviation in DEVIATIONS.md. This file becomes a backlog of potential Workbench contributions.</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">5</div> | |
| <div class="step-body"> | |
| <h3>Review and iterate</h3> | |
| <p>Run a design review for prioritized improvements, or a UX checklist for a strict pass/fail gate. Fix findings in small batches.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <details> | |
| <summary>Learn more about deviations</summary> | |
| <div class="detail-content"> | |
| <p>A deviation is anything you build that Workbench doesn’t offer: a custom timeline feed, a color-coded status dot, a two-column layout with a sticky sidebar. These are expected and valuable in prototypes — they show what the design system might need next.</p> | |
| <p><strong>What counts:</strong> Custom components, new UI patterns, colors or spacing not in Workbench tokens.</p> | |
| <p><strong>What doesn’t count:</strong> Minor layout tweaks with Box, mock data, simplified interactions.</p> | |
| <p>The pipeline: <strong>Workbench Check</strong> (“does this exist?”) → <strong>Sandbox Rules</strong> (“if not, deviate with tokens”) → <strong>DEVIATIONS.md</strong> (“log what you built and why”).</p> | |
| </div> | |
| </details> | |
| </div> | |
| </section> | |
| <section id="before-after"> | |
| <div class="container"> | |
| <h2>The Before / After Pattern</h2> | |
| <p>When you’re prototyping changes to an existing page, don’t just build the new version. Build both states so reviewers can compare them side by side with a toggle.</p> | |
| <div class="two-col"> | |
| <div class="card" style="border-color: var(--gray-300);"> | |
| <h3>Before</h3> | |
| <p>Production-faithful. What exists today, built with mock data. This is the baseline reviewers compare against.</p> | |
| </div> | |
| <div class="card" style="border-color: var(--teal); border-width: 2px;"> | |
| <h3>After</h3> | |
| <p>Your proposed enhancements layered on top. Gated behind a toggle so they can be switched on and off instantly.</p> | |
| </div> | |
| </div> | |
| <h3 style="margin-top: 2rem;">The Prototype Controller</h3> | |
| <p>A floating toolbar at the bottom of the screen that’s visually separate from the app. It lets reviewers toggle states, switch personas, and read QA notes — without touching the product UI.</p> | |
| <div class="toolbar-mock"> | |
| <span class="tb-label">View</span> | |
| <span class="tb-btn tb-inactive">Before</span> | |
| <span class="tb-btn tb-active">After</span> | |
| <span class="tb-divider"></span> | |
| <span class="tb-label">Persona</span> | |
| <span class="tb-persona">Accountant</span> | |
| <span class="tb-divider"></span> | |
| <span class="tb-qa">QA Notes</span> | |
| </div> | |
| <details style="margin-top: 1.5rem;"> | |
| <summary>How does the code work?</summary> | |
| <div class="detail-content"> | |
| <p>The AI sets up three files for every Before/After prototype:</p> | |
| <p><strong>PrototypeContext.tsx</strong> — holds the shared state (isAfter, persona, feature flags) and exposes a usePrototype hook.</p> | |
| <p><strong>PrototypeToolbar.tsx</strong> — the dark floating bar. Uses native HTML, not Workbench components.</p> | |
| <p><strong>designQA.ts</strong> — route-keyed QA notes. Each entry describes what changes in After mode and how to verify it.</p> | |
| <div class="code-block"> | |
| <span class="code-keyword">const</span> { isAfter } = <span class="code-component">usePrototype</span>();<br><br> | |
| <span class="code-comment">// Swap between versions</span><br> | |
| {isAfter ? <<span class="code-component">EnhancedSearch</span> /> : <<span class="code-component">BasicSearch</span> />}<br><br> | |
| <span class="code-comment">// Add sections only in After</span><br> | |
| {isAfter && <<span class="code-component">SummaryTotals</span> />} | |
| </div> | |
| </div> | |
| </details> | |
| <details> | |
| <summary>What about brand new pages?</summary> | |
| <div class="detail-content"> | |
| <p>Pages with no production equivalent should redirect to the parent route when Before is active. This way, the Before toggle doesn’t show a broken empty page — it gracefully sends the reviewer back to the main view.</p> | |
| </div> | |
| </details> | |
| <details> | |
| <summary>Can I toggle individual features separately?</summary> | |
| <div class="detail-content"> | |
| <p>Yes. For prototypes with multiple independent enhancements, the AI sets up granular feature flags in the context — not just a single Before/After toggle. Reviewers can evaluate changes one at a time or all together.</p> | |
| </div> | |
| </details> | |
| </div> | |
| </section> | |
| <section id="evaluate"> | |
| <div class="container"> | |
| <h2>How to Evaluate Your Prototype</h2> | |
| <p>Three tools, each with a different purpose. Use them at different stages of development.</p> | |
| <div class="card-grid" style="grid-template-columns: repeat(3, 1fr);"> | |
| <div class="card"> | |
| <span class="card-tag tag-rule">Rule</span> | |
| <h3>Design Review</h3> | |
| <p style="font-size: 0.95rem; font-style: italic; color: var(--gray-500);">“Getting feedback from a senior designer”</p> | |
| <p>Produces a prioritized table of findings (High / Medium / Low) with effort estimates and creative improvement ideas. Advisory, not a gate.</p> | |
| <div class="card-key"><strong>When:</strong> During development. Ask “run a design review” to see what’s improvable.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-skill">Skill</span> | |
| <h3>/ux-checklist</h3> | |
| <p style="font-size: 0.95rem; font-style: italic; color: var(--gray-500);">“A final exam with 4 questions”</p> | |
| <p>Strict pass/fail against Gusto’s 4 Non-Negotiables: Clarity, System Thinking, Personalized Guidance, Platform Correctness. Any violation = FAIL.</p> | |
| <div class="card-key"><strong>When:</strong> Before shipping. Type <code>/ux-checklist</code> for the go/no-go gate.</div> | |
| </div> | |
| <div class="card"> | |
| <span class="card-tag tag-skill">Skill</span> | |
| <h3>/audit-experience</h3> | |
| <p style="font-size: 0.95rem; font-style: italic; color: var(--gray-500);">“Running the exam on every page and tracking scores”</p> | |
| <p>Runs /ux-checklist across an entire product area in parallel and writes results to Google Sheets for month-over-month tracking.</p> | |
| <div class="card-key"><strong>When:</strong> Monthly. Track how an entire area is trending over time.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="tools-compared"> | |
| <div class="container"> | |
| <h2>Tools Compared</h2> | |
| <p>Different tools for different jobs. Here’s when to reach for each one.</p> | |
| <h3 style="margin-top: 2rem;">Review tools</h3> | |
| <table class="compare"> | |
| <thead> | |
| <tr> | |
| <th></th> | |
| <th>Design Review</th> | |
| <th>/ux-checklist</th> | |
| <th>/audit-experience</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>Tone</strong></td> | |
| <td>“Here are 12 things to improve, ranked”</td> | |
| <td>“You have 1 violation. FAIL.”</td> | |
| <td>“Here’s how 20 pages scored this month”</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Output</strong></td> | |
| <td>Prioritized backlog + design ideas</td> | |
| <td>PASS or FAIL</td> | |
| <td>Google Sheets scorecard</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Scope</strong></td> | |
| <td>One page or flow</td> | |
| <td>One page or flow</td> | |
| <td>Entire product area</td> | |
| </tr> | |
| <tr> | |
| <td><strong>When</strong></td> | |
| <td>During development</td> | |
| <td>Before shipping</td> | |
| <td>Monthly tracking</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Type</strong></td> | |
| <td><span class="badge badge-auto">Rule</span></td> | |
| <td><span class="badge badge-manual">Skill</span></td> | |
| <td><span class="badge badge-manual">Skill</span></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <h3 style="margin-top: 2.5rem;">Building tools</h3> | |
| <table class="compare"> | |
| <thead> | |
| <tr> | |
| <th></th> | |
| <th>Regular Prototyping</th> | |
| <th>/scaffold</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>How it works</strong></td> | |
| <td>You describe what you want, the AI builds it iteratively following your rules</td> | |
| <td>You pick a template type and the AI generates all files at once from a schema</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Best for</strong></td> | |
| <td>Custom, exploratory prototypes where the design is evolving</td> | |
| <td>Standard page patterns where structure is known upfront</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Output</strong></td> | |
| <td>Whatever you and the AI create together</td> | |
| <td>Complete page with routes, data, and tests — regenerable from scaffold.json</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Templates</strong></td> | |
| <td>No templates — fully custom</td> | |
| <td>4 types: stepper, left-nav, tabs, index (list/detail)</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Before/After</strong></td> | |
| <td>Yes — with Prototype Controller</td> | |
| <td>No — generates new pages only</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <div class="callout" style="margin-top: 1.5rem;"> | |
| <strong>Think of it this way:</strong> | |
| Regular prototyping is like sketching on a blank canvas. <code>/scaffold</code> is like using a Figma template — faster to start, but limited to the template’s structure. Use scaffold when you need a standard layout fast; use regular prototyping when you’re exploring something new. | |
| </div> | |
| <h3 style="margin-top: 2.5rem;">Suggested workflow</h3> | |
| <div class="steps"> | |
| <div class="step"> | |
| <div class="step-num">1</div> | |
| <div class="step-body"> | |
| <h3>Write user stories</h3> | |
| <p>Define intended behavior with acceptance criteria</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">2</div> | |
| <div class="step-body"> | |
| <h3>Run design review during development</h3> | |
| <p>Get prioritized improvements while you’re building</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">3</div> | |
| <div class="step-body"> | |
| <h3>Run /ux-checklist before sharing</h3> | |
| <p>Pass/fail gate — make sure you meet the 4 Non-Negotiables</p> | |
| </div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-num">4</div> | |
| <div class="step-body"> | |
| <h3>Run /audit-experience monthly</h3> | |
| <p>Track how your product area is trending across all pages</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="cheat-sheet"> | |
| <div class="container"> | |
| <h2>Cheat Sheet</h2> | |
| <p>Copy-paste these into a Cursor chat to get started quickly.</p> | |
| <div class="cheat"> | |
| <div class="cheat-row cheat-header"> | |
| <div>Say this to the AI</div> | |
| <div></div> | |
| <div>What happens</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">“Create a prototype at /reports”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Creates folder, page.tsx, wires routing, wraps in PageLayout</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">“Use Before/After for this”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Sets up Prototype Controller with toggle, personas, and QA notes</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">“Write user stories for this feature”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Creates acceptance criteria in Gherkin format that drive tests and reviews</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">“Run a design review”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Produces prioritized findings table with effort estimates and ideas</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">/ux-checklist</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">PASS or FAIL against Gusto’s 4 Non-Negotiables</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">/scaffold tabs “benefits settings”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Generates a complete tabbed page with routes, data, and tests</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say">“What deviations have we made?”</div> | |
| <div class="cheat-arrow">→</div> | |
| <div class="cheat-do">Opens DEVIATIONS.md — your backlog of custom patterns for Workbench</div> | |
| </div> | |
| <div class="cheat-row"> | |
| <div class="cheat-say" style="border-bottom: none;">“Create a plan for these findings”</div> | |
| <div class="cheat-arrow" style="border-bottom: none;">→</div> | |
| <div class="cheat-do" style="border-bottom: none;">Batches fixes into small PRs, ordered low-risk to high-risk</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <footer> | |
| <div class="container"> | |
| Gusto Design · Prototyping Workflow Reference · Updated March 2026 | |
| </div> | |
| </footer> | |
| <script> | |
| const sections = document.querySelectorAll('section[id]'); | |
| const navLinks = document.querySelectorAll('nav a'); | |
| window.addEventListener('scroll', () => { | |
| let current = ''; | |
| sections.forEach(s => { | |
| if (window.scrollY >= s.offsetTop - 100) current = s.id; | |
| }); | |
| navLinks.forEach(a => { | |
| a.classList.toggle('active', a.getAttribute('href') === '#' + current); | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment