heang-world
Skill15 starsChanged 4 months agoMITView on GitHub
OPTIONAL module of 宇航.design (see the heang-design skill for the required base). Add a new UI world (a complete visual style) or a new world-switch transition to 宇航.design / heang-design. Use when the user asks for a new 世界/次元/UI 风格/主题, sends reference screenshots of a look they want added, wants another 切换动效, or asks to change how the random world switcher behaves.
In this repository8 other files it gives its agents.
- anatomySkill
- atypica-researchSkill
- craft-repository-readmeSkill
- 飞书多 Agent 配置助手Skill
- haiguitangSkill
- heang-designSkill
- OpenClaw 网络优化助手Skill
- shuorenhuaSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 49
Keep the @scope ([data-dim="<id>"]) to ([data-dim]) wrapper: the transition's frozen copy of the previous world sits inside the page, and …
- Very specific: line 55
Fonts: add any new family to the <link> in index.html, with a real fallback stack.
- Distinctive: line 65
No page-curl, no decoration that stays on screen after the switch.
- Distinctive: line 71
Run from the project root:
- Distinctive: line 80
Run every transition into and out of the new world and confirm no errors and no leftovers:
- Very specific: line 91
Every visit starts in world 01 太空少年 (restoreMode() forces 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
heang-world
Optional. The required base of every project (太空少年 style, pointer interactions, logo splash) is in the
heang-designskill; world switching is only added when the user asks for it.
宇航.design shows one page in many worlds. The content and layout never change; a world restyles everything through tokens + scoped CSS and paints its own backdrop. Clicking anywhere (while 切换模式 is on) jumps to a random world with a random transition.
Project root: the heang-design/ folder that contains this .claude/.
The pieces
| What | Where | Registered by |
| World definition | src/worlds/<id>/index.ts | import.meta.glob in src/worlds/registry.ts — just create the folder |
| World look | src/worlds/<id>/world.css (imported by its index.ts) | — |
| Live backdrop (optional) | src/worlds/<id>/Backdrop.tsx | backdrop: () => import("./Backdrop") |
| 3D hero object (optional) | add a variant to src/components/lab/ArtifactScene.tsx | used from a Backdrop |
| Transition | src/transitions/fx/<id>.ts | import.meta.glob in src/transitions/engine.ts |
| Paintings / videos | public/dims/ | referenced from image / video |
| Fonts | the Google Fonts <link> in index.html | — |
Contracts: src/worlds/types.ts (WorldDef) and src/transitions/types.ts (TransitionCtx).
World 01 (cadet, 太空少年) is the default every visit starts in; its tokens live in
src/tokens/tokens.css because public sites use them as the base set. Don't renumber it.
Add a world
- Read the brief. From the user's words or reference images, name: ground color, one accent,
display face, what sits behind the page (painting, video, or something drawable live), and the
one detail that makes it unmistakable (vertical CJK, HUD chamfers, a seal, a glowing ring…).
Reference screenshots with text baked in can't be used as backdrops — ask for the clean
image/video, or draw the hero object live (canvas /
ArtifactScene). - Copy the templates:
templates/world/*→src/worlds/<id>/. Replace every__PLACEHOLDER__.no= next free two-digit number. - Tokens first (
world.cssblock 1). Set every token; the template lists them all.--h-r-pillcontrols how round buttons are,--h-bwborder weight,--h-sh*shadows. - Redraw (block 3) through the hook classes only — never edit components for one world:
h1,h1 mark,h1 > i(the title's end dot),h2,.kv,.h-badge,.h-badge--sun,.h-prompt,.h-btn,.h-btn--primary,.h-btn--term,.stk(every card),.h-bar(sticky top bar — keep it readable: translucent + blur),.h-bar b,.h-bar svg(logo),.h-nav,.h-nav[aria-current="page"],.kbd,.h-account,.h-chip,.h-sechead,.h-status. Keep the@scope ([data-dim="<id>"]) to ([data-dim])wrapper: the transition's frozen copy of the previous world sits inside the page, and the lower boundary is what stops styles leaking into it. - Backdrop. Painting →
image. Video →video(+imageas poster), muted loop, ≤ 5 MB, 10–20 s, slow push-in. Live →Backdrop.tsxfrom the template; follow the pointer a little, freeze underprefers-reduced-motion. Tune.dim-world__shadeso text on the left stays legible, and add a@media (max-width: 900px)veil if the subject crosses the text on phones. - Fonts: add any new family to the
<link>inindex.html, with a real fallback stack. - Verify (see below).
Add a transition
- Copy
templates/transition.ts→src/transitions/fx/<id>.ts. - The page underneath is already the new world. Remove the old world using
c.ghost()copies (clip-path, mask, transform, filter), light it withc.fx()inc.accent.c.originis the click. - Rules the user set — don't break them:
- Fast and discrete. ≤ 600 ms of motion, hard stops, staggered hits ("啪叽啪叽"). No slow reveals.
- No page-curl, no decoration that stays on screen after the switch.
- Everything you create is removed by the engine; don't leave timers running past
run().
- Try it from the TRANSITIONS row on the page (it forces that transition).
Verify
Run from the project root:
npx tsc --noEmit && npx vite buildThen in the preview (npm run dev):
- Set
document.documentElement.dataset.dim = "<id>"and check the hero, the bar, a section of cards and the status bar, at desktop width and at ~400 px. - Run every transition into and out of the new world and confirm no errors and no leftovers:
const { switchWorld, TRANSITIONS, randomWorld } = await import('/src/transitions/engine.ts'); for (const t of TRANSITIONS) await switchWorld(randomWorld(document.documentElement.dataset.dim), { transition: t.id }); document.querySelectorAll('.dim-ghost,.dim-fx').length // → 0 - The Claude browser pane's screenshots lag behind fast animation and mis-map clicks under viewport emulation; judge motion in a real browser and click-test at the pane's native size.
Behaviour of the switcher (don't regress)
- Every visit starts in world 01 太空少年 (
restoreMode()forces it). - 切换模式 defaults to on; the choice is remembered (
localStorage["heang-switch"]). - While on, any click switches — except inside
[data-switch-ignore](the 打开/关闭切换 control, the world picker, the transition row), form fields and dialogs. Mark new controls that must keep working withdata-switch-ignore. - Random world never repeats the current one; random transition never repeats the last one.
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.

