DOMAIN:DESIGN:DESIGN_FOR_AGENTS¶
OWNER: alexander (Design System Engineer, shared) UPDATED: 2026-03-24 SCOPE: how design works in an agentic development context PREREQUISITE: design-system-engineering.md (DESIGN.md structure and component catalog) ALSO_RELEVANT_TO: floris (Team Alpha frontend), floor (Team Beta frontend), felice (visual QA)
PRINCIPLE: AGENTS_READ_SPECS_NOT_MOCKUPS¶
RULE: agents cannot see. They cannot interpret images, screenshots, or Figma files. RULE: every design decision must be expressed as structured text in DESIGN.md. RULE: if a design detail is not in DESIGN.md, it does not exist for the development agents. REASON: LLMs process text. A human developer can look at a Figma mockup and infer spacing, hierarchy, and intent. An agent needs explicit instructions: "Card padding is 1.5rem. Title is h3 with font-weight 600. Status badge uses variant 'secondary' for draft status."
DESIGN_MD_AS_MACHINE_READABLE_SPEC¶
WHY_DESIGN_MD_EXISTS¶
Traditional design handoff:
Agentic design handoff:
DESIGN.md replaces Figma, Sketch, Adobe XD, InVision, and Zeplin. It is: - Machine-readable (structured markdown that agents parse) - Version-controlled (in git, like code) - Diffable (changes are visible in PRs) - Composable (references shadcn/ui component names directly) - Self-contained (no external tools needed to read it)
DESIGN_MD_PARSING_BY_AGENTS¶
When a frontend agent (floris/floor) receives a WP, they:
STEP_1: read DESIGN.md to understand the design system (tokens, components) STEP_2: find the screen specification for the screen they are building STEP_3: implement the component tree exactly as specified STEP_4: apply design tokens via Tailwind CSS classes (not hardcoded values) STEP_5: implement responsive behavior per the breakpoint specifications STEP_6: implement all states (loading, empty, error, populated)
WHAT_AGENTS_NEED_FROM_DESIGN_MD¶
MUST HAVE (agent cannot build without it):
- Design token values (colors, spacing, typography, radii, shadows)
- Component selection per screen (which shadcn/ui components)
- Component configuration (props, variants, sizes)
- Layout structure (grid columns, flex direction, spacing between sections)
- Data binding (which API field maps to which UI element)
SHOULD HAVE (agent can build but result may be wrong):
- Responsive behavior per breakpoint
- State specifications (loading, empty, error)
- Interaction behavior (hover, focus, active states)
- Animation specifications (if any)
NICE TO HAVE (agent can infer from conventions):
- Icon selection (agent picks from Lucide catalog)
- Exact pixel measurements (agent uses spacing scale)
- Color shade selection (agent uses token names)
DESIGN_TOKEN_FORMAT_FOR_LLM_CONSUMPTION¶
OPTIMAL_FORMAT¶
Agents parse markdown. The format must be: - Flat (no deeply nested structures) - Named (every value has a semantic name) - Typed (agent knows if value is a color, size, or string) - Contextual (agent knows where to use each token)
TOKEN_SPECIFICATION_FORMAT¶
## Design Tokens
### Colors
| Token Name | Value | Usage |
|---------------------|-------------------------|------------------------------------|
| primary | oklch(0.65 0.15 250) | Buttons, links, active states |
| primary-foreground | oklch(0.98 0 0) | Text on primary backgrounds |
| secondary | oklch(0.95 0.02 250) | Secondary buttons, hover states |
| destructive | oklch(0.55 0.22 25) | Delete buttons, error states |
| muted | oklch(0.96 0.005 250) | Disabled backgrounds, subtle areas |
| muted-foreground | oklch(0.55 0.01 250) | Placeholder text, labels |
| border | oklch(0.91 0.005 250) | Input borders, card borders |
| background | oklch(1 0 0) | Page background |
| foreground | oklch(0.14 0 0) | Body text |
### Typography
| Token Name | Value | Usage |
|---------------|--------------------------------|------------------------------|
| font-sans | "Inter", system-ui, sans-serif | All text |
| text-xs | 0.75rem / 1rem | Captions, footnotes |
| text-sm | 0.875rem / 1.25rem | Labels, table cells |
| text-base | 1rem / 1.5rem | Body text |
| text-lg | 1.125rem / 1.75rem | Sub-headings |
| text-xl | 1.25rem / 1.75rem | Section headings |
| text-2xl | 1.5rem / 2rem | Page headings |
| text-3xl | 2rem / 2.25rem | Hero headings |
### Spacing
| Token | Value | Usage |
|--------|---------|--------------------------------------------|
| 1 | 0.25rem | Icon-to-text gap, tight spacing |
| 2 | 0.5rem | Input padding-y, compact gaps |
| 3 | 0.75rem | Input padding-x, form field gaps |
| 4 | 1rem | Card padding, standard component spacing |
| 6 | 1.5rem | Card padding (spacious), section gaps |
| 8 | 2rem | Section spacing |
| 12 | 3rem | Page section spacing |
| 16 | 4rem | Major section spacing, page margins |
WHY_THIS_FORMAT_WORKS:
- Agents can scan the table and find the right token by usage description
- Token names match Tailwind classes directly (e.g., text-sm, p-4, bg-primary)
- No ambiguity about when to use which value
COMPONENT_SELECTION_FROM_SHADCN_CATALOG¶
THE_SELECTION_PROCESS¶
Alexander reads Anna's spec and maps each UI need to a shadcn/ui component:
ANNA'S SPEC SAYS: ALEXANDER SELECTS:
"Paginated list of orders" → Table + Pagination
"Create order form" → Form + Input + Select + Button
"Order status indicator" → Badge (variant by status)
"Confirm before delete" → AlertDialog (destructive)
"Success notification" → Sonner toast
"Date range filter" → DatePicker (range mode)
"User profile dropdown" → DropdownMenu + Avatar
"Sidebar navigation" → Sidebar + SidebarMenu
"Search across all records" → Command (Cmd+K palette)
"Settings organized by topic" → Tabs + Form sections
"Expandable order details" → Collapsible or Accordion
COMPONENT_SPECIFICATION_FORMAT¶
Each screen in DESIGN.md specifies components with enough detail for an agent to implement:
### Screen: Order List (/orders)
#### Layout
- Sidebar (left, collapsible on mobile)
- Main content area with PageHeader + content
#### Component Tree
FilterBar (flex row, gap-2, mb-4) ├── Input(type="search", placeholder="Search orders...") ├── Select(placeholder="Status") options=[All, Draft, Submitted, InProgress, Completed] ├── DatePicker(mode="range", placeholder="Date range") └── Button(variant="outline", size="sm") "Clear filters"
DataTable ├── columns: │ ├── order_number: sortable, link to /orders/{id} │ ├── client_name: sortable │ ├── status: Badge component │ │ ├── draft → variant="secondary" │ │ ├── submitted → variant="default" │ │ ├── in_progress → variant="default" + blue custom │ │ ├── completed → variant="default" + green custom │ │ └── cancelled → variant="destructive" │ ├── total: right-aligned, formatted EUR │ ├── created_at: relative time ("2 hours ago") │ └── actions: DropdownMenu [View, Edit, Delete] ├── pagination: bottom, 20 rows per page ├── empty: EmptyState icon=Package title="No orders yet" │ description="Create your first order to get started" │ action=Button "New Order" └── loading: Skeleton rows matching column layout
#### Responsive
- Desktop: full table with all columns
- Tablet: hide created_at column, compact padding
- Mobile: card layout replacing table
- Each card shows: order_number, client_name, status badge, total
- Tap card → navigate to detail
WHEN_TO_USE_STITCH_VS_MANUAL¶
DECISION_FRAMEWORK¶
| Scenario | Approach | Reason |
|-----------------------------------|-----------------|-------------------------------------|
| Standard CRUD list page | Manual (L1) | Table + Form = well-known pattern |
| Standard form page | Manual (L1) | shadcn Form + inputs = sufficient |
| Login/register page | Manual (L1) | Standard auth pattern |
| Settings page | Manual (L1) | Tabs + forms = well-known pattern |
| Dashboard with KPI cards | Manual (L1) | Card grid = simple layout |
| Dashboard with custom charts | Stitch (L2) | Chart layout is visual, needs help |
| Landing/marketing page | Stitch (L2) | Creative layout, not standard CRUD |
| Client-facing portal (branded) | Stitch (L2) | Client brand requires visual design |
| Complex wizard/multi-step flow | Stitch (L2) | Step visualization needs design |
| Showcase page for GE itself | External (L3) | Brand-critical, needs human design |
STITCH_PROMPT_ENGINEERING¶
When using Stitch MCP, Alexander writes prompts that constrain the output to GE conventions:
GOOD PROMPT:
"A professional order management dashboard using a clean, minimal style.
4 KPI cards in a row at the top (total orders, pending, completed, revenue).
Below, a 2-column layout: left column has a line chart showing orders over
the last 30 days, right column has a table of 5 most recent orders.
Use Inter font, blue primary color (#4A73E8), white background.
Cards have subtle shadows and rounded corners.
Responsive: stack to single column on mobile."
BAD PROMPT:
"Make a nice dashboard for orders"
PROMPT_RULES: - Specify layout (grid, columns, positioning) - Specify content (what data appears where) - Specify style constraints (font, colors, borders, shadows) - Specify responsive behavior - Do not specify implementation details (no React, no CSS class names)
POST_STITCH_WORKFLOW¶
After Stitch generates output:
STEP 1: Alexander reviews Stitch HTML/CSS output
STEP 2: Alexander maps Stitch components to shadcn/ui equivalents
Stitch <div class="card"> → shadcn Card
Stitch <table> → shadcn Table
Stitch <button> → shadcn Button
STEP 3: Alexander adjusts design tokens to match project DESIGN.md
Stitch colors → project oklch tokens
Stitch font → project font-sans
STEP 4: Alexander writes screen spec in DESIGN.md
Component tree, responsive behavior, states
STEP 5: Human (Dirk-Jan) reviews Stitch mockup + DESIGN.md spec
STEP 6: Developer agent implements from DESIGN.md (not from Stitch HTML)
CRITICAL: developers NEVER implement from Stitch HTML directly. Stitch output is reference material for Alexander. DESIGN.md is the implementation spec.
VISUAL_QA_BY_FELICE¶
FELICE_ROLE¶
Felice is the Visual Asset Producer. After development, Felice compares the implemented UI against DESIGN.md.
FELICE_CANNOT: see the running application (agents cannot view browsers). FELICE_CAN: read the source code and compare it against DESIGN.md specifications.
WHAT_FELICE_CHECKS¶
CODE-LEVEL VERIFICATION:
[ ] Tailwind classes use design token names (bg-primary not bg-blue-500)
[ ] Component selections match DESIGN.md (Table not custom <div> grid)
[ ] Spacing uses token scale (p-4 not p-[17px])
[ ] Typography uses token scale (text-sm not text-[13px])
[ ] Color usage matches token purpose (destructive for errors, not red-500)
[ ] Border radius uses token (rounded-md not rounded-[7px])
[ ] Dark mode tokens applied where specified
RESPONSIVE VERIFICATION:
[ ] Mobile-first classes present (base styles for mobile)
[ ] Breakpoint modifiers match DESIGN.md (md: for tablet, lg: for desktop)
[ ] Hidden elements at correct breakpoints (hidden md:block for desktop-only)
[ ] Touch targets >= 44px on mobile (h-11 w-11 minimum for interactive)
ACCESSIBILITY VERIFICATION:
[ ] Alt text on images
[ ] ARIA labels on icon-only buttons
[ ] Form labels associated with inputs (htmlFor matches id)
[ ] Heading hierarchy correct (h1 > h2 > h3, no skipping)
[ ] Focus-visible styles not suppressed
[ ] prefers-reduced-motion respected for animations
STATE VERIFICATION:
[ ] Loading state uses Skeleton components
[ ] Empty state uses EmptyState pattern
[ ] Error state uses Alert with retry
[ ] All states render without console errors
FELICE_OUTPUT_FORMAT¶
## Visual QA: {screen_name}
### Status: PASS | NEEDS_FIXES
### Findings
#### BLOCKER
- [ ] BUG: Button in header uses `bg-blue-500` instead of `bg-primary`
File: components/orders/order-header.tsx:14
Fix: replace `bg-blue-500` with `bg-primary`
#### SHOULD_FIX
- [ ] DEVIATION: Card padding is p-3 but DESIGN.md specifies p-6
File: components/orders/order-card.tsx:8
Fix: change `p-3` to `p-6`
#### NITPICK
- [ ] MINOR: Icon could be Package instead of Box (closer to DESIGN.md intent)
File: components/orders/empty-state.tsx:5
Suggestion: change `<Box>` to `<Package>`
DESIGN_SYSTEM_EVOLUTION¶
WHEN_THE_DESIGN_SYSTEM_CHANGES¶
TRIGGER_1: new project with different brand → new DESIGN.md, different tokens TRIGGER_2: shadcn/ui releases new component → Alexander evaluates for GE catalog TRIGGER_3: Stitch adds new capability → Alexander evaluates for Layer 2 workflow TRIGGER_4: accessibility standard updates → Alexander updates a11y requirements TRIGGER_5: Tailwind CSS update → Alexander updates token implementation
DESIGN_SYSTEM_VERSIONING¶
RULE: each project has its own DESIGN.md in the project repository. RULE: GE maintains a base DESIGN.md template with defaults. RULE: project DESIGN.md overrides base tokens for client branding. RULE: structural patterns (component selection, responsive strategy) are shared across projects.
BASE_DESIGN_MD_TEMPLATE¶
The base template lives in GE's wiki and is used as the starting point for every project:
# DESIGN.md — {Project Name} (base template)
## Design System: GE Default
### Brand Identity
- Override these tokens with client's brand colors
- Default: professional blue (#4A73E8) primary
### Component Library
- shadcn/ui (latest, Tailwind v4 compatible)
- Icons: Lucide React
### Layout Conventions
- Max content width: 1280px (7xl)
- Sidebar width: 256px (64)
- Page padding: 1.5rem (6) mobile, 2rem (8) desktop
- Content gap: 1.5rem (6)
### Form Conventions
- Labels above inputs (not inline)
- Required fields marked with asterisk
- Validation errors below input in text-destructive
- Submit button right-aligned
- Cancel button left of submit, variant="outline"
### Table Conventions
- Zebra striping off (clean look)
- Hover row highlight: bg-muted/50
- Pagination always visible
- Default page size: 20
- Sortable columns indicated with icon
### Dialog Conventions
- Max width: sm for confirmations, lg for forms
- Close button top-right
- Primary action right-aligned
- Destructive actions use AlertDialog, not Dialog
DESIGN_ANTI_PATTERNS_IN_AGENTIC_CONTEXT¶
ANTI_PATTERN_1: "Figma-first design" WHY_BAD: no agent can read a Figma file. Design work in Figma is wasted effort. INSTEAD: DESIGN.md first. Stitch for visual validation. Figma only if external designer (Layer 3).
ANTI_PATTERN_2: "Hardcoded colors and sizes"
WHY_BAD: bg-blue-500 bypasses the design system. Changing the brand requires touching every file.
INSTEAD: bg-primary. Always use design tokens.
ANTI_PATTERN_3: "Custom components when shadcn has one" WHY_BAD: custom components lack Radix UI accessibility, keyboard nav, and ARIA. More code to maintain. INSTEAD: use shadcn/ui. Customize via tokens and Tailwind classes, not by rewriting the component.
ANTI_PATTERN_4: "Design tokens in JavaScript" WHY_BAD: tokens in JS are not accessible to Tailwind's JIT compiler. Double source of truth. INSTEAD: tokens in CSS variables (globals.css). Tailwind reads them via @theme.
ANTI_PATTERN_5: "No empty/loading/error states in DESIGN.md" WHY_BAD: developer agent implements the happy path only. First API delay = broken UI. INSTEAD: every screen in DESIGN.md must specify all four states.
ANTI_PATTERN_6: "Pixel-perfect specs" WHY_BAD: agents do not measure pixels. They use spacing scale tokens. INSTEAD: use token names (p-4, gap-6, text-sm), not pixel values (16px, 24px, 13px).
INTEGRATION_WITH_GE_PIPELINE¶
DESIGN_IN_THE_PIPELINE¶
Aimee (scope) → Anna (spec) → ALEXANDER (design) → Faye/Sytske (WPs) → Devs → Felice (QA)
↑ ↑
DESIGN.md created DESIGN.md verified
TIMING¶
Alexander works AFTER Anna's formal spec is approved (Gate 4) and BEFORE Faye/Sytske create WPs (Phase 6).
REASON: Faye needs DESIGN.md to size frontend WPs correctly. A complex custom dashboard (Layer 2) takes more WPs than a standard CRUD screen (Layer 1).
DESIGN_WP_IN_THE_WP_SET¶
Faye/Sytske always include a design WP as the first frontend-related WP:
- id: WP-003
title: "Create DESIGN.md and global theme tokens"
lane: LANE_DESIGN
assigned_to: alexander
size: S (Layer 1 only) | M (Layer 1 + Layer 2 screens)
depends_on: [] # Alexander reads Anna's spec, not other WPs
spec_refs: [] # Design is cross-cutting, not tied to one REQ
produces:
- "DESIGN.md"
- "styles/globals.css" (if project needs custom token setup)
RULE: the design WP has no dependencies (Alexander only needs Anna's spec, which passed the gate). RULE: all frontend WPs depend on the design WP (they need DESIGN.md to implement correctly). RULE: backend WPs do NOT depend on the design WP (APIs are design-agnostic).