• AI product
  • Design system
  • Claude Code

Vukoli

An AI interview coach that runs on your own computer, with its design system linked between Figma and Storybook

Year
2026
Role
Product, design and build
Client
Own product
Team
Solo

The task. Practising a job interview out loud, in English, when English isn't your first language, with a coach that runs on your own computer.

What I did. I took Vukoli from a personal tool to a product: research, a name, a logo, a design system in Figma and Storybook, the app itself and installers. I ran it through Project Builder, my own pipeline for Claude Code, and made the call at every gate. To carry the design system between Figma and code I built a bridge plugin and a set of skills.

The result. A public open-source app for macOS and Windows, released four days after the brief and now at v0.2.2. One design system, the same component names in Figma and in Storybook, light and dark, and not one value out of sync between them.

Constraints
  • Local firstWith Ollama nothing leaves the machine. Sessions stay as files on the user's computer.
  • No real users yetI had no one to interview, so the research ran on simulated interviews and one live test: me.
  • Figma on StarterThe Figma MCP runs out of calls fast on this plan, and one call returns 48 KB at most. A whole design system doesn't fit through that.
  • SoloProduct, design and code are all mine. The routine work runs through my own pipeline in Claude Code.

The product

You paste a job posting, or say what you want to practise. Mike, the interviewer, sets up the round, asks real questions and follows up like a person would. After the call comes a debrief across content, English and delivery.

Vukoli home in the dark theme: What are we practising today? with a composer and three suggestions
Paste a job, or say what you want to practise.

The session opens on the debrief: a verdict, the reason for it and one final score, the average of the scored skills. Below it sits a plan of up to three steps with one primary button, Drill. Then the questions, one at a time, each with its own list of feedback. This is v0.2.2, five days after the first release.

Vukoli debrief in the dark theme: Getting there, a final score of 4.7 out of 5, the level bar, a one-step plan with Drill these weak spots, and question tabs
Verdict, one score, a short plan, then the questions one by one.
Vukoli debrief in the dark theme: question 2 of 5, the answer on the left and the feedback on content, language and delivery on the right
One question: what you said, how it lands, how to fix it.
Vukoli session in the Conversation view, dark theme: Mike's questions and the candidate's answers, question by question
The whole conversation is one switch away.

It runs on Ollama, any OpenAI-compatible server, the Claude Code, Codex or Antigravity CLI, or Gemini Live with your own key. Sessions stay on the machine as JSON and Markdown. The code is on GitHub under AGPL.

Light and dark

Light and dark come from the same tokens, so every screen and every component story exists in both. In v0.2.2 the light theme turned inside out: a white sidebar, cards and composer on a grey canvas. Dark stayed as it was. Both themes are monochrome, with blue saved for the moments that matter.

Home, debrief and conversation, light to dark and back.

Chat motion

I brought the motion back from the first version of the app: a hard ease-out with no springs, shifts of 6 to 16 px, exits faster than entrances. Mike's scripted replies come without typing dots. Dots and shimmer show only while real work runs, like reading a file or preparing questions, so the app never fakes thinking.

Setting up a round with Mike, recorded on the test server with a scripted engine.

During the call a glow along the top edge shows who is talking. It's there only while someone speaks or Mike thinks. Five lobes follow the voice, and thinking is a crest of light sweeping side to side. It replaced the orb from the first designs. While you talk every loop pauses, and with reduced motion each state is one still frame.

Mike speaking, your turn, Mike thinking. Recorded from the Storybook stories.

How I run a project

Vukoli is the first project to go through Project Builder from the brief to a public release. Project Builder is my template for product work: the rules I follow as a product designer and front-end developer, written down so Claude Code can follow them too.

Redesign trackProject Builder · Vukoli
  1. RulesDirectives
    Lessons from past projects
  2. TriggerBrief
    Stages 00–01
  3. OrchestratorPick the next stage
    18 stages · 6 phases
  4. Claude CodeAgents run the stage
    8 roles + scripts
  5. OutputA page per stage
    CSV · Excel · Markdown
  6. Human · VladApprove the phase?
    5 gates · D1–D101
    No · changes → Agents run the stageYes · next phase → Pick the next stage
  7. Stage 14Retro
    61 lessons
    Lessons go back into the template → Directives
  8. Releasev0.1.0 on GitHub
    4 days from the brief
Directives say what, agents do the expert work, scripts do the repeatable part. The decisions stay with me.

Every stage ends with a page I can read in a minute and send to anyone: what was done, the numbers and the open questions. My decisions get numbers, D1 to D101 so far, so any change in the code points back to a decision.

The Scope and PRD page: a TL;DR and four numbers: 43 owner decisions, 38 plus 4 Must features, 65 features scored, 108 points
Scope and PRD, signed off at the definition gate.

Timeline

Vukoli went on the redesign track of the pipeline, because a personal tool already existed. Every phase ended at a gate I had to approve. The IA started before its gate because I wanted speed, and the retro called it out.

  1. Discovery
    • BriefOct 19
    • ResearchOct 19
  2. Definition
    • IA and flowsOct 19–20
    • Scope and PRDOct 19–20
  3. Design
    • Moodboard and tokensOct 20
    • Design systemOct 20
    • Review, v1 to v36Oct 20–21
    • Figma bridgeOct 21
    • Kit in FigmaOct 21
  4. Build
    • Front endOct 21–22
    • Design QA and my testOct 22
    • RetroOct 22
  5. After release
    • v0.2.0, v0.2.1Oct 23
    • New debriefOct 24
    • v0.2.2Oct 27
  6. Design approved
  7. v0.1.0 public
Days from the project log, October 2026.

Research

The audience is IT people who interview in English as a second language. Before the PRD I ran competitors, a UX audit of a similar product, proto-personas and simulated interviews with them. Each step is a skill I wrote earlier: competitive-research, ux-audit, proto-personas and simulated-interview.

Simulated interviews test hypotheses, they don't confirm them. The only live test so far is me using the app before my own interviews.

Design review

I don't start screens in Figma. They're built in code from the design system's tokens and components, and a review page shows each one with a comment field under it. I leave comments, copy them all in one click and paste them back. The next version answers every comment.

  • 47DecisionsMade in about a day and a half, as comments under screens.
  • 36VersionsOf the review page, from the first layout to the approved one.
  • 0CallsEverything went through the page.

I turned down v1 whole. It was laid out from the PRD's feature list, and I wanted a chat, like ChatGPT or Ollama. From v2 on, home is a greeting, one field and up to three suggestions.

The name

  • 12CandidatesThe first list of names, before any checks.
  • ~150DomainsChecked through RDAP, so most of the list fell out early.
  • ~350One-word namesA second, wider round of short invented words.
  • 1VukoliVOO-ko-lee. .com, .app and .dev free, no trademarks found on Trademarkia.

The logo took six rounds with Claude. I turned down two rounds of symbols, then drew the lockup and the icon myself as sketches, and the final grew out of them.

On the left, two sketches: the lockup and the app icon. On the right, the final vukoli lockup and the blue gradient app icon
My sketches on the left, the final lockup and app icon on the right.

The mark is a rounded shield, filled with one gradient from pale sky to deep navy. The wordmark is Manrope Bold with tight tracking. A check against 1,400 logos found Vuetify, Vue and Vitest closest.

Figma and Storybook

The tokens live in one file in the W3C format and compile to CSS. 142 text and background pairs pass 4.5:1. Then I moved the system onto Untitled UI PRO: names from Untitled UI, values from Vukoli. That's 80 colour roles, 23 of them with Vukoli values and 29 extra ones the kit doesn't have.

There are 42 components in code. In Figma, 18 sets are adapted from the kit and 25 are built for Vukoli. Every set has the code name and its story in the description, and a link to the story. About 40 shots compare Figma with Storybook in both themes. After an audit I rewrote the stories for 31 components.

Storybook holds 548 stories: every component with its states, and every screen state the app can reach. Props are live controls, and a toolbar switch flips the theme.

Storybook: the component list on the left, the ChatMessage conversation story in the dark theme, and its props table below
ChatMessage in Storybook: the component list, the story and its props.
Storybook: every state of the StatusPill from Connecting to Muted, in the dark theme
StatusPill, every state on one canvas.

The link itself comes from my figma-storybook-sync skill. On Vukoli it hit a flat folder layout it didn't know, and after the fix it covered 41 components instead of 0.

The bridge

Adapting a design system means hundreds of writes to Figma. Through the MCP on Starter that's a call limit and 48 KB per answer. So I wrote a bridge: Figma runs the same scripts, but through my own plugin.

Figma bridgeClaude Code → Figma
  1. Claude CodeWrites a job
    Plugin API code, as for the MCP
    MCP stays for screenshots and reads → Design system
  2. Bridge · PythonKeeps a job queue
    Local only, a token per job
  3. Figma dev pluginRuns the next job
    Same scripts, my own plugin
    Result back through the server, whole, into a file → Writes a job
  4. Figma fileDesign system
    32 sets · 44 text styles
Writes go through the bridge, reads stay on the MCP. No MCP call limit, no 48 KB cap on the answer.
  • 32Component setsBuilt from the code in one pass.
  • ~60 sText stylesAll 44 text styles created in about a minute.
  • 0Mismatches159 values updated and 35 new variables added, then a check across 292 found nothing off.

The bridge only listens on the local machine and checks a token on every job.

Testing

Three kinds of checks ran on the build, and each caught things the others didn't.

  • 162 / 162End-to-endOn desktop and phone widths, against a scripted engine, so no model is needed.
  • 20Design QA findingsScreen by screen against the stories and the spec. All closed in two rounds.
  • 0 of 5PredictedOf five problems from my live test, simulated users fully predicted none and one in part.

The end-to-end suite was green at 144 out of 144 while design QA and simulated users found two serious bugs. The test helper clicked the feedback toggle itself, so it never noticed the panel didn't open on its own.

Simulated users read screenshots, so speech, timing and in-between widths slip past them. They're good for a second opinion, not for the final word.

Retro

The retro reads the project log and the session history, not my memory of them.

Worked

  • A review page with comments47 decisions in about a day and a half, no calls.
  • Parallel agents on separate filesOne batch of changes took about ten minutes instead of an hour.
  • Live checks on a scripted engineEnd-to-end runs found three gaps against the acceptance criteria that stories and simulated users missed.

Didn't

  • Slow small stepsA full end-to-end run takes about ten minutes, and small visual fixes went one by one.
  • Usage limitsAll the heavy work ran on Claude. Next time part of it goes to other models.
  • Work ahead of the gatesThe state caught up after the fact.

My own remarks were the most useful data. Out of 113, nine were some form of "fixed, but it doesn't work" and about ten were "make it like Claude or Gemini". So now a hook won't let Claude Code report a task done without a live check, and "like X" means screenshots of X before any code. The design QA role reports and can't edit code, so it can't quietly fix what it was meant to find. 61 lessons went back into the template across 23 files.

Handoff skills

The Figma side of the process is packed into skills Claude Code can repeat on the next project. Four more came out of the retro.

  • figma-bridgeRuns Plugin API code in Figma through the bridge, without the MCP.
  • figma-storybook-syncTokens to Figma Variables, the same component names in Figma and code, links both ways.
  • verify-liveScreenshots before and after. A hook won't let Claude say done without a check.
  • feedback-intakeTurns my dictated remarks into a checklist, hands it to agents and returns a was → now table.
  • open-localStarts the server, the web app and Storybook in one go.
  • usage-reportShows where the tokens went in a session.

Results

4 days
from the brief to the first public release
0 / 292
values off between Figma and code after the sync
162 / 162
end-to-end runs pass on desktop and phone
20
design QA findings, all closed

More work