A real brief. A real product. An open-ended challenge.
I attended a community design call where the Head of Design at Knowunity gave attendees a brief: product overview, user personas, design principles, and a style tile. The challenge was open-ended — take these starting ingredients and build your own design system.
Knowunity is an AI-powered study companion for students aged 12 to 20+. 30M+ users, 15+ countries, mobile-first. It combines student-created content with conversational AI for flashcards, quizzes, and AI chat. Built in Berlin by students, for students.
The dual-audience tension was the hardest thing to hold. A 16-year-old will reject anything that feels designed for a 10-year-old. A 20-year-old college student will bounce from anything that feels like a kids' app. The system had to feel warm and capable without ever being patronizing.
The style tile gave us a mid-range purple, a deep navy, four scattered accent colors, Inter as the current typeface, and a ghost mascot. I treated these as ingredients, not constraints. Some I kept, some I edited, one I replaced entirely.
What if you worked through every decision in conversation before touching Figma?
I wanted to see if AI-assisted design could be genuinely rigorous. Not prompting for output, but using conversation to think through decisions before building anything. Chat-first ideation, then execute in Figma via MCP.
Every token category, naming convention, and design decision proposed and refined in conversation, before any Figma.
Designer reviews and signs off on direction explicitly. "Yes, Noto Sans." "Happy with the color direction." Clear checkpoints.
Claude executes Figma Plugin API scripts through the Console MCP, creating variables, styles, components, and docs directly on canvas.
Screenshot verification after each batch. Fix issues before moving on. No design-by-accident moments.
What changed and why.
The interesting part of design system work isn't the output. It's the reasoning behind each call. Here are the four that shaped this system most.
Switched Inter to Noto Sans
Noto Sans has a larger x-height than Inter, so 15px reads closer to Inter's 16px at mobile sizes. More practically: Knowunity is live in 15+ countries and German text runs 30–40% longer than English. Noto Sans was designed for global language coverage. Inter wasn't.
Four accent colors, narrowed to one
Four scattered accent hues reads as random. Lime and purple create a striking, memorable pairing — complementary energy without chaos. The retired colors weren't removed; they were promoted to semantic feedback roles where they earn their place through meaning rather than decoration.
Error states are deliberately soft
Knowunity's design principle 4: never amplify stress. Students come to the app feeling anxious about exams. Wrong answer feedback should say 'try again', not 'you failed'. The difference between a saturated red and a soft blush communicates that distinction without any words.
Primitive to Semantic alias chain
Following Shopify Polaris and IBM Carbon's model: 38 primitive raw values that no component ever references directly. 48 semantic tokens alias to primitives. Change purple/500 and every surface, text, and border updates automatically. Ready for dark mode by adding a single mode column.
152 tokens, rendered live.
This section is rendered directly from the token data — no screenshots. Every value here is the actual value in the system.
118 components. No hardcoded values in any of them.
Every fill, stroke, radius, spacing, and text style references a token variable. Change a primitive and the whole library updates.
Buttons: 4 types × 3 sizes × 3 states = 18 variants. Pill radius by default. Destructive uses radius/large for a slightly more contained feel.
Input fields: default, focused, filled, error, disabled states. Error borders use border/error; soft red bg communicates fixable, not broken.
Badges and tags: dot badges, count badges, label badges, filter chips, removable tags. Pill radius throughout.
Avatars: 5 sizes × 3 types × 4 status states = 34 variants. All sized for 44pt minimum touch targets.
Full component library — Card, List Item, Bottom Nav, Toast, AI Chat Bubble, and Progress Bar. All built token-bound from the start.
Figma's variable panel showing the alias chain. Semantic tokens reference primitives via VARIABLE_ALIAS, no raw hex values in the semantic layer.
Foreground tokens scoped to TEXT_FILL and SHAPE_FILL. They only appear in the right Figma pickers so designers can't accidentally apply a background color to text.
The system in use.
Three hero screens at 375×812px, built entirely from token references. Every color, spacing, and radius value traces back to a named token.
Status bar, greeting, progress card with accent/lime streak, subject cards at radius/large, bottom nav with brand accent.
Suggested chips at radius/pill, user and AI bubbles, key term highlight card, pill input bar.
Progress bar in accent/brand, correct-state card in background/success with border/success, action buttons at radius/pill.
Honest reflection.
The interesting part wasn't the output. It was the workflow. Separating ideation from execution completely meant no design-by-accident moments. When you've already agreed on a direction in conversation, the build step becomes fast and precise rather than explorative and wasteful.
The chat-first model meant every decision was documented before it was built. No backtracking through Figma to figure out why something is the way it is. The MCP's component-to-instance pattern was also genuinely fast: 48 component instances built in 156ms.
The Console MCP cloud relay drops after a few minutes of inactivity; sessions need frequent re-pairing. For longer builds, Claude Desktop with a local bridge would be significantly more reliable. Figma's API also requires FILL sizing to be set after appending a node to its parent, which isn't documented anywhere obvious.
I came into this thinking AI would speed up the execution. What I didn't expect: it mostly improved the reasoning. The decisions I made here are more considered than ones I'd have made at 2am trying things in Figma. That feels like the actually interesting thing to explore further.
Want to talk through the workflow?
This was a personal experiment but the process behind it is something I think about a lot. Happy to walk through it.









