Foundations
The cross-cutting modules: motion principles, the design audit, the tells, the UI/UX dataset, the mobile and desktop platform layers, and the orchestration bunshin runs its clones with.
All documentation
These seven are not tied to a framework. They carry the parts of the craft that transfer between web, Apple and Android, the layer that checks the work before it ships, and the one that lets a team of agents do the work together.
motion-principles
The foundation, loaded on every single invocation. It is the reason a spring in Compose and a transition in CSS come out of the same pipeline feeling related.
It carries a duration table keyed by context rather than by taste (micro-interactions 100 to 150ms, UI transitions 200 to 300ms, route transitions 300 to 500ms, scroll-driven work progress-based with no duration at all), and the frequency rule: the more often an animation plays, the shorter and subtler it has to be.
Easing is chosen by direction. Entering elements decelerate, exiting elements accelerate, elements moving between states ease both ends, scroll-synced motion is linear because anything else reads as lag. Exit is always more subtle than enter.
It also carries a cross-platform equivalence table, so cubic-bezier(0.2, 0, 0, 1),
SwiftUI’s .snappy, and Compose’s spring(stiffness = StiffnessMedium, dampingRatio = 0.85f) are understood as the same intent expressed three ways.
Finally it carries five prohibitions, each with the wrong and right form in all
three stacks: never animate width, height, top or left; never scale to
zero; never ease-in on an entrance; never exceed 500ms on a UI interaction; never
skip reduced motion. Those are spelled out in Principles.
design-audit
The closing checkpoint. It runs a tested script rather than hand-written greps,
which is what makes it catch things a read-through misses, and every finding
comes with file:line.
The hygiene checks look for conditional renders with no exit animation, :hover
rules with no transition on the base selector, animated layout properties,
outline: none without a :focus-visible replacement, clickable divs without a
role, decorative motion missing aria-hidden, broad will-change, animation
loops driven from JavaScript timers, and a total absence of reduced-motion
handling in an animated project.
A second group, the tells, runs eighteen checks over the text a page actually displays and its markup, and over the classes and CSS for the few tells that live there: invented build statuses, weather and locale strips, part numbers that point to no catalogue, numbered eyebrows, generic step labels, scroll cues, placeholder names, suspiciously round numbers, filler verbs, em dashes, runs of middle dots, the same call to action under several labels, three identical cards, gradient text, glows, glass panels, blurred blobs and animations that never stop. Tells are reported apart, at the lowest severity, because what they weigh is decided against the thesis, not by the script.
It also takes an inventory of what the project really uses: distinct durations, easings, colours, radii and font families, each with where it was found. A well-designed project uses three to five durations and three to five named easings. Fifteen distinct duration values is a finding, not a style.
What a script cannot see, like frame timing or a real device, is handed over marked unverified, with the exact thing to run.
tells
The catalogue of defaults a model produces when nobody asked for them. It loads on
a web stack once a thesis exists, because a tell only means something against
one: a pattern is a tell when the validated thesis did not ask for it, and an
exception has to be named in the thesis’s own Allowed patterns: line. A mood
word like “editorial” does not unlock anything.
Every entry has the same three parts: the marker you can see, why models produce it, and a question that sends you back to the thesis or to the project’s own data. There is never a fourth part telling you what to use instead.
The web catalogue holds forty-two entries, and every one of them is in the tells field guide with the question it asks. They fall into four families:
- Invented information. Data that came from nowhere: a build number, a city and its weather, a founding year, a stock counter, a placeholder name.
- Decorative filler. Elements that carry texture and no information: numbered eyebrows, pagination on tiles, scroll cues, decorative status dots, glows and blurred blobs.
- Reflex convergence. Choices that came from the model’s habits rather than the thesis: three equal cards, a zigzag repeated down the page, one layout family everywhere, a display face picked as the default creative move, a warm paper ground on a brief that never mentioned paper.
- Hollow copy. Sentences that could sit on any site: filler verbs, the same call to action under three names, poetic labels, a register that changes from one section to the next.
Web is covered today. The Compose and SwiftUI sections exist and say “not covered yet”, because that material has to be observed rather than made up. Tells are observations of how models behave, so they are dated, and one that stops showing up in runs without genjutsu becomes a candidate for removal.
ui-ux-pro-max
A searchable design-system dataset with a CLI: 84 styles, 192 palettes, 74 font
pairings, 25 chart types and 99 UX guidelines across 22 stacks. paint loads it
during the design-system phase to ground palette and typography choices in
something with structure rather than in invention, and treats what it returns as a
proposal that the thesis and the tells get to veto.
Internal, and not invokable on its own.
mobile-principles
Loads when the target is mobile web or native iOS or Android.
Touch target minimums, the no-hover doctrine (hover cannot be the only way to reach anything, and press states have to carry the feedback instead), thumb zones and what belongs in reach, safe areas, canonical gesture patterns and the conflicts between them, mobile performance budgets, and a unified cross-platform account of reduced motion.
desktop-principles
Loads for macOS or for desktop web with no mobile indicators.
Hover states as mandatory rather than decorative, pointer precision and what it allows that touch does not, keyboard shortcuts as first-class rather than optional, multi-window state coherence, focus management, information density, and the subtle-animation doctrine: desktop motion is shorter and quieter than mobile motion because it fires far more often.
orchestration
Loaded by bunshin alone, at the summoning, before the first clone. A clone is a
subagent that starts from nothing: no conversation, no memory of the thesis, no
idea which files its siblings are editing. Everything it knows is in its brief,
and everything that goes wrong in a fan-out goes wrong because a brief left
something out. This module is how the clones are briefed, fenced, checked and
stopped, so that ten agents in parallel produce one site and not ten opinions.
The brief. Six parts, in order: who the clone is and what it builds, what to
read first by absolute path, the exact files it owns, the rules that do not move
(the validated theses with their Allowed patterns: line, the voice, the truth
rule, mobile first, reduced motion), how it verifies, and the shape of what it
returns. A seventh, what is already verified, keeps reviewers from spending a
lens on a green build.
Ownership. One owner per file, declared before the fan-out, and kept on disk
as data. Page clones never edit a shared file: a shared need comes back as a
request. When a shared contract changes, the shared owner runs first and alone.
Isolated builds. Each clone builds in a copy of the project outside it, with
the framework’s own binary and never the package manager: in a copy linked to
the project’s node_modules, pnpm build decides the install is foreign and
reinstalls through the links into the real one. The copy links node_modules
entry by entry, so parallel builds never write into the project’s own caches,
and green means the build printed exit code 0.
Evidence. Reviewers judge what renders, so every review starts from captures
of every page at 390x664, 390x844, 1280x720 and 1440x900, taken by shoot.mjs
from the static build: a zero-dependency script that drives a headless Chrome
and answers every request to its made-up origin from disk. No dev server runs
and no port is fixed: the only socket is the browser’s DevTools endpoint, on a
free port the operating system picks, so every clone captures at once. Requests
to other origins go to the network, nothing outside the build folder is served,
and a shot that fails comes back with its error without stopping the others.
The same shots run scripted tests of the paths that sell and report the value
each one measured.
Lenses, plan, verdict. Five lenses (finish, mobile, desktop, truth,
tech), three on the lean tier, each on the same packet and blind to the
others. With Impeccable installed, finish is its shipped finish reviewer,
spawned by the agent type the host lists and answering in its own contract: a
disposition, then five sections (persistence, fidelity, ceiling, material
fixes, keep), and a recapture carries only its list. When the host does not
list that agent type, its degraded role file is passed as finishRole. One
plan clone deduplicates, verifies every finding against the code and the
captures, rejects with a reason, and groups the fixes by owner, on disk;
review.js draws no plan on a recapture or a rebuild. After each round of
fixes, the finish reviewer scores every fix resolved, partial or unresolved,
and names at most three regressions, with no new hunt. verdict.js writes the
next round’s plan from its remaining points, with an empty fixes list when
nothing is left. When the tier calls for it, a cold-eyes art director, who has
read nothing, says what still looks like a template. Its notes become rules in
a decisions file, never a task list: that step is art direction, and it is
never delegated.
The stop rule. The finish reviewer’s disposition first: recapture means
the evidence failed, so nothing that pass said binds until the pages are
captured again, and rebuild means a full review after the rebuild. Then: nothing above
minor left, the tier’s round cap, or a round that fixed nothing. Never one more
round for the minor points.
The templates. Each fan-out (research, build, review, refine, verdict) is a
workflow script under the module’s workflows/ folder, parameterised entirely by
its arguments. CI runs each one against stubbed agents: to the end with every
agent answering, and again with every agent answering null, where it must end
or stop on a deliberate error, never crash. The run bunshin was drawn from lost
a whole fan-out to a placeholder string where a script expected an array, so the
plan now travels as a file on disk, never through the arguments, and the
templates refuse a string where they expect a list. The two that build, build.js and
refine.js, quote every path, print the build’s real exit code, and refuse a
package manager as the build command. With a workflow tool they run as written;
with only a subagent tool, the template is the plan and the same clones are
spawned by hand. Each one returns what the next decision needs and writes the
rest to disk.
The scripts. Two, both without a dependency. shoot.mjs takes the captures
above. brief.mjs is for a host with a subagent tool and no workflow tool: it
runs a template against stand-in agents and prints every clone it would spawn,
with its label, agent type, schema and exact prompt, so nothing is rebuilt by
hand.
It also carries the per-unit costs of one measured run (a seven-page site in
two languages) that bunshin builds its tier estimates from, says where they
come from, and names the two it could only estimate: a three-lens review with
its plan, and a verdict without cold eyes.