Crucible mock-to-unity
Use when implementing Unity UI Toolkit code from a mockup, HTML reference, screenshot, or visual spec. Triggers on "implement this mockup", "translate to USS", "build this UI", "match the mock", "UI looks wrong", "fix the layout", "spacing is off", "doesn't look like the design", or any task turning a visual reference into Unity UI Toolkit USS/C# code.
git clone https://github.com/raddue/crucible
T=$(mktemp -d) && git clone --depth=1 https://github.com/raddue/crucible "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/mock-to-unity" ~/.claude/skills/raddue-crucible-mock-to-unity && rm -rf "$T"
skills/mock-to-unity/SKILL.mdMock to Unity
Translate visual mockups into Unity UI Toolkit code (USS/C#) with structural fidelity. Prevents drift through a mandatory translation map, layered implementation, and self-verification.
Skill type: Rigid — follow exactly, no shortcuts.
Related skills: When writing C# controllers (Layers 1, 3, 4), your project's coding standards apply to all C# code. After implementation,
test-driven-development applies for controller tests. After self-verification, crucible:quality-gate validates the output.
Architecture Decision: Programmatic C# (Not UXML)
Build VisualElement trees programmatically in C# — do not use UXML. The project has moved to programmatic construction because
styleSheets.Add(Resources.Load<StyleSheet>()) silently fails in Unity 6 (Issue #412). UXML-based workflows depend on stylesheet loading that is broken.
Exception: If the target panel already uses UXML (check the existing controller), follow its pattern rather than mixing approaches.
File Placement
| Output | Location |
|---|---|
| USS files | |
| C# controllers | |
| Theme.uss variable additions | |
If unsure which subsystem directory, grep for similar controllers or check the cartographer module maps.
Step 1: Read the Mockup
Read the full source mockup before writing any code.
- HTML file: Read the complete file. If too large, read in sections and summarize each section's structure, variables, and layout.
- Screenshot/image: Describe every visible element, its approximate position, colors, text, spacing, and hierarchy. Assign BEM class names based on the visual hierarchy. Estimate colors by matching to the nearest Theme.uss variable. Estimate spacing by matching to the nearest
value. Document estimation uncertainty in the translation map.--spacing-* - Text/ASCII: Parse the described structure into a mental model of containers and elements.
Do not skip this step. Do not skim. The mockup is the source of truth for the entire implementation.
Step 2: Produce a Translation Map
Write a structured mapping document before any implementation code. This is the checkpoint that catches drift early. Persist the translation map to
and commit it. All subsequent steps reference this file on disk, not conversation context.docs/plans/<feature>-translation-map.md
Selectors
Map every CSS class to its USS selector:
.talent-node → .talent-node .talent-node__icon → .talent-node__icon .talent-node--maxed → .talent-node--maxed
Properties
Map every CSS property to USS equivalent. Flag gaps:
padding: var(--spacing-md) → padding: var(--spacing-md) [direct] gap: var(--spacing-sm) → not supported in USS [use margin on children] text-overflow: ellipsis → needs C# truncation [inline workaround] :hover background change → PointerEnterEvent callback [C# layer 4]
Variables
Confirm every CSS variable exists in Theme.uss. Read the mockup-builder skill's references/theme-variables.md for the catalog:
var(--color-bg-base) → exists in Theme.uss [ok] var(--color-vendor-price) → NOT in Theme.uss [needs adding]
:root Value Validation: For each
:root variable in the mockup, verify its VALUE matches the mockup-builder skill's references/theme-variables.md (which reflects Theme.uss :root). Flag value mismatches — these cause the mockup to render differently in browser vs Unity:
var(--color-bg-base): rgb(20, 20, 31) in mockup → rgb(20, 20, 31) in Theme.uss [ok] var(--color-bg-base): rgb(25, 25, 40) in mockup → rgb(20, 20, 31) in Theme.uss [MISMATCH - fix mockup or update Theme.uss]
Effect Decision Registry
Before choosing a USS approximation pattern for any flagged CSS effect:
- Read
skills/shared/uss-effect-decisions.md - If a prior decision exists for the same effect intent (e.g., "outer glow on interactive elements"), use that exact pattern — do not choose a different approximation
- If no prior decision exists, choose from
, implement it, and append a new entry to the registry after the implementation is verifiedskills/shared/uss-approximation-patterns.md - To deliberately deviate from a registry decision, document the justification in the translation map and note it as a fork in the registry entry
This ensures visual consistency across all panels. Panel 15 should use the same glow technique as Panel 1.
Hierarchy
Map HTML nesting to VisualElement tree:
div.talent-panel → VisualElement "talent-panel" div.top-bar → VisualElement "top-bar" div.search-wrapper → VisualElement "search-wrapper" input.search-box → TextField "search-box" div.points-display → VisualElement "points-display"
Bug Zone Flags
Flag known Unity 6 USS issues:
— height/min-height inside ScrollView children → inline C# required[SCROLLVIEW]
— new runtime UIDocument →[FONTMANAGER]
requiredFontManager.ApplyToRoot(root)
— do not use[STYLESHEET]
— embed in existing USS or inline C#styleSheets.Add(Resources.Load<StyleSheet>())
— runtime UIDocument rootVisualElement resolves to 0x0 with percentage/flex sizing → use explicit pixel dimensions[DIMENSIONS]
Step 2.5: Generate Structural Scaffold
After the translation map is written to disk, generate a structural scaffold — a starting C# file that mechanically derives from the map:
-
Full VisualElement tree from the Hierarchy section — every element with its correct class name assigned via
, in the correct nesting order. This eliminates name drift between map and code.AddToClassList() -
Extra elements for USS approximation patterns — for each gap flagged in the Properties section that references an approximation pattern requiring additional elements (shadow siblings for Pattern 3, inset-glow children for Pattern 2, glow-line children for Pattern 8, gradient segments for Pattern 6), insert the extra VisualElements at the correct position in the tree with TODO comments:
// USS approximation: outer glow (Pattern 1) — see uss-approximation-patterns.md // TODO: verify border-width and border-color values match translation map -
Bug zone stubs at every site flagged
,[SCROLLVIEW]
,[FONTMANAGER]
in the Bug Zone Flags section:[DIMENSIONS]// [SCROLLVIEW] USS height ignored inside ScrollView children (Unity 6) // TODO: set value from translation map — var name: --spacing-3xl scrollChild.style.height = new StyleLength(/* TODO */); -
Effect Decision Registry references — for each approximation pattern used, include a comment noting the registry decision (if one exists) or marking it as a new decision to be registered after verification.
The scaffold is the starting point for Layer 1, not a separate deliverable. Layer 1 becomes "review and fill in the scaffold" rather than "build the tree from scratch." Layer 2 USS can immediately target the scaffold's class names. Layer 3 fills in the TODO stubs.
Include the scaffold in the Step 3 checkpoint so the user can review structure before implementation begins.
The scaffold is generated by the implementing agent, not by an external tool. The agent reads its own translation map and mechanically produces the C# file. This is deterministic template expansion, not creative work.
Step 3: User Checkpoint
Present the translation map AND the structural scaffold. Wait for approval before proceeding to Layer implementation. Explicitly state the element count, approximation-pattern elements added, and bug zone stubs included.
- Number of elements in the hierarchy
- Number of USS properties that translate directly
- Number of items flagged for inline C# workarounds
- Any new Theme.uss variables needed
If operating autonomously (e.g., as a subagent in a build pipeline), skip the wait but still produce the map in output for traceability.
Step 4: Implement in Layers
Build in this order. Do not skip layers or combine them.
Layer 1 — Structure: Start from the Step 2.5 scaffold. Review the generated VisualElement tree, fill in any remaining structural details, and verify element count and nesting depth match the translation map. The scaffold provides the correct class names and approximation-pattern elements — do not rename or restructure unless the translation map is wrong.
Layer 2 — USS Styling: Write USS selectors using Theme.uss variables. Reference the translation map for every property. Use
var() references exclusively — no hardcoded values. For any variable flagged as "needs adding to Theme.uss" in the translation map, add it to Assets/_Project/Resources/UI/Theme.uss in the appropriate section with a comment. Also update the mockup-builder skill's references/theme-variables.md to include the new variable.
Layer 3 — Inline C# Workarounds: For every item flagged in the translation map's bug zone flags and property gaps. Each workaround gets a code comment:
// USS bug: height ignored inside ScrollView children (Unity 6) // See: Theme.uss variable --spacing-3xl = 30px element.style.height = 30;
Layer 4 — Interactive Behavior: Hover/active states use USS pseudo-classes (
:hover, :active) — these work directly in USS. Only use C# PointerEnterEvent/PointerLeaveEvent for hover behavior that changes non-style properties (e.g., showing a tooltip, triggering animations via DOTween). Click handlers, drag registration, context menu wiring remain in C#.
Step 5: Self-Verify
Verification is layer-appropriate — not every layer needs a screenshot:
Layer 1 (Structure): Code-level audit only. Verify element count, names, and nesting depth match the translation map. No screenshot needed — unstyled elements are meaningless visually.
Layer 2 (USS Styling): Screenshot comparison is now useful. Take a screenshot if UI is reachable. Compare layout, colors, and spacing against the mockup. Note that inline workarounds are pending — some visual gaps are expected.
Layer 3 (Inline Workarounds): Screenshot should now closely match the mockup. Compare and fix any remaining drift.
Layer 4 (Interactive): Final verification. All visual and behavioral elements should match.
If UI is NOT reachable (requires specific game state like level 25, combat, NPC interaction): Fall back to code-level structural audit — invoke the
ui-verify skill in code-audit mode.
Step 6: Mandatory ui-verify
After self-verification (Step 5) passes, invoke
crucible:ui-verify as a mandatory cross-check:
- Invoke
with the mockup path and translation map path (crucible:ui-verify
)docs/plans/<feature>-translation-map.md - ui-verify forces a fresh re-read of the mockup and produces a structured delta report
- Loop until: all categories pass (
or[PASS-visual]
), OR remaining deltas are documented as USS limitations ([PASS-code]
with reference to[WARN]
)skills/shared/uss-approximation-patterns.md - Do NOT skip this step. Self-verification (Step 5) checks your own work. ui-verify checks against the source of truth with a fresh read.
Quality Gate
This skill produces translation maps and implementations. When used standalone, invoke
crucible:quality-gate after ui-verify (Step 6) completes. When used as a sub-skill of build, the parent orchestrator handles gating.
The gate reviews:
- Translation map completeness — every mockup element mapped, translation map persisted to
docs/plans/<feature>-translation-map.md - USS approximation patterns applied — every flagged gap has a documented workaround from
that was actually implementedskills/shared/uss-approximation-patterns.md - ui-verify delta report — no unresolved
items (only[FAIL]
,[PASS-visual]
, or[PASS-code]
for documented USS limitations)[WARN]
Unity 6 Rules
These are non-negotiable. Violations are bugs.
| Rule | Reason |
|---|---|
Every runtime UIDocument calls | Text invisible without it (Issue #187) |
Never use | Rules silently ignored in Unity 6 (Issue #412) |
| Height/min-height inside ScrollView → inline C# only | USS values silently ignored (Unity 6 bug) |
All colors via Theme.uss variables | Player-customizable themes requirement |
Cross-UIDocument coords use | Each UIDocument has its own panel coordinate space |
Equipment slot drop handlers guard | Prevents null-ref on non-Item drags |
Reference
For the full Theme.uss variable catalog, read the mockup-builder skill's references/theme-variables.md. For CSS-to-USS property mapping, read
references/css-to-uss-mapping.md.