Sander Korf
  • Portfolio
  • Resume

Sander Korf

Dutch Full Stack AI Engineer helping businesses cut costs through intelligent automation. 13+ years turning expensive manual processes into systems that work 24/7. Based in Amsterdam, available for freelance projects.

Navigation

  • Portfolio
  • Resume

Legal

  • Cookies
  • Privacy Policy
  • Terms and Conditions

Blog

Algolia

  • Algolia InstantSearch INP and object identity
  • Algolia merch by Sanity _type, not title
  • Algolia InstantSearch search key, not admin

Vercel

  • Vercel Git deploy beats custom GitHub Actions
  • Next.js empty Suspense fallbacks wreck CLS P95
  • Vercel Workflows: skip closed eToro legs

eToro

  • eToro deploy vs rotate: idle cash not rotate
  • eToro search 404: query fields, not ticker
  • eToro v2 opens at-most-once, settlement
  • eToro LLM overlay ±10pp: critic cannot veto

Next.js

  • Figma design tokens in Tailwind, one scale
  • next-intl useTranslate skip links above fold
  • next-intl owns Klaviyo nl-NL email copy

Firebase & Expo

  • Staging deep links must not hijack production
  • Turn off Worklets Bundle Mode for EAS SHA-1
  • Reclaim Firebase orphan without password wipe

Centra & Klaviyo

  • Centra to Klaviyo tags need a plugin contract

About

  • Full Stack AI Engineer in Amsterdam

© 2026 Sander Korf. All rights reserved

94719489

  • Applied AI
  1. Home
  2. Blog
  3. Figma design tokens in Tailwind, one scale

Figma design tokens in Tailwind, one scale

Product UI kept drifting from Figma until I landed typed tokens, a shared Icon set, and motion durations as CSS variables. One source, no one-offs.

Sander KorfPublished September 1, 20262 min read
figmatailwindnextjsdesign-system

This was a product UI that imported Figma by screenshot

Next.js. Tailwind 4. A Figma design-system file with primitives, components, and motion specs. Engineering had hex codes in one repo corner, spacing magic numbers in another, and duration-300 sprinkled like salt. Every sprint added a new one-off. QA opened Figma side by side and filed bugs that said "wrong blue."

What they would notice if it failed

Buttons that look almost right. Headings that are 2px off. Icons that don't match the set in the file. Discovery Session panels that ease in over 400ms while the rest of the app snaps at 200ms. None of it crashes. All of it erodes trust.

Three PRs, one lesson: land the file, not the mock

I merged three related changes the same day. Design-system color and spacing tokens with a showcase page. A Figma component set wired into product UI (Icon, Heading, Text). Motion tokens plus a Discovery Session example that proves the scale.

The puzzle wasn't "use Figma." It was stop letting every screen invent its own subset.

Tokens first. Primitives become CSS variables in globals.css and Tailwind theme extensions. The showcase page renders every token so drift is visible before it ships. If a dev can't grep the token name, they'll paste #3B82F6 again.

Components second. Icon is typed. Heading and Text map to the Figma text styles. Product code imports @repo/components atoms, not raw SVGs and arbitrary text-lg. When the design file renames a style, TypeScript complains. That's the guardrail.

Motion third. Durations and easings live in one scale (--duration-fast, --duration-normal, --ease-out-product). The Discovery Session example uses that scale for enter and stagger. No transition-all duration-[437ms] because someone liked it in DevTools once.

:root {
	--duration-fast: 150ms;
	--duration-normal: 250ms;
	--ease-out-product: cubic-bezier(0.22, 1, 0.36, 1);
}
import { Icon } from '@repo/components/atoms/icon';
import { Heading } from '@repo/components/atoms/heading';
 
<Heading level={2}>Discovery Session</Heading>
<Icon name='sparkles' className='motion-safe:transition-opacity duration-[var(--duration-normal)]' />

Figma is the contract. Tailwind and typed components are the enforcement layer. Motion tokens are the part teams forget until every modal feels like a different app.

One scale. One icon set. One token file. Drift becomes a compile error, not a design review surprise.


Happy coding! Sander