From Design to Code
Chapter objectives
- Generate a clean reusable component
- Handle states (hover, focus, disabled)
- Turn an image or a sketch into an interface
From mockup to component: changing mindset
Until now, you were producing pages: renders to show, discuss, validate. The client's developer, though, doesn't integrate pages — they integrate components: autonomous, reusable bricks (a button, a card, a form field) that they assemble in their application. Moving from design to code is first this change in the unit of thought: you no longer deliver a screen, you deliver a vocabulary of bricks.
Why does it matter so much? Because a button coded as a component exists in a single copy in the code, varied through parameters (its variant, its size, its state). Fixing a defect fixes it everywhere. Conversely, a monolithic page where the same button is copy-pasted twelve times becomes unmanageable at the first evolution. It's the same logic as design tokens, one level up: the system before the page.
flowchart LR D["Design validated in the artifact"] --> T["Tokens: CSS variables"] T --> C["Components: props + states + accessibility"] C --> I["Integration by the developer"] I --> V["Verification: states, keyboard, contrast"]
Anatomy of a good component
A well-designed component is described by its props (its input parameters): for a button, typically variant (primary, secondary, ghost), size (sm, md, lg) and disabled. This interface isn't a technical detail: it's the translation into code of your design system's decisions. Three button variants in the mockup = a variant prop with three values in the code. If you find yourself asking for a fourth variant "just for this page", that's the signal that a design decision is leaking out of the system.
Always ask the AI for the component plus a usage example: seeing <Button variant="primary" size="lg">Try for free</Button> lets you immediately judge whether the interface is intuitive. And specify the output format from the start — pure HTML/CSS, React, with or without Tailwind — because converting afterward wastes time and introduces discrepancies.
Interactive states: hover, focus, disabled
Here is the most visible difference between a demo render and a professional component: the states. A real button lives at least four lives: rest, hover (mouse-over — feedback that the element is clickable), focus (keyboard selection — indispensable, we'll come back to it), active (the instant of the click) and disabled (action unavailable). A component without states isn't finished: it's a picture that looks like a button.
Each state must be perceptible but consistent: on hover, you slightly darken the color (hence the --color-primary-hover token) and you can subtly raise the shadow; in the disabled state, you reduce the opacity and change the cursor. Transitions must be gentle — 150 to 200 ms — for Sereno's calming mood. And think about components beyond the button: a form field also has its states (focus, error, filled), a clickable card has its hover.
Turn the Sereno landing page button into a reusable React component: - props: variant (primary | secondary | ghost), size (sm | md | lg), disabled - visual states: hover (darken toward --color-primary-hover, 180ms transition), focus-visible (2px ring in --color-accent, offset by 2px), active (slight scale reduction), disabled (0.5 opacity, cursor not-allowed) - use exclusively the CSS variables of the provided design system — no hard-coded values - accessibility: native <button> element, visible keyboard focus, minimum height of 44px at md size Deliver the complete code + 3 usage examples (one per variant) + the list of tokens used.
Accessibility in code: beyond contrast
In chapter 2, accessibility was about contrast. In code, it takes on two additional dimensions. First, keyboard navigation: a share of your users don't use a mouse (motor disability, screen readers, or simple preference). Every interactive element must be reachable with Tab and clearly show it's selected — that's the role of the focus-visible state, that ring around the button some designers remove "because it's ugly". Never remove it: style it so it's beautiful.
Second, HTML semantics: a button must be a <button>, not a styled <div> with a click handler. The native element brings keyboard focus, activation with Enter and Space, and correct announcement to screen readers for free. Same logic for headings (<h1>…<h2> in order, without skipping levels), lists and links. The AI produces correct semantic HTML… if you ask for it. Systematically add "semantic and accessible HTML" to your code prompts, and request an audit: "review this component from an accessibility standpoint and list the problems".
Image → interface: starting from a screenshot or a sketch
A spectacular and genuinely useful capability: giving the AI an image — a screenshot, an exported mockup, or a photo of a marker sketch on the corner of a table — and asking it to reproduce the structure in code. Current models analyze the layout, identify the components (navigation, hero, cards, forms) and produce a functional interface close to the original.
The concrete studio uses: digitizing a workshop (the client sketched their vision on the whiteboard — photograph and code in five minutes, the effect is guaranteed), starting from a reference ("take the structure of this screenshot, but apply my design system entirely" — borrowed structure, custom skin), or rebuilding the existing (a screenshot of the client's old site as the starting point of the redesign).
Here is the photo of the sketch the client made in the workshop [image attached]. Reproduce the structure of this layout in HTML/CSS: - identify each zone (navigation, hero, columns, footer) and name them in comments - apply my design system provided below — the structure comes from the sketch, the style comes from the tokens - where the sketch is ambiguous, choose the simplest interpretation and flag it in a comment [paste your :root block here]
Keeping the code clean and wired to the tokens
Last link in the chain: the quality of the delivered code. Three requirements to state explicitly. One: the code reuses the tokens — any hard-coded value is a consistency bug (you can request an audit: "list all remaining hard-coded values in this code and replace them with the appropriate tokens"). Two: comments explain the non-obvious choices, not every line — "why this z-index" deserves a comment, "this is a button" doesn't. Three: the names (classes, props, files) follow a consistent convention the client's developer can extend.
Also get into the habit of critical review: the generated code is generally correct, but not always optimal. Duplicated CSS rules, an overly specific selector, a forgotten state — ask the AI to reread its own code ("reread this component as a demanding senior developer: quality, accessibility, consistency with the tokens") before delivering. A clean component is maintainable; a hacked-together one quickly becomes unmanageable, and the studio's reputation is on the line with every delivery.
Context
The client has approved the Sereno landing page mockup. Their developer is now waiting for a button system ready to integrate into their React app — variants, sizes, states and accessibility included. It's Studio Mango's first code delivery to this client: it must be flawless, because phase 2 (the full app) hinges on this impression.
Instructions
- Request a React button component with props (variant, size, disabled), reusing exclusively your CSS tokens.
- Demand the four states: hover, focus-visible, active and disabled — with gentle transitions (150-200 ms).
- Verify each state in the render: hover, tab through with the keyboard, test the disabled state.
- Request an accessibility audit of the component: semantics, keyboard focus, minimum target size (44px).
- Request the list of remaining hard-coded values and have them replaced with tokens.
- Image → code test: take a screenshot of an existing component (or a quick sketch) and have it coded with your design system.
- Request a final "demanding senior developer" review and apply the fixes before considering the delivery complete.
In summary
- You don't deliver pages but components: parameterizable bricks (props) that exist in a single copy in the code.
- Props translate the design system's decisions: three button variants = one variant prop with three values.
- A component must handle its states: hover, focus-visible, active, disabled — without them, it's just a picture of a button.
- Accessibility in code = contrast + keyboard navigation (styled, never removed, visible focus) + semantic HTML (native button, ordered headings).
- You can start from an image or a sketch: the AI reproduces the structure, your design system provides the skin.
- Specify the output format from the start (HTML/CSS, React, Tailwind mapped to the tokens) based on the recipient's stack.
- Clean code = zero hard-coded values, comments on non-obvious choices, consistent naming conventions.
- Before delivering: accessibility audit + critical review requested from the AI itself.
Quiz — check your understanding
1. What distinguishes a finished component?
2. Can you start from a paper sketch?
3. Why use a native