| name | salvador |
| description | Autonomous p5.js visualization agent. It implements, inspects, critiques design/UX, fixes, and launches the result. |
Salvador Agent
Use this skill to visualize concepts using p5.js with a focus on high-quality UX, aesthetics, and continuous motion.
The visual IS the explanation. Teach through visual metaphor — show concepts as physical actions the viewer can follow (a pile splitting into chunks, elements rearranging, quantities flowing). Text is annotation, not content. If you can show it with animation or transformation, don't write it in words.
Workflow
Follow this strict loop when asked to visualize a concept:
Phase 1: Bootstrap
- Check Context: If
package.json is missing, run bash .claude/skills/salvador/scripts/setup.sh.
- Scaffold: Ensure
index.html and src/main.js exist.
- Read p5.js Reference: Read
resources/p5-missing-knowledge.md for p5.js 2.x API changes before writing any code.
- Read Responsive Design: Read
resources/responsive-design.md for the scale factor pattern.
- Read Visual Quality Rules: Read
resources/visual-quality.md for layout, typography, and color rules.
- Read Design Defaults: Read
resources/design-defaults.md for spacing values and code patterns.
Phase 1.5: Concept Analysis (Before Coding!)
Before writing any code, decompose the concept:
-
Decide the visualization type:
- Staged: concept needs step-by-step explanation (how a qubit works, how sorting algorithms compare, how photosynthesis works). Has multiple stages with ← → navigation.
- Standalone: single living scene (starfield, fractal, lava lamp, particle system, a physics sandbox). No stages — one continuous experience with interactivity.
- Hybrid: mostly one scene but with modes or layers the user can toggle (solar system with clickable planets, waveform explorer with parameter sliders).
This decision shapes everything below. Don't force stages on a concept that doesn't need them.
-
Research the Domain: Look up the actual facts (angles, counts, formulas, rules)
- Don't guess scientific/mathematical details
- Get the real values (e.g., H2O bond angle is 104.5°, not "about 109°")
-
If staged: Read resources/storytelling.md for narrative structure, then plan the arc:
- Setup: introduce the actors and the world
- Tension: what's the question or unknown? create curiosity
- Revelation: the moment of insight (this is where learning happens)
- Understanding: show the mechanism, the "why"
- Mastery: let the user interact or explore variations
-
If staged — STOP — Write the Bridge Chain (do NOT proceed to coding without it):
Write out this exact structure for every stage:
stage 1: [title]
BEFORE: [what the viewer sees at the START of this stage]
AFTER: [what the viewer sees at the END — what changed and why]
teaches: [what this visual change communicates to the viewer]
analogy: [everyday thing that works like this]
→ "[question that creates pull to stage 2]"
stage 2: [title]
BEFORE: [starting visual state — must answer the bridge from stage 1]
AFTER: [ending visual state — what transformed]
teaches: [what the contrast communicates]
analogy: [...]
→ "[question that creates pull to stage 3]"
stage 3: ...
Example — BAD:
stage 2: Cooper Pairs
BEFORE: lattice with electrons
AFTER: lattice with paired electrons
teaches: Cooper pairs have zero resistance
Example — GOOD:
stage 2: Cooper Pairs
BEFORE: 12 electrons bouncing chaotically off lattice nodes, leaving short jittery trails
AFTER: temperature gauge drops, electrons slow, snap into pairs with glowing bonds, glide smoothly through lattice without deflecting
teaches: the CONTRAST between chaotic-bouncing and smooth-gliding IS the explanation of superconductivity — no text needed
Rules:
- every stage MUST have a visible transformation (BEFORE ≠ AFTER). if a stage has no change, it's a static exhibit — merge it or rethink it.
- if you can't write a bridge question between two stages, they are disconnected — rethink the order or merge them
- each bridge question MUST appear visually in the rendered stage
- each analogy MUST appear visually in the rendered stage alongside the real concept — not as text in a card
- after the chain, write a scene plan: for each transition (1→2, 2→3, ...) decide
same canvas or new scene and say why. when in doubt, same canvas is better — the viewer sees the scene evolve instead of jumping between slides. this decides which transition pattern from design-defaults.md to use.
- this chain is your contract — the code must implement it
-
If standalone/hybrid: Plan the scene and interactions:
- what is the visual core? (the main thing the viewer sees and interacts with)
- what parameters can the user control? (sliders, mouse, click, keyboard)
- what makes it alive? (physics, particles, procedural generation, response to input)
- what moves, how, and why? Do NOT make a static snapshot — everything moves in the Universe.
-
Identify What Needs Explanation (if educational):
- Key terms to define
- Quantities to show
- Relationships to highlight
- For each step, ask: what does the viewer NOT know yet? Don't skip steps that seem obvious — the viewer is learning, not reviewing.
Phase 1.6: Design Principles
-
Living Systems: The system must breathe.
- Idle Animation: Even when waiting for user input, nothing should be perfectly frozen.
- Continuous Time: Use
draw() to animate physics/logic continuously. noLoop() is forbidden.
-
(Staged only) Scene Transitions: Use the scene plan from step 4.
- Same canvas: add/modify elements in place. Use the lerp transition pattern from
design-defaults.md. (e.g., trigonometry builds up one diagram; sorting transforms the array in place.)
- New scene: use the scene-switch pattern from
design-defaults.md — shared chrome (info card, nav) lerps, scene content fades in smoothly. Never instant-cut.
-
(Staged only) Granular Transitions: Never skip the "moment of change"
- BAD: "state A" → "state B" (viewer misses the transformation)
- GOOD: "state A" → "approaching change" → "moment of change" → "state B"
- Rule: if two stages feel like a big jump, add an intermediate stage
-
Trackability: When elements transform or move, viewers must follow them
- Assign distinct colors to individual components at the start
- Maintain those colors throughout the visualization
- Make it obvious which element went where, became what, or combined with whom
-
(Educational) Data Cards: Show the underlying facts, not just the visual
- Include domain notation (formulas, equations, configurations, pseudocode)
- Display quantities, measurements, and labels using proper terminology
Phase 2: Autonomous Loop (The "Work")
Repeat this cycle until the visualization is High Quality:
-
Implement/Refine: Write src/main.js.
- Always:
- Use a modern color palette (avoid default pure RGB)
- Continuous Motion:
draw() runs continuously. Show micro-movements even in idle states.
- Animation speed: text that appears during animation must stay visible for at least 3 seconds. Transformations must be slow enough to follow — when in doubt, double the duration.
- Text budget per stage: 1 title (3-5 words), up to 4 labels (1-3 words each), 1 bridge question, optionally 1 equation. More text than this = text-first anti-pattern.
- Ensure text is readable and has high contrast
- Font hierarchy: size reflects importance (see
resources/visual-quality.md)
- Fractions: NEVER use forward-slash for math fractions. Use the visual fraction renderer from
resources/design-defaults.md.
- Canvas sizing: Use 850x540 base coordinates
- Keyboard handling: Use
window.addEventListener('keydown'). Map 'G' to saveGif.
- Support interactions (mouse, click, keyboard)
- Staged only:
- Build an interactive stepper (← →) through stages
- Expose stage count: Set
window.stageCount = stages.length so the inspector can navigate all stages.
- Transitions — NO FADE-CUTS: Elements present in consecutive stages must lerp to their new positions/sizes. New elements can fade in, removed elements can fade out, but shared elements move continuously. Use the transition pattern from
resources/design-defaults.md.
- Color-code components that transform and maintain those colors throughout all stages.
- Use domain-accurate values, not approximations
- Standalone/hybrid:
- Focus on interactivity and responsiveness
- Make controls discoverable (visual hints, glow, cursor changes)
-
Inspect: Run node inspect.js
- For staged: the inspector captures ALL stages (navigates via ArrowRight, saves
snapshots/stage_N.png for each).
- For standalone: the inspector captures 3 frames at different animation moments (
snapshots/frame_1.png, frame_2.png, frame_3.png). If the visualization has no stages, window.stageCount is not needed.
-
Critique: Open every snapshot. Your job is to find problems — list at least 3 per screenshot. If you can't find 3, look harder — there are always problems in a first draft.
Before checking details, ask: would a viewer understand this concept if they couldn't read any text? If not, the visuals aren't carrying enough weight — rethink the approach, don't polish details.
For each snapshot, do these two things in order:
First — describe what you see: What would a first-time viewer understand from this screenshot alone? What's clear? What's confusing? What's broken? (overlaps, clipping, misalignment, text collisions, elements outside bounds, unclear processes or connections)
Then — check specifics (use resources/visual-quality.md as reference):
- overlaps, clipping, out-of-bounds, misalignment
- (staged only) transitions between consecutive stages: do shared elements lerp? bridge questions visible?
- (standalone) compare frames: does animation show meaningful change? is anything too fast to read?
Verification rule: if you claim a fix, re-run node inspect.js and verify the specific area in the new screenshot before proceeding.
-
Decide:
- Errors? -> Fix code -> Repeat.
- Static/Boring? -> Add Micro-Movement (vibration, orbits) -> Repeat.
- Physics/Logic Broken? -> Fix Simulation Logic -> Repeat.
- Layout/Typography/Transition issues? -> Fix the specific issue -> Repeat.
- Amazing, Dynamic & Polished? -> Proceed to Phase 3.
Phase 3: Presentation (The "Reveal")
Once the loop is complete and the visualization is polished:
- Launch: Run
npx vite --open.
- Notify: Tell the user "Visualization is ready. Controls: [List controls here]."