source-first-ui
Skill0 starsChanged 2 months agoMITView on GitHub
Research, judge and freeze every design decision for an interface the way a designer does - read the real market first, then render whole systems and look at them. Use before building any interface: it derives what the repo already knows, asks eight things only a human can answer, reverse-engineers the actual type scale, radius, shadow and palette off competitor sites, generates three complete design directions constrained by that research, renders them as real pages to screenshot and judge, then freezes the winner into design/tokens.css and design/DESIGN.md so the build phase cannot drift. Covers icons, typefaces, colour, radius, shadow, spacing, motion and component libraries as one system. Run it before design-taste-frontend builds anything.
In this repository6 other files it gives its agents.
- 9am-architectureSkill
- amar-protocolSkill
- graphifySkill
- prototypeSkill
- routeSkill
- triageSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 32
Before any interface work.
- Distinctive: line 43
Run them in order. Every phase writes a file the next one reads, so nothing is asked twice and nothing is decided in a chat message that …
- Very specific: line 55
All scripts live in scripts/ and print usage with no arguments.
- Very specific: line 92
Never block: Every question has a default.
- Very specific: line 149
Read references/market-profiles.md now, and add to it.
- Very specific: line 224
Check the survivor against hard_no in the brief and against the market profile before freezing.
- Distinctive: line 242
Verify anything you plan to import before importing it:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
source-first-ui
A model asked to design something answers from memory: Inter, Lucide, 12px radius, a soft shadow. That is not a decision, it is a recall - and it is why generated interfaces are recognisable on sight.
A designer does something different, and it is not mysterious:
read the real market → commit to a stance → render it → look at it → freeze it.
Two steps are the ones a model always skips. It never looks at the real sites first, so it reproduces the market baseline by accident. And it never freezes the result, so page 9 stops matching page 1.
This skill does the whole loop. It is not an icon picker.
When this runs
Before any interface work. It runs BEFORE design-taste-frontend: this skill
decides what the materials are, that skill builds pages with them and is
explicitly forbidden from re-deciding (see its "frozen tokens win" block).
Skip it when design/tokens.css already exists - read that instead and say so.
ui-ux-pro-max's offline CSV is a fallback only when there is no network.
The six phases
Run them in order. Every phase writes a file the next one reads, so nothing is asked twice and nothing is decided in a chat message that gets lost.
design/BRIEF.md who and what (phase 0)
design/field-notes.md the real market (phase 1)
design/directions.json three systems (phase 2)
design/suite.html the render (phase 3) <- the decision happens here
design/tokens.css frozen values (phase 5)
design/DESIGN.md the reasoning (phase 5)All scripts live in scripts/ and print usage with no arguments.
Phase 0 - derive first, then ask eight things
Derive what the repo already knows. Asking a human for facts that are sitting on disk is rude and slow:
node ~/.claude/skills/source-first-ui/scripts/brief.mjs derive --dir .This reports the stack, fonts and colours already in use, the real colours read out of the logo file (it decodes PNG and SVG), and the field names on the main database record - which decide the card layout more than any taste question does.
Then ask the eight questions only a human can answer, in one batch, using
AskUserQuestion so the user clicks instead of typing:
node ~/.claude/skills/source-first-ui/scripts/brief.mjs questionsAudience · main action · what the eye hits first on a card · languages · what makes a stranger trust this market · what is already locked · reference sites they like and hate · what must not appear.
Rules, and they matter more than the questions:
- Eight, not twenty. A long interview gets abandoned and half-answers are worse than none.
- No design jargon. "Type scale", "elevation", "density" are banned in the interview. Ask in the words the user actually uses.
- Never ask about taste. "Modern or classic?" gets a useless answer. Taste is settled in Phase 4 by pointing at a render.
- Never block. Every question has a default. Anything unanswered is written
into
assumptionsand stated in the reply. - When the user said "kar do" / "just build it": skip the interview entirely. Derive everything, record the assumptions, and show three directions anyway.
node ~/.claude/skills/source-first-ui/scripts/brief.mjs write --project NAME --answers answers.jsonanswers.json is { "audience": "...", "primary_action": "..." } keyed by
question key. The brief is written once and never re-asked - later phases
read it.
Phase 1 - look at the real market (the step that was missing)
This is what makes the difference between a design and a template. A model starts at Iconify. A designer opens fifteen real sites in the market first, because the thing they all do is the baseline you are about to reproduce by accident.
A human reverse-engineers those numbers by eye. We read them exactly:
node ~/.claude/skills/source-first-ui/scripts/field.mjs probe zameen.com graana.com ilaan.com --saveHeadless, no browser needed. It returns each site's real typefaces, its radius histogram and dominant radius, its shadow language, its type sizes, its palette, and its template tells - carousel plugins, Font Awesome, stock photo hosts, thirty different corner radii, stock Bootstrap.
For the three or four sites that matter most, get the computed truth instead of the parsed stylesheet. Open the site in the browser pane and run:
node ~/.claude/skills/source-first-ui/scripts/field.mjs scriptPaste that output into javascript_tool, then feed the result back:
node ~/.claude/skills/source-first-ui/scripts/field.mjs record --url https://site --file out.jsonScreenshot each reference into design/refs/<host>.png. The numbers say what
they did; only the picture says whether it worked. Then:
node ~/.claude/skills/source-first-ui/scripts/field.mjs notes --out design/field-notes.mdThree lists come out. The first is the one nobody writes down and the one that matters: what they ALL do. Then what one site does differently - those are the openings. Then what reads as cheap.
Read references/market-profiles.md now, and add to it. It holds the knowledge
no registry has: what signals trust in this specific market. If the market has
no profile yet, write one before Phase 2, not after.
Phase 2 - three complete systems, not three loose picks
node ~/.claude/skills/source-first-ui/scripts/directions.mjs makeA direction is a whole coherent stance - radius, shadow, border weight, spacing
base, type scale, two or three typefaces, icon family, palette and motion, all
chosen together. Mixing a soft radius with a hard shadow and a grotesque is what
"AI-made" looks like; the eight archetypes exist so that cannot happen
(directions.mjs archetypes lists them).
Five constraints are applied automatically, and they are the whole value:
| Constraint | Effect |
| the brief | decides which archetypes are eligible at all |
| the field notes | force at least one direction to break the market baseline |
| rotation memory | blocks the archetype and icon sets the last project used |
| competitor fonts | banned outright - if zameen.com runs Lato, we do not |
| contrast | every pair repaired to WCAG AA before it is written |
Two more things it gets right that a recall never does:
- The accent is seeded from the logo, not invented. A brand that already has a colour does not get a new one.
- A second script gets its own face. For Urdu or Arabic, the Latin face is chosen on Latin merit and a script-matched companion is chosen separately. Setting English in Lateef is the typographic version of a wrong icon.
Phase 3 - render whole pages and LOOK (never skipped)
node ~/.claude/skills/source-first-ui/scripts/suite.mjs
node ~/.claude/skills/source-first-ui/scripts/serve.mjs design --port 4321Each direction renders as a small but complete page using the project's own content - the real headline, the real rupee figure, the real Urdu line, the real record fields - on the light ground at desktop width and the flipped ground at 380px. A card holding "Lorem ipsum" and "$99" proves nothing.
Open http://localhost:4321/suite.html in the browser pane and screenshot it.
Browser pane constraints - follow them or the screenshot comes back blank:
file://is refused. The little server is not optional.- The screenshot does not follow
scroll. Useresize_windowwith a tall viewport (1150x1500 for one direction, 1150x4600 for all three) so the part you want is inside the frame. Reset with presetdesktopafterwards.
Then actually judge the image. Reasons that count are only visible in the render:
- does the price still dominate the card, or has the photo eaten it
- does the headline fit in two lines at the planned size, or run to three
- is the icon weight consistent with the text beside it
- does the glyph still read as the object it names at 16px
- does the Urdu line sit correctly against the Latin, or look bolted on
- does it survive the flipped ground
- does it look like the sites in
field-notes.md, or not
Phase 4 - the call
Narrow to two, show them, let the user pick. Do not pretend the tool decided.
Check the survivor against hard_no in the brief and against the market profile
before freezing.
Phase 5 - freeze, or the whole thing was theatre
node ~/.claude/skills/source-first-ui/scripts/tokens.mjs freeze --pick 2 \
--why "..." --rejected "1: ..." --rejected "3: ..."Writes design/tokens.css (every value, plus the generated dark counterpart and
a reduced-motion block) and design/DESIGN.md (the pick, the reasons, the exact
identifiers, the licences, what lost, what was not looked at). It also records
the decision in the cross-session memory, so the next project is blocked from
reaching for the same answer.
Verify anything you plan to import before importing it:
node ~/.claude/skills/source-first-ui/scripts/libcheck.mjs <every package>Exits non-zero if a package does not exist, is deprecated, or carries a licence
that is unsafe for client work. references/licences.md has the one-line
meaning of every licence you will meet.
Phase 6 - hand over
Tell design-taste-frontend to build. It reads design/tokens.css and is
forbidden from re-deciding colour, type, radius or shadow. That handover is what
keeps page 9 looking like page 1.
What the reply must contain
Without these the loop did not happen:
- The pick, by number, with a reason tied to something seen in the render.
- Every rejected direction and why - one line each.
- The exact identifiers (
ph:house,Sentient 500, not "a serif"). - The licence of everything being shipped.
- What the field research found - the market baseline, and whether this breaks it.
- Any assumption recorded because a question went unanswered.
- What was not looked at.
Failure modes this exists to prevent
| Failure | Caught by |
| Reproducing the market baseline by accident | Phase 1 measures it; Phase 2 forces one direction to break it |
| Using a competitor's typeface | Phase 2 bans every font the field research found |
| Inventing a brand colour that already exists | Phase 0 reads it out of the logo file |
| English set in an Arabic-script face | Phase 2 picks the two faces separately |
| A monospace face as body copy | Phase 2 rejects mono for text roles by name, not category |
Wrong glyph, right name (solar:card-search for "search") | Phase 3 - visible in the render |
| A glyph that dissolves at 16px | Phase 3 - real interface sizes |
| Inaccessible palette shipped then audited | Phase 2 repairs contrast before writing |
| Same font on every project | Fontshare first, --skip-top, rotation memory |
| Non-commercial licence in client work | Phase 5 + references/licences.md |
| Page 9 not matching page 1 | Phase 5 freeze + the design-taste-frontend rule |
| Interview asked twice | BRIEF.md is written once and read thereafter |
Honest limits
- The final call between two good directions is the user's. Narrow to two, render, let them point.
- Market judgement is not automatable. It lives in
references/market-profiles.mdand only a human can put it there. - Only free libraries are searched - Google Fonts, Fontshare, Iconify, npm, shadcn registries. Adobe Fonts and commercial foundries need a login and are out of reach. Say so.
- Whether the design converts is an A/B test, not a design review.
- Real device testing still needs a real device. The 380px render catches most cut-off text, not all of it.
- Cost. A full loop is roughly 80,000 to 120,000 tokens against about 5,000 for answering from memory. That is the price of not looking templated, and it is paid once per project, not per page. Say so if asked.
Scripts
| Script | Does |
brief.mjs | Phase 0. Derives stack, fonts, colours, logo palette (decodes PNG/SVG) and record fields; holds the eight questions; writes and reads BRIEF.md |
field.mjs | Phase 1. Probes real sites headless, emits the browser-pane extractor, builds field-notes.md |
directions.mjs | Phase 2. Eight archetypes, five constraints, contrast repair, dual-script typography |
suite.mjs | Phase 3. Renders whole pages with the project's own content, both grounds, desktop and phone |
tokens.mjs | Phase 5. Freezes tokens.css + DESIGN.md, records the decision |
icons.mjs | Iconify search, family licences, glyph synonyms, resolve, contact sheets |
fonts.mjs | Google Fonts and Fontshare; --skip-top is the anti-slop lever |
libcheck.mjs | npm existence, last publish, downloads, deprecation, licence |
sheet.mjs | The single-decision contact sheet (icons, fonts, raw) |
serve.mjs | Static server, because the browser pane refuses file:// |
picks.mjs | Cross-session memory of picks and, more usefully, of rejects |
References
| File | Read it |
references/market-profiles.md | before Phase 2, always. Add to it. |
references/licences.md | before shipping anything |
references/spec-format.md | only when hand-writing a sheet.mjs spec |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

