@12ui/design 0.2.71 → 0.2.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +5 -0
  2. package/SKILL.md +1 -1
  3. package/dist/cli-capabilities.d.ts +9 -0
  4. package/dist/cli-capabilities.d.ts.map +1 -1
  5. package/dist/cli-capabilities.js +10 -0
  6. package/dist/cli-capabilities.js.map +1 -1
  7. package/dist/cli-help/index.d.ts +93 -0
  8. package/dist/cli-help/index.d.ts.map +1 -1
  9. package/dist/cli-help/index.js +2 -0
  10. package/dist/cli-help/index.js.map +1 -1
  11. package/dist/cli-help/scene.d.ts +96 -0
  12. package/dist/cli-help/scene.d.ts.map +1 -0
  13. package/dist/cli-help/scene.js +162 -0
  14. package/dist/cli-help/scene.js.map +1 -0
  15. package/dist/cli-run.d.ts.map +1 -1
  16. package/dist/cli-run.js +6 -0
  17. package/dist/cli-run.js.map +1 -1
  18. package/dist/cli-scene-command.d.ts +3 -0
  19. package/dist/cli-scene-command.d.ts.map +1 -0
  20. package/dist/cli-scene-command.js +292 -0
  21. package/dist/cli-scene-command.js.map +1 -0
  22. package/dist/cli-usage.d.ts +8 -0
  23. package/dist/cli-usage.d.ts.map +1 -1
  24. package/dist/cli-usage.js +26 -1
  25. package/dist/cli-usage.js.map +1 -1
  26. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  27. package/dist/legacy-skill-catalog.js +11 -0
  28. package/dist/legacy-skill-catalog.js.map +1 -1
  29. package/dist/prototype-browsers.d.ts +8 -2
  30. package/dist/prototype-browsers.d.ts.map +1 -1
  31. package/dist/prototype-browsers.js +8 -3
  32. package/dist/prototype-browsers.js.map +1 -1
  33. package/dist/prototype-process.js +1 -1
  34. package/dist/prototype-process.js.map +1 -1
  35. package/dist/run-journal-commands.d.ts.map +1 -1
  36. package/dist/run-journal-commands.js +6 -0
  37. package/dist/run-journal-commands.js.map +1 -1
  38. package/dist/scene/camera-model.d.ts +48 -0
  39. package/dist/scene/camera-model.d.ts.map +1 -0
  40. package/dist/scene/camera-model.js +89 -0
  41. package/dist/scene/camera-model.js.map +1 -0
  42. package/dist/scene/camera-solve.d.ts +58 -0
  43. package/dist/scene/camera-solve.d.ts.map +1 -0
  44. package/dist/scene/camera-solve.js +288 -0
  45. package/dist/scene/camera-solve.js.map +1 -0
  46. package/dist/scene/capture-plan.d.ts +28 -0
  47. package/dist/scene/capture-plan.d.ts.map +1 -0
  48. package/dist/scene/capture-plan.js +79 -0
  49. package/dist/scene/capture-plan.js.map +1 -0
  50. package/dist/scene/capture.d.ts +21 -0
  51. package/dist/scene/capture.d.ts.map +1 -0
  52. package/dist/scene/capture.js +118 -0
  53. package/dist/scene/capture.js.map +1 -0
  54. package/dist/scene/image-colors.d.ts +25 -0
  55. package/dist/scene/image-colors.d.ts.map +1 -0
  56. package/dist/scene/image-colors.js +110 -0
  57. package/dist/scene/image-colors.js.map +1 -0
  58. package/dist/scene/image-rectify.d.ts +25 -0
  59. package/dist/scene/image-rectify.d.ts.map +1 -0
  60. package/dist/scene/image-rectify.js +82 -0
  61. package/dist/scene/image-rectify.js.map +1 -0
  62. package/dist/scene/image-sheet.d.ts +19 -0
  63. package/dist/scene/image-sheet.d.ts.map +1 -0
  64. package/dist/scene/image-sheet.js +118 -0
  65. package/dist/scene/image-sheet.js.map +1 -0
  66. package/dist/scene/least-squares.d.ts +31 -0
  67. package/dist/scene/least-squares.d.ts.map +1 -0
  68. package/dist/scene/least-squares.js +173 -0
  69. package/dist/scene/least-squares.js.map +1 -0
  70. package/dist/scene/numbers.d.ts +17 -0
  71. package/dist/scene/numbers.d.ts.map +1 -0
  72. package/dist/scene/numbers.js +39 -0
  73. package/dist/scene/numbers.js.map +1 -0
  74. package/dist/scene/placement.d.ts +43 -0
  75. package/dist/scene/placement.d.ts.map +1 -0
  76. package/dist/scene/placement.js +107 -0
  77. package/dist/scene/placement.js.map +1 -0
  78. package/dist/scene/raster.d.ts +18 -0
  79. package/dist/scene/raster.d.ts.map +1 -0
  80. package/dist/scene/raster.js +31 -0
  81. package/dist/scene/raster.js.map +1 -0
  82. package/dist/scene/scene-kit.d.ts +20 -0
  83. package/dist/scene/scene-kit.d.ts.map +1 -0
  84. package/dist/scene/scene-kit.js +74 -0
  85. package/dist/scene/scene-kit.js.map +1 -0
  86. package/dist/scene/scene-verbs.d.ts +4 -0
  87. package/dist/scene/scene-verbs.d.ts.map +1 -0
  88. package/dist/scene/scene-verbs.js +5 -0
  89. package/dist/scene/scene-verbs.js.map +1 -0
  90. package/dist/scene/seeded-random.d.ts +20 -0
  91. package/dist/scene/seeded-random.d.ts.map +1 -0
  92. package/dist/scene/seeded-random.js +42 -0
  93. package/dist/scene/seeded-random.js.map +1 -0
  94. package/dist/scene/spec-expression.d.ts +25 -0
  95. package/dist/scene/spec-expression.d.ts.map +1 -0
  96. package/dist/scene/spec-expression.js +234 -0
  97. package/dist/scene/spec-expression.js.map +1 -0
  98. package/dist/scene/static-server.d.ts +13 -0
  99. package/dist/scene/static-server.d.ts.map +1 -0
  100. package/dist/scene/static-server.js +99 -0
  101. package/dist/scene/static-server.js.map +1 -0
  102. package/open-design.json +2 -2
  103. package/package.json +3 -1
  104. package/scene-kit/starter/camera.js +10 -0
  105. package/scene-kit/starter/gobo.js +60 -0
  106. package/scene-kit/starter/index.html +23 -0
  107. package/scene-kit/starter/lib.js +84 -0
  108. package/scene-kit/starter/main.js +78 -0
  109. package/scene-kit/starter/scene.js +33 -0
  110. package/scene-kit/vendor/LICENSE +21 -0
  111. package/scene-kit/vendor/addons/geometries/RoundedBoxGeometry.js +216 -0
  112. package/scene-kit/vendor/addons/renderers/CSS3DRenderer.js +454 -0
  113. package/scene-kit/vendor/three.core.js +60586 -0
  114. package/scene-kit/vendor/three.module.js +19719 -0
  115. package/skills/12ui-design/SKILL.md +7 -1
  116. package/skills/12ui-design/scene.md +172 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: 12ui-design
3
- description: "Design interfaces with 12ui, expand an approved screen into pages or app states, convert design images into editable code and assets, and improve existing applications. Use for non-trivial UI creation, image-to-code, and visual redesign."
3
+ description: "Design interfaces with 12ui, expand an approved screen into pages or app states, convert design images into editable code and assets or into a live 3D / Three.js scene, and improve existing applications. Use for non-trivial UI creation, image-to-code, and visual redesign."
4
4
  ---
5
5
 
6
6
  # 12ui Design
@@ -96,3 +96,9 @@ With an approved target, use §4's command to skip drafting. Without `--apply`,
96
96
  Only if needed, read [improve.md](improve.md) for controls, target preparation, site work, and kit use.
97
97
 
98
98
  The pick is mandatory when generating candidates. Exit code 0 with an INCOMPLETE kit means nothing has been picked yet, not that the run failed. Never work around the checkpoint by approximating the design in CSS.
99
+
100
+ ## 7. 3D scene
101
+
102
+ When asked to recreate a design image as a live 3D or Three.js scene, with real geometry, light, and interactions rather than a projection of the picture, read [scene.md](scene.md). It uses the local `12ui scene` tools, which need no account and make no network request:
103
+
104
+ 12ui scene init <scene-dir>
@@ -0,0 +1,172 @@
1
+ # Rebuild a design image as a live 3D scene
2
+
3
+ Use this when asked to recreate a design or concept image (hero shot, product on a surface, landing-page render,
4
+ illustrated scene) as a live Three.js scene with real geometry, materials, light and a few interactions, not a
5
+ projection of the picture. Solve the camera from landmarks, model the objects, then check the result from the source
6
+ camera and from 15 degrees either side. Everything runs on this machine through `12ui scene`: no account, no model
7
+ call, no network. `12ui scene --help` lists the tools and `12ui scene <verb> --help` explains each one.
8
+
9
+ ## The rule
10
+
11
+ - **Model the objects.** Boxes, slabs, lathes, extrusions, instanced detail, procedural textures, physical materials,
12
+ real lights and shadows. If it is solid in the picture it is solid in the scene.
13
+ - **Use the source image only as a reference** for colour, layout and mood, and as a texture on **flat printed things**
14
+ (a screen, a label, a poster, a sleeve print). Never paint the whole picture onto geometry, and never bake shading
15
+ or a reflection into a texture that should be lit.
16
+ - **It must hold at +-15 degrees and beyond.** You are trading some landing-view exactness (proportions, exact colour,
17
+ a display font) for a scene that is real from every angle. That is the point. Say so in your report.
18
+ - **Everything is modelled procedurally.** There is no image-to-mesh step: a box, lathe, extrusion or instanced
19
+ field covers the objects a design image shows.
20
+ - Budget 12 to 20 render passes. Stop when passes stop improving the worst mismatch.
21
+
22
+ ## Setup (once)
23
+
24
+ Work in one folder, with the source image copied into it:
25
+
26
+ 12ui scene init <scene-dir>
27
+ 12ui scene serve <scene-dir> --port <port>
28
+
29
+ `init` writes the starter (`index.html`, `camera.js`, `scene.js`, `lib.js`, `gobo.js`, `main.js`) and three.js r186 in
30
+ `vendor/` (no build step, an importmap), and refuses to overwrite anything already there. `serve` binds 127.0.0.1 and
31
+ prints its PID; stop it by that PID when done, never by a name pattern.
32
+
33
+ The starter already gives you the renderer, tone mapping, the solved camera, a contain-fit frame, orbit about a pivot,
34
+ click-to-toggle actions, and the capture contract (`window.__ready`, `window.__scene.{actions,setOrbit,setAction,reset,render}`).
35
+ `buildScene(scene, renderer, camera)` gets the renderer (PMREM env maps) and camera (gobos, overlays).
36
+ You write `scene.js` (split into modules by object once it grows: `box.js`, `floor.js`, `textures.js`, `actions.js`).
37
+ Page text and buttons are real DOM inside `#stage`, positioned in source pixels.
38
+
39
+ ## 1. Camera first
40
+
41
+ Everything else is placed through the camera, so solve it before modelling anything.
42
+
43
+ 1. Read the source at full size. Pick **6 to 8 landmarks**: corners of the most clearly rectangular objects (a box, a
44
+ screen, a table edge, a sleeve, a book), read to the pixel. Include at least one landmark off the main plane, or
45
+ the field of view is ambiguous. Read them yourself from the image; zoom crops help. If a landmark residual is
46
+ large later, you misread it.
47
+ 2. Write `spec.json` and solve (`12ui scene solve --help` has the format). World coordinates are yours: choose a
48
+ unit (an object height of 1, or a floor at y = 0), let unknown dimensions be `free`, pin a scale with `"fix"`.
49
+
50
+ 12ui scene solve spec.json --out cam.json
51
+
52
+ rms should be 1 to 4 px. Roll is pinned to 0 unless you set `"solve_roll": true`. Read the `warnings` and
53
+ `fovSensitivity`: flat-lay and table shots are near top-down and coplanar, where fov is not determined by
54
+ landmarks. Pin it (`"fix": {"fov": 35}`; 20-30 product shot, 35-50 normal, 60+ wide) or add an off-plane landmark
55
+ such as an object's top edge above its base. A non-square object of unknown depth: fix its width, `free` its depth.
56
+ 3. Paste the printed `camera.js` line into the starter's `camera.js` (degrees, same keys as `cam.json`, plus the `clip`
57
+ near/far, which must stay tight: far/near under about 100). Set `PIVOT` to the subject centre.
58
+ 4. **Place objects by ray, not by eye.** Cast the source pixel of an object's base onto the ground plane, or solve a
59
+ rectangle directly, then check with `project`:
60
+
61
+ 12ui scene ray cam.json --plane-y 0 836,691 1237,749
62
+ 12ui scene rect cam.json --corners "TLu,TLv;TRu,TRv;BRu,BRv;BLu,BLv" --plane-y 0
63
+ 12ui scene rect cam.json --corners "TLu,TLv;TRu,TRv;BRu,BRv;BLu,BLv" --width 0.6 --height 0.4
64
+ 12ui scene project cam.json 0.1,0,0.3
65
+
66
+ `--plane-y` is a rectangle flat on a surface; `--width` and `--height` are a tilted one of known size. Render once
67
+ with plain grey boxes at the solved positions. If the silhouettes overlay the source, the rest is modelling and
68
+ light. If not, fix the camera now: nothing downstream repairs it. A rectangle seen from one view is ambiguous in
69
+ lean versus depth (give `--width` alone to solve the other side); use what you know (it rests on the floor, it
70
+ leans on the wall) and force draw order when something ends up inside another object.
71
+
72
+ ## 2. Model and material, per object type
73
+
74
+ | Object | Build |
75
+ |---|---|
76
+ | Box, carton, crate, wall, table | `BoxGeometry` with real wall thickness, or five walls plus hinged flaps. Bevel visible edges. |
77
+ | Book, card, drive, phone, laptop deck, sleeve | `slabGeometry(w,h,t,r)` from `lib.js` (rounded extrude, clean cap UVs), a page block and boards for a book. |
78
+ | Cup, jar, bottle, vinyl, bucket, lamp | `LatheGeometry` from a profile you read off the silhouette. Vinyl grooves: concentric bands in a roughness and colour canvas. |
79
+ | Logos, rings, outlines, ribbons | `ExtrudeGeometry` of a `Shape`, or a canvas texture if it is printed flat. |
80
+ | Rows of small things (keys, grass, bricks, sand, pins) | `InstancedMesh` with per-instance jitter in scale, rotation, colour. |
81
+ | Terrain, sand, cloth | Displaced plane plus a grain normal or bump map; never a photo. |
82
+ | Flat printed surface | Canvas texture, or the source region rectified (section 4). |
83
+
84
+ Materials: `MeshStandardMaterial` or `MeshPhysicalMaterial` (clearcoat for lacquer, glass, varnish; roughness map for
85
+ scuffs). Make surface textures procedural on a canvas (`canvasTex`, `grain` in `lib.js`): fibres and speckle for kraft
86
+ or paper, weave for cloth, streaks for brushed metal, value noise for concrete. **Sample the source for colour** before
87
+ you tune: `12ui scene colors source.png --box x0,y0,x1,y1` gives the hex to use; comparing regions against a render
88
+ afterwards gives brightness ratios to correct light, not paint.
89
+
90
+ Give thin parts real thickness (a sleeve, card or book is 1 to 2 percent of its width, not zero), and keep it consistent
91
+ with the source's shadow length: a long crisp shadow from a thin object means a low light, not a thicker object.
92
+ Glossy discs, lacquer and glass want an environment map, not more lights: `studioEnv(renderer)` from `lib.js`,
93
+ assigned to those materials only.
94
+
95
+ Light like the source: one key (spot or directional) placed by where the shadows fall, a low hemisphere or ambient
96
+ fill, a warm or cool bounce on the side faces if they read lit. Add `contactShadow` under everything that sits on a
97
+ surface. For a glossy floor use `reflections()` from `lib.js` (mirrored, jittered copies with fade) and a sheen strip;
98
+ planar reflection is often the biggest single win. Window light and leaf shadows: a `SpotLight.map` gobo drawn in
99
+ source-image pixels and resampled through the solved camera, so it lands where drawn and stays real light: the
100
+ starter's `gobo.js` (its header has the recipe and the orientation, which is verified; do not flip anything by hand).
101
+ Volumetric beams: an additive open cone. Use `ACESFilmicToneMapping`, `SRGBColorSpace`, and shadow bias about -0.0004.
102
+ Do not use `PCFSoftShadowMap` (removed in r186).
103
+
104
+ ## 3. Layout and page text
105
+
106
+ Real DOM for real page text: headline, nav, buttons, body copy, callout labels, in `#stage` at source pixel
107
+ coordinates. Pick the display font by rendering candidate faces at the measured cap height in a strip next to a source
108
+ crop and choosing the closest glyph shapes, then fit the measured line width with a `scaleX` on a span (`data-fit`).
109
+
110
+ Fonts are local only. Copy a `.ttf`, `.otf` or `.woff2` into the scene folder (from the user's project or an installed
111
+ system font) and load it with `@font-face { src: url(./file.woff2) }`, or use a face that is already installed. Never
112
+ link a hosted font stylesheet: capture blocks it, and its `remote requests blocked` and `fonts:` lines show a missing
113
+ face. Leader lines are SVG whose end dots track 3D anchors (`Object3D.getWorldPosition(v).project(camera)`), so they
114
+ follow the orbit. Never render page text into the 3D scene.
115
+
116
+ ## 4. Screens and app UI
117
+
118
+ - **Flat and static** (default): flatten the screen quad to a texture, then map it on the screen face of the device
119
+ slab. Remove painted glare and shadows in the crop, cover any bezel bleed, and light the screen with an emissive map
120
+ so it reads as lit.
121
+
122
+ 12ui scene rectify source.png --corners "TLu,TLv;TRu,TRv;BRu,BRv;BLu,BLv" --size 1200x800 --out screen.png
123
+
124
+ - **Live and editable screens**, only if the user asks for one. Optional, needs network: `12ui convert <crop.png> --output html`.
125
+ Put the result in a `CSS3DRenderer` layer (`vendor/addons/renderers/CSS3DRenderer.js`) with the same camera, or as
126
+ an iframe texture; keep the rectified crop as the offline default in the report.
127
+ - A wall of screens, a dashboard, cards on a wall: same recipe per screen, one rectified crop each.
128
+
129
+ ## 5. The self-review loop (this is the work)
130
+
131
+ After every pass, render and compare:
132
+
133
+ 12ui scene capture http://127.0.0.1:<port>/index.html --out-dir shots/i01 --size 1536x1024
134
+ 12ui scene sheet source.png shots/i01/landing.png shots/i01/az-15.png shots/i01/az+15.png --out shots/i01/sheet.png
135
+ 12ui scene blend source.png shots/i01/landing.png --out shots/i01/blend.png
136
+ 12ui scene colors source.png shots/i01/landing.png --exclude "x0,y0,x1,y1;x0,y0,x1,y1"
137
+
138
+ `capture` writes `landing`, `az-15/-10/+10/+15` and `act-<name>` (each action at t = 1), then prints
139
+ `remote requests blocked: N`, `fonts: N loaded, M failed` and any console errors. A blocked count above 0 is a defect:
140
+ the scene reached for something off this machine; make it local. If capture reports that Chromium is missing, run the
141
+ install command it prints once, then retry. Custom views: `half=0:0:lid=0.5` (name=azimuth:elevation:action=t,...).
142
+ Debug an object with `--hide vinyl` (name substring; name your groups), `--eval "js"`, `--size 900x600` for fast passes.
143
+
144
+ `colors` lists the worst cells of a grid; `--exclude` the boxes covered by DOM text (or `--exclude-dom boxes.json`),
145
+ or the text cells read as error. `--region "name:x0,y0,x1,y1;name:x0,y0,x1,y1"` compares named regions instead.
146
+
147
+ Open the sheet and the blend (source, render, 50 percent overlay, difference) and look. Fix the **single largest
148
+ mismatch** in this order: camera and silhouettes, object proportions, light direction and value, colour, then texture
149
+ detail. Log one line per pass (what looked wrong, what you changed). Look at `az-15` and `az+15` every time: if an
150
+ object turns into a card, a floor smears, or an edge opens, that is a real defect the landing view hides. Stop when
151
+ the biggest gap left is texture realism. Headless software GL is slow (a few fps); do not chase framerate, but keep
152
+ triangle counts sane (under about 500k) and do not run 9-tap reflections on everything.
153
+
154
+ ## 6. Interactions
155
+
156
+ Two or three, each on a **separate object**, each a pure function `apply(t)` of `t` in 0..1 (the starter's `actions`
157
+ registry, click a mesh to toggle, ease in and out): a **hinge** (lid, flap, cover, door: a Group at the hinge line,
158
+ rotate it), a **lift** (book, cup, card: translate along its own up axis with a small tilt), a **slide** (drive, paper,
159
+ drawer: translate along its own axis, optionally rotate slightly). Optional small extras: a lit-to-dark toggle,
160
+ a bucket tipping upright. Also give pointer-drag or arrow-key orbit clamped to +-15 degrees, and one or two labelled
161
+ buttons in `#stage` that call `__scene.toggle(name)`. Verify with a real click in the headless page as well as
162
+ `setAction`, and capture each action at t = 1 from the landing camera.
163
+
164
+ ## 7. Report
165
+
166
+ Say what you built (objects, interactions), the camera rms and worst landmark, how many render passes, the paths of
167
+ the contact sheet and captures, the capture's `remote requests blocked` and `fonts:` lines, and the remaining gaps
168
+ against the source (fonts, texture realism, proportions). Do not claim a pixel match; claim a real scene that reads as
169
+ the source from the landing camera and holds at +-15 degrees.
170
+
171
+ Ports and processes: use only the ports you were given; stop your servers by the PID `serve` printed; never kill by
172
+ name pattern. Keep output small: `init` copies three.js once per scene folder, and captures go under `shots/`.