---
name: lh-dev-handoff
description: >
  Translating design into implementable specs: design-tool-to-code concept
  mapping, design tokens, component specs, UI acceptance criteria. Trigger: load
  when handing a design to a developer, discussing a Figma or Sketch file,
  defining tokens, or writing what "done" means for a UI task.
license: Apache-2.0
metadata:
  author: jrodrigopuca
  version: "1.1"
  local-agents-id: "sk-78d899"
---

## Critical Patterns

### 1. The design-tool ↔ code Rosetta stone

Speak both languages by mapping the concepts — most handoff confusion is
vocabulary, not disagreement. The table below is written in Figma's vocabulary
because that is what most teams draw in; every concept in it exists in Sketch,
Penpot and Framer under a different name, so translate the left column to your
tool and the mapping still holds:

| Figma | Code | Watch out |
|-------|------|-----------|
| Auto-layout | Flexbox (direction, gap, padding, align) | "Hug" = fit-content, "Fill" = flex-grow/width:100% |
| Component + variants | Component + props (variant/size/state) | Variant names should MATCH prop names |
| Component properties | Props (boolean, text, instance-swap ≈ slot/children) | |
| Variables / styles | Design tokens → CSS custom properties / Tailwind theme | One source of truth, not two |
| Constraints / resizing | CSS positioning + responsive behavior | Figma frames are snapshots; CSS is rules — spec the RULE |
| Frame sizes | Breakpoints | A 1440px frame is one sample, not the spec |

The last row is the deepest trap: Figma shows discrete artboards, code renders
a continuum. Every handoff must state what happens BETWEEN the artboards.

### 2. Tokens are the shared vocabulary — semantic, not raw

Name tokens by ROLE (`color-text-muted`, `space-md`, `radius-card`), never by
value (`gray-400`, `spacing-12px`). Role names survive a rebrand; value names
lie after the first change. Two layers max: primitives (the palette/scale) →
semantic (what screens use) — and a theme (dark, high-contrast) is a second
mapping of primitives onto the SAME semantic names, never a second set of
names; a screen that references a role works in every theme by construction.
This is the one home of token naming in the catalog; [lh-visual-craft](../lh-visual-craft/SKILL.md)
decides which roles exist. If designers use Figma variables and devs use CSS
variables with DIFFERENT names, you have two design systems drifting — align
the names first, everything else follows.

### 3. The component spec — what a dev actually needs

For each component handed off, spec (a filled table beats prose):

1. **Anatomy** — the parts, named like the code will name them
2. **Variants & props** — every axis (size, kind, state) with allowed values
3. **States** — default / hover / focus-visible / active / disabled / loading /
   error — interactive states are ALWAYS in scope, even when Figma only shows default
4. **Behavior** — what happens on click/submit/overflow; text truncation rules
   (ellipsis at N lines? wrap?); min/max content cases
5. **Responsive rule** — how it reflows between breakpoints (the rule, not
   per-breakpoint pictures)
6. **A11y notes** — focus order, ARIA role if non-obvious, contrast-checked

### 4. Acceptance criteria for UI: observable, not aesthetic

"Matches the design" is not testable. Write criteria a dev (or a test) can
verify: "primary button disabled until both fields valid", "list shows skeleton
while loading, empty-state illustration at 0 items", "layout switches to single
column below 768px". The [five states](../lh-ux-flows/SKILL.md) each become at
least one criterion. Pixel-perfection claims follow the evidence ladder — check
the rendered result against the spec, don't eyeball the screenshot.

### 5. Annotate the WHY on non-obvious decisions

When a design deviates from the system or the obvious (an odd spacing, a
duplicated action, a hidden feature), annotate the reason in the handoff. An
unexplained oddity gets "fixed" back into a bug by a well-meaning dev — same
principle as code comments explaining constraints.

### 6. Handoff is a conversation, not a throw

Walk the dev through flows and states, ask what's expensive to build, and
NEGOTIATE: often a 5% visual compromise saves 40% of implementation cost — a
peer designer wants to know that tradeoff exists. And the most contested call
in any handoff gets decided out loud, not by default: new component, new
VARIANT of an existing one, or a one-off? A variant when the anatomy is the
same and one axis changes; a component when the anatomy differs; a one-off
only with an expiry date, because one-offs are how design systems die.

## Resources

- Sibling skills: [lh-ux-flows](../lh-ux-flows/SKILL.md) (source of the states),
  [lh-visual-craft](../lh-visual-craft/SKILL.md) (source of the token values),
  [lh-mockups](../lh-mockups/SKILL.md) (the artifact being handed off)
- Implementation side: a `tailwind-4` skill if the host exposes one (tokens →
  theme; ships outside this catalog, so optional),
  [senior-dev/lh-react-next](../../../senior-dev/skills/lh-react-next/SKILL.md)
  (variants → props in practice)
