cast
The Illusionist. How the cast pipeline reads your stack, states an interaction thesis, implements motion in your own APIs, and audits the code against the thesis.
All documentation
cast gives an interface motion. It adapts to what is already there, which makes
it the right entry point for anything short of a full visual rebuild: a hover
state, a section, a scroll narrative, a whole page that feels inert.
With the Claude Code plugin it is /genjutsu:cast. After an npx install or on
claude.ai, type /genjutsu or just ask; the router sends motion work here.
The pipeline
Seven stages. Two of them are gates where nothing proceeds without you.
1. Scan
Before asking you anything, it reads the project. On web that means
package.json for the framework, the CSS layer, and any animation library. On
Apple it means Package.swift or the Xcode project, distinguishing iOS from macOS
by platform declaration or SDK root. On Android it means the Gradle files,
including whether the Kotlin Multiplatform and Compose plugins are both present.
It also works out whether the context is mobile, desktop, or both, and notes
whether the project mixes modern UI with legacy layouts (XIBs, storyboards, layout
XML, setContentView).
The scan decides which modules load later. You do not get asked what stack you are on, because the answer is in the repository.
One check follows the scan, before anything is asked. When the request is a whole
site or web app on a web stack (or no project yet), the session can spawn
subagents, and the brief has real material, two audiences or languages, a first
version meant for a client, or asks for the full treatment, cast proposes
bunshin once, with its cost range and the two times it would
ask you. It switches only on a yes, and never proposes it again in that session.
With nobody there to answer, it names bunshin in one line and in the final
report, and carries on.
2. Discover
It starts by saying what it thinks it is looking at, in one line: what the product is, who it is for, the direction it seems to be heading, and the stack. Then it waits for you to correct it before asking anything else. A wrong read caught here costs one sentence.
Discovery is skipped when your request is already specific. “Add a hover scale on this button” needs no interview.
It is used when the request is open-ended. “Make this page feel more alive” could go in a dozen directions, so it asks: mood, references, constraints, what is explicitly out of scope. One question at a time, because the second question depends on your answer to the first.
Vague answers get pushed on rather than silently interpreted. “Something modern” comes back as a question about what the motion is for: at the moment this moves, should someone feel that it is fast, that it is precise, that something was saved? The options come from the product’s own moments, never from another brand’s site, because naming one anchors the thesis on a famous default. If that stalls, the inverse question follows: what would feel wrong.
3. Scope
| Scope | Example | Modules | Variants |
|---|---|---|---|
| Light | One isolated component: hover, toggle, dropdown | 1 to 2 | No |
| Medium | A page or section: hero, gallery, navigation | 2 to 3 | 2 to 3 |
| Full | An app, or a complete overhaul | Full pipeline | 2 to 3 |
The rule this table exists to enforce: a hover effect never justifies a scroll-driven animation pipeline.
4. Thesis, and this is a gate
One sentence, naming the feel and the technique. Three examples of the form:
This dropdown will use 150ms CSS micro-transitions with slide plus fade, for a snappy, modern feel.
This hero will combine scroll-triggered parallax with staggered text reveals, for cinematic impact.
This SwiftUI tab transition will use
matchedGeometryEffectwith a.smoothspring (response 0.5, damping 0.85), for a tactile, spatial feel.
It also has to pass a guessability test: a thesis that could have been written from the product category alone is the category’s default motion, not a decision, and it is rewritten from this product’s own moments.
Under the thesis sits one more line, Allowed patterns:, naming every deliberate
device the design relies on that could pass for decoration or habit: mono labels,
hairline rules, a looping animation, a live clock. It reads
Allowed patterns: none when there are none. You see the list before you say yes,
and the audit reads it: a tell counts as allowed only when this line names it.
Nothing is written until you validate it. If you reject it, it does not start over from zero; it asks what feels wrong and adjusts.
Before the first gate that shows you something, it asks once how you want to see it: a rendered page if the session can render one (on Claude, an artifact), otherwise a throwaway HTML file; a live preview route in your own project; or plain text in the conversation. The choice holds for the session. The preview carries what a sentence cannot, like the easing curve plotted with its exact value and an element actually performing the motion, and it is never ported into the real implementation. What each mode means on each host is further down.
The reason this gate exists is arithmetic. A wrong thesis caught here costs one sentence. Caught after implementation, it costs the implementation.
5. Load
Motion foundations always. Then the platform layer (mobile or desktop
principles), the stack modules the scan identified, and the audit module when the
scope is full. On a web stack at medium or full scope it also loads tells,
right after the thesis is validated, so the defaults it lists are avoided while
the code is written rather than found afterwards. See
the module reference for what each one carries.
Modules load in separate shell calls, one per heavy module, so no single read is too long for the agent to see in full.
6. Implement
Light scope goes straight to code. Medium and full scope propose variants first, graded by how far they push:
Variant A (subtle) - the feel, and the technique, in one line. Variant B (balanced) - the feel, and the technique, in one line. Variant C (impressive) - the feel, and the technique, in one line.
You pick before anything is written. Whatever you pick, the validated thesis still governs; a variant is a way of expressing the thesis, not a way around it.
If the motion the thesis promised cannot be delivered in working order, cast
ships the static version and says so. Half-broken motion is never the fallback.
7. Audit
Not optional, not skipped because the result looks good. The audit is split into what can be checked here, with evidence, and what has to be handed to you.
Checked here, with evidence. The first item is the thesis against the code:
every promise the thesis made (durations, easing, springs, palette, type, layout
family) is matched to the file:line that keeps it, or reported as missing.
Then reduced-motion support, exit animations, no layout-property animation,
visible focus, all five interactive states, tokens rather than magic numbers,
computed contrast (4.5:1 for body text), and semantics. When tells was loaded,
the tells audit runs too, and every finding is confronted with the thesis. It has
one of three outcomes: the audit quotes the entry of the Allowed patterns: line
that allows it; it is not this tell, when the detection contradicts the
entry’s own marker (a loop that reports a real loading state, a blur that is a
modal backdrop), with the file:line that proves it, and never on a matter of
taste; or it is a problem. A problem on a line the run wrote is fixed before the
report, and the check runs again, two passes at most; what still fails is
reported with its file:line. A tell that was already in your project is listed
for you and never changed by the audit.
Handed over, marked unverified. An agent cannot open a profiler or move a pointer, so frame timing, the four breakpoints (375, 768, 1024, 1440), Reduce Motion on a device, recomposition counts on Compose, and the Hitches instrument on SwiftUI come back as a block with the exact thing to run and the pass condition. They are never ticked on its word.
The report reads like “9 checked, 2 problems found, 8 handed over”, and it ends with two lines naming the modules that loaded and the ones that did not.
When nobody is there to answer
Some sessions run without a human, in a pipeline or an evaluation. cast then
takes the preview mode it announced, takes the thesis it proposed and labels it
as not validated, installs nothing, and marks the final report UNVALIDATED so no
one mistakes it for an approved direction.
The preview, host by host
cast and paint ask the same question, once, before the first gate that shows
you something: a rendered page, a live preview, or inline. The answer holds for
the session. Later gates announce the mode in one line, and you switch by saying
so (“show me that as text”, “put it on a page”). Whatever the mode, the preview is
throwaway: it exists to be looked at, never to become the implementation.
A rendered page carries the easing curve plotted with its exact value, an element performing the motion with a replay button, the raw numbers and a reduced-motion toggle; for a design system, swatches with their contrast ratios, a real type specimen and the five states of every component. Inline is the sentence, which is still the right answer for a 150ms hover.
| Host | Rendered page | Live preview | Inline |
|---|---|---|---|
| claude.ai | A native artifact | A throwaway route in your project | Text in the conversation |
| Cowork | The host’s persistent artifact, which outlives the turn | Usually unavailable: often no project checkout to write into | The host’s inline widget |
| Claude Code | The Artifact tool when the session has it, else as on any other host |
A throwaway route, or a @Preview / #Preview scratch file on Compose or SwiftUI |
Text in the conversation |
| Any other host | Its HTML rendering tool if it has one, else a throwaway HTML file, opened in a browser the session can drive or handed over as a path | A throwaway route | Text in the conversation |
An option that cannot work on the host is not offered, and one line says why. When nothing can render a page, the gate falls back to inline rather than failing.
The gate works out the host itself, before any module loads. Cowork is checked
before Claude Code: both can have a ~/.claude folder, and only Cowork has the
per-session skills mount, so the more specific signal wins.
bunshin never asks this question: its direction cards go on Impeccable’s
decision page when it is installed, and on a rendered page, announced in one
line, otherwise.
Writing a good request
The pipeline works better with a target than with an adjective.
- Name the element. “The pricing cards” beats “the page”.
- Name the feeling, not the technique. “Should feel physical, like they have weight” gives more to work with than “add a spring”.
- Name what you do not want. Constraints sharpen a thesis faster than aspirations do.
- Mention a reference if you have one. One URL can replace three questions.
When to use paint, or bunshin, instead
Reach for paint when there is no visual direction to adapt to,
or when the existing one is what you want gone. cast improves what exists;
paint decides what should exist. When what should exist is a whole site, first
version, bunshin builds it with a team of subagents.