UX CASE STUDY · DESIGN TOOLS · v1.0 shipped 2026, laptop pass Sept 2026

From a folder of 800 references to a shipped palette in under three minutes without sending a single pixel to the cloud.

Point Nitpic at a folder of references and a one-sentence brief. Get back a curated palette, a WCAG audit, and an exportable design system, in one window, in under three minutes. Everything runs locally.

SPEC · NV001
Role
Solo Designer & Developer
Timeline
v1.0, Shipped 2026
Stack
Electron · Vite + React · FastAPI · Ollama
Constraint
RUNS LOCALLY (NO CLOUD)
TOKENS PER BRIEF CURATION REQUESTAFTER vs BEFORE 22828→7500
MY ROLE002

Solo project, so I owned every layer: research, persona, IA, the visual system, the build, and the September pass that fixed the skin tone filter and made the shell work on a laptop. The audience I designed for is the audience I am: working designers and the creative directors who manage them.

Team
Solo, Designer of One
Stakeholders
Designers, Dev Leads, Creative Directors
FIG. 01v1.0, Shipped 2026
PROBLEM → SOLUTION003

The Problem vs. The Solution

Every color tool I owned wanted three jobs done on three surfaces: pick favourites in a viewer, build a palette in a swatch app, check contrast somewhere else. The work fell apart in the gaps between them.

BEFORE003.A

Three tools, three tabs, nothing talks

P-01
10 to 15 minutes per image, by handEyedrop, squint at the near-duplicate, copy the hex, lose the source. Repeat.
P-02
Auto-palettes you cannot steerFive colors, no reasons, no weighting, and the client’s brand hex is a fight to merge in.
P-03
A gap between moodboard and tokensInspiration lives in Pinterest, tokens live in Figma or code, and the handoff never quite finishes.
AFTER003.B

One window, folder to palette

S-01
Brief-driven curationType “moody cinematic noir, deep blues, one warm light” and the AI ranks every image against it. Ollama by default, Claude as the fallback.
S-02
Palette to design system, WCAG built inEight named roles across six mockups with a live contrast matrix, then a Tokens stage that exports light and dark themes as CSS or JSON.
S-03
Local-first, zero cloud costReference images stay on disk. The cloud path exists for weak hardware, not as the happy path.
THE JOURNEY004

The Journey

Folder in, design system out. Two ways through the middle: by eye with the filters, or by brief with the AI. Nothing calls a cloud model unless the designer opts in.

FIG. 02Two lanes through the middle. The cloud is a side door, not the hallway.
THE IMPACT005

The Impact

Nitpic is a personal product, so these come from benchmarking v1.0 against my own workflow.

Folder to exported palette
0min
End to end, for someone who knows the flow
Token payload cut
0%
From 22,828 down to 7,500 tokens for 150 images
AI cost per palette
$0
Default local path runs entirely on Ollama

Brief curation token payload

The first cut overflowed Ollama’s 4,096-token context. Three layered fixes brought it under.
KEY DECISIONS006

Key Design Decisions

Four calls that defined what Nitpic is, and what it deliberately is not. The full log of eight lives in the repo.

DEC-01
Three-pane shell, not a floating canvas

v0 was a single 680px column; on a 27-inch monitor half the screen was wallpaper. A Lightroom-style grid beat a Figma-style canvas.

Why

Picking colors needs the reference grid, the image and the palette visible at once. The moment one overlaps another you are working blind underneath.

DEC-02
Metadata-only curation, not vision models

The app sends a one-letter-keyed JSON catalog per image: hex, tone bucket, lightness, hue, three tags. The model reasons about color in HSL space.

Why

Vision calls cost tokens by the thousand and most local models cannot see. The catalog fits 150 images in 7,500 tokens.

DEC-03
A custom design system, C-FRG

Industrial camera: signal-red accents, amber lens motifs, Barlow Condensed display, Share Tech Mono data labels, void-black surfaces.

Why

A color tool has to show a point of view or the pitch collapses. Designers trust tools that look made by someone who uses them.

DEC-04
Skin tone as a range, seven buckets, measured before shipped

Seven Monk-aligned buckets shown as 2×2 swatch grids, and a classifier that reads real cheek pixels. The September rework moved it onto the dermatology standard, the Individual Typology Angle, and measured it before it shipped.

Why

A filter that works worse for some faces than others is not a neutral bug. If I cannot show the numbers, I have not fixed it.

UNDER THE HOOD007

Inner Workings

Three views of the same machine: what is on screen, how a dropped folder becomes catalog rows, and how a one-line brief becomes a curated set without a vision model.

FIG. 03Information architecture. One window, one local backend.
FIG. 04Drop to catalog row. Every step runs on the machine.
FIG. 05No pixels leave the machine. The model reads numbers.
LIVE PROTOTYPE008

Try the Tokens engine

The palette-to-design-system stage as a single page: pick a palette, watch the role heuristic map it onto tokens with a WCAG AA guard, flip light and dark, export CSS or JSON. The same engine that runs inside the app.

kashb.ca/nitpic-tokens kashb.ca/nitpic-tokens ↗
AFTER V1010

The September pass

Two things v1 got wrong and I only found by using it on a laptop. The skin tone filter put light-to-medium faces one bucket too light and missed small faces altogether. The shell was built for a 27-inch monitor and fell apart at 1280.

FIG. 181024 wide. Rails fold, the inspector slides over, nothing clips.
FIG. 19One bucket selected. The library here is synthetic, generated locally for the capture.
MEASURED BEFORE MERGED010.A

The classifier now reads cheek and forehead pixels from face keypoints, searches the image at three tile scales so small faces register, and buckets on the Individual Typology Angle, which uses yellow chroma alongside lightness so a brightly lit deep-brown face no longer reads as fair. Two test sets: twelve studio portraits generated locally and bucketed by eye first, and 84 faces from the CC BY FairFace set, each also pasted small onto a moodboard-sized canvas.

Portraits within one bucket of my read
12of 12, was 9
Exactly the bucket I read: 7 of 12, was 3. The old thresholds put a very fair redhead in Medium.
Small faces that get a bucket
74of 84, was 67
The ten left are black-and-white or colour-cast photos, declined on purpose.
Same face, close vs small, within one bucket
71of 73, was 38 of 65
A face should not change tone because the photo is wide.
DESIGN PROCESS011

Design Process

Double Diamond, run end to end by one person. Owning every layer makes it tempting to skip the parts you find boring, so the artifacts kept me honest.

Discover and defineAudit · teardown · persona · six-stage journey

WIRE 01Dashboard
WIRE 02Color DNA
WIRE 03Scatter map, cut

Design and deliverC-FRG system · Electron shell · v1.0 · September pass

FIG. 201366 wide, both rails open.
Discover: workflow audit, teardown of Coolors, Adobe Color and Khroma.
Define: creative director persona, six stages from Discover to Output.
Design: three dark-mode wireframes, then C-FRG.
Deliver: Electron over Vite and FastAPI, one-command launcher. Four working features cut before v1.
Revisit: the September pass, measured before merged.
REFLECTION012
The hardest part of senior design is shipping less

Four features got cut from v1 after they were built and working: a region highlighter, a dedup button, a pop-out preview, a floating tone strip. The rule I landed on: if I could not state the cut reason in a sentence, the feature stayed. The September pass taught the other half of the lesson. A feature that ships without a measurement is a feature you do not know is working.

Available for Work

Let's build something impactful.

I'm currently open to new opportunities in UX/UI Design, Product Design, and GovTech transformation roles.