lecodes-sdk 0.19.0

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 (367) hide show
  1. package/README.md +114 -0
  2. package/dist/global.d.ts +503 -0
  3. package/dist/host.d.ts +61 -0
  4. package/dist/inject.js +4730 -0
  5. package/dist/types/animate/animate.d.ts +20 -0
  6. package/dist/types/animate/bezier.d.ts +2 -0
  7. package/dist/types/animate/easings.d.ts +21 -0
  8. package/dist/types/canvas/Canvas.d.ts +168 -0
  9. package/dist/types/core/Aspect.d.ts +171 -0
  10. package/dist/types/core/InspectorUI.d.ts +88 -0
  11. package/dist/types/core/StateMachine.d.ts +81 -0
  12. package/dist/types/core/color.d.ts +13 -0
  13. package/dist/types/core/compWrite.d.ts +11 -0
  14. package/dist/types/core/events.d.ts +11 -0
  15. package/dist/types/core/fields.d.ts +58 -0
  16. package/dist/types/core/registry.d.ts +7 -0
  17. package/dist/types/core/signals.d.ts +29 -0
  18. package/dist/types/core/time.d.ts +31 -0
  19. package/dist/types/g2/Camera2D.d.ts +19 -0
  20. package/dist/types/g2/CharacterController2D.d.ts +134 -0
  21. package/dist/types/g2/Node2D.d.ts +91 -0
  22. package/dist/types/g2/OneWay2D.d.ts +24 -0
  23. package/dist/types/g2/Physics2D.d.ts +147 -0
  24. package/dist/types/g2/Scene2D.d.ts +72 -0
  25. package/dist/types/g2/Shape2D.d.ts +58 -0
  26. package/dist/types/g2/Sprite.d.ts +51 -0
  27. package/dist/types/g2/SpriteAnimation.d.ts +50 -0
  28. package/dist/types/g2/SpriteSheet.d.ts +69 -0
  29. package/dist/types/g2/Texture2D.d.ts +16 -0
  30. package/dist/types/g2/Tilemap.d.ts +20 -0
  31. package/dist/types/g2/Tileset.d.ts +32 -0
  32. package/dist/types/g2/Trigger2D.d.ts +20 -0
  33. package/dist/types/g2/autotile.d.ts +133 -0
  34. package/dist/types/g2/cells.d.ts +14 -0
  35. package/dist/types/g2/defineScene2d.d.ts +141 -0
  36. package/dist/types/g2/groups2d.d.ts +16 -0
  37. package/dist/types/g2/loop.d.ts +4 -0
  38. package/dist/types/g2/scenarios2d.d.ts +30 -0
  39. package/dist/types/g2/touch.d.ts +2 -0
  40. package/dist/types/gl/Camera.d.ts +79 -0
  41. package/dist/types/gl/CameraPlace.d.ts +26 -0
  42. package/dist/types/gl/CharacterController.d.ts +98 -0
  43. package/dist/types/gl/Gearbox.d.ts +86 -0
  44. package/dist/types/gl/Geometry.d.ts +39 -0
  45. package/dist/types/gl/IK.d.ts +53 -0
  46. package/dist/types/gl/InstancedMesh.d.ts +46 -0
  47. package/dist/types/gl/Light.d.ts +73 -0
  48. package/dist/types/gl/Lightmap.d.ts +85 -0
  49. package/dist/types/gl/Locomotion.d.ts +279 -0
  50. package/dist/types/gl/Material.d.ts +100 -0
  51. package/dist/types/gl/Mesh.d.ts +33 -0
  52. package/dist/types/gl/Model.d.ts +53 -0
  53. package/dist/types/gl/NavAgent.d.ts +99 -0
  54. package/dist/types/gl/NavMesh.d.ts +169 -0
  55. package/dist/types/gl/Node.d.ts +99 -0
  56. package/dist/types/gl/Noise.d.ts +20 -0
  57. package/dist/types/gl/Particles.d.ts +277 -0
  58. package/dist/types/gl/Physics.d.ts +91 -0
  59. package/dist/types/gl/Plane.d.ts +19 -0
  60. package/dist/types/gl/Ragdoll.d.ts +86 -0
  61. package/dist/types/gl/Ray.d.ts +8 -0
  62. package/dist/types/gl/Scene.d.ts +221 -0
  63. package/dist/types/gl/Shape.d.ts +122 -0
  64. package/dist/types/gl/Terrain.d.ts +280 -0
  65. package/dist/types/gl/Texture.d.ts +27 -0
  66. package/dist/types/gl/Trigger.d.ts +10 -0
  67. package/dist/types/gl/Vehicle.d.ts +191 -0
  68. package/dist/types/gl/Wheel.d.ts +95 -0
  69. package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
  70. package/dist/types/gl/animation/Animator.d.ts +219 -0
  71. package/dist/types/gl/animation/Layer.d.ts +31 -0
  72. package/dist/types/gl/animation/Loop.d.ts +17 -0
  73. package/dist/types/gl/animation/Playback.d.ts +36 -0
  74. package/dist/types/gl/animation/core.d.ts +367 -0
  75. package/dist/types/gl/controls.d.ts +19 -0
  76. package/dist/types/gl/physicsEvents.d.ts +1 -0
  77. package/dist/types/gl/scenarios.d.ts +98 -0
  78. package/dist/types/gl/state.d.ts +5 -0
  79. package/dist/types/gl/terrainMesh.d.ts +46 -0
  80. package/dist/types/gl/touch.d.ts +2 -0
  81. package/dist/types/inject.d.ts +123 -0
  82. package/dist/types/math/Mathf.d.ts +39 -0
  83. package/dist/types/math/mat4.d.ts +66 -0
  84. package/dist/types/math/quat.d.ts +53 -0
  85. package/dist/types/math/vec.d.ts +129 -0
  86. package/dist/types/net/codec.d.ts +25 -0
  87. package/dist/types/net/core.d.ts +106 -0
  88. package/dist/types/net/index.d.ts +80 -0
  89. package/dist/types/net/replication.d.ts +101 -0
  90. package/dist/types/plugins/camera.d.ts +25 -0
  91. package/dist/types/plugins/geolocation.d.ts +39 -0
  92. package/dist/types/plugins/oauth.d.ts +25 -0
  93. package/dist/types/plugins/permission.d.ts +1 -0
  94. package/dist/types/plugins/push.d.ts +46 -0
  95. package/dist/types/plugins/qr.d.ts +21 -0
  96. package/dist/types/plugins/service.d.ts +33 -0
  97. package/dist/types/runtime/app.d.ts +67 -0
  98. package/dist/types/runtime/appEvents.d.ts +7 -0
  99. package/dist/types/runtime/channel.d.ts +1 -0
  100. package/dist/types/runtime/clipboard.d.ts +7 -0
  101. package/dist/types/runtime/datetime.d.ts +80 -0
  102. package/dist/types/runtime/device.d.ts +126 -0
  103. package/dist/types/runtime/fetch.d.ts +31 -0
  104. package/dist/types/runtime/files.d.ts +33 -0
  105. package/dist/types/runtime/input.d.ts +121 -0
  106. package/dist/types/runtime/media.d.ts +46 -0
  107. package/dist/types/runtime/misc.d.ts +11 -0
  108. package/dist/types/runtime/net.d.ts +15 -0
  109. package/dist/types/runtime/rpc.d.ts +44 -0
  110. package/dist/types/runtime/service.d.ts +1 -0
  111. package/dist/types/runtime/share.d.ts +2 -0
  112. package/dist/types/runtime/storage.d.ts +5 -0
  113. package/dist/types/runtime/touch.d.ts +56 -0
  114. package/dist/types/scene/defineScene.d.ts +296 -0
  115. package/dist/types/scene/editorPlugins.d.ts +82 -0
  116. package/dist/types/scene/gizmos.d.ts +56 -0
  117. package/dist/types/scene/grammar.d.ts +56 -0
  118. package/dist/types/scene/level.d.ts +98 -0
  119. package/dist/types/scene/material.d.ts +76 -0
  120. package/dist/types/server/auth/appConfig.d.ts +16 -0
  121. package/dist/types/server/auth/global.d.ts +56 -0
  122. package/dist/types/server/auth/models.d.ts +164 -0
  123. package/dist/types/server/auth/types.d.ts +56 -0
  124. package/dist/types/server/channel.d.ts +28 -0
  125. package/dist/types/server/context.d.ts +27 -0
  126. package/dist/types/server/db/defineDb.d.ts +36 -0
  127. package/dist/types/server/db/fields.d.ts +146 -0
  128. package/dist/types/server/db/index.d.ts +6 -0
  129. package/dist/types/server/db/marci/query.d.ts +326 -0
  130. package/dist/types/server/db/types.d.ts +163 -0
  131. package/dist/types/server/errors.d.ts +8 -0
  132. package/dist/types/server/inject.d.ts +5 -0
  133. package/dist/types/ui/NativeView.d.ts +38 -0
  134. package/dist/types/ui/UI.d.ts +27 -0
  135. package/dist/types/ui/UIBottomSheet.d.ts +71 -0
  136. package/dist/types/ui/UIButton.d.ts +30 -0
  137. package/dist/types/ui/UIContainer.d.ts +33 -0
  138. package/dist/types/ui/UIImage.d.ts +35 -0
  139. package/dist/types/ui/UIInput.d.ts +110 -0
  140. package/dist/types/ui/UIModal.d.ts +70 -0
  141. package/dist/types/ui/UINode.d.ts +363 -0
  142. package/dist/types/ui/UIPager.d.ts +123 -0
  143. package/dist/types/ui/UIPopover.d.ts +39 -0
  144. package/dist/types/ui/UIScreen.d.ts +57 -0
  145. package/dist/types/ui/UIScrollable.d.ts +40 -0
  146. package/dist/types/ui/UISpacer.d.ts +9 -0
  147. package/dist/types/ui/UITabs.d.ts +96 -0
  148. package/dist/types/ui/UIText.d.ts +19 -0
  149. package/dist/types/ui/UIVideo.d.ts +28 -0
  150. package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
  151. package/dist/types/ui/UIWidget.d.ts +65 -0
  152. package/dist/types/ui/fonts.d.ts +9 -0
  153. package/dist/types/ui/presentable.d.ts +68 -0
  154. package/dist/types/ui/router.d.ts +40 -0
  155. package/dist/types/ui/theme.d.ts +26 -0
  156. package/dist/types.json +1 -0
  157. package/package.json +46 -0
  158. package/prompts/2d.md +395 -0
  159. package/prompts/3d-scene-files.md +113 -0
  160. package/prompts/3d-scene.md +119 -0
  161. package/prompts/3d.md +303 -0
  162. package/prompts/README.md +142 -0
  163. package/prompts/ar.md +109 -0
  164. package/prompts/canvas.md +27 -0
  165. package/prompts/compose.ts +46 -0
  166. package/prompts/concept.md +49 -0
  167. package/prompts/core-design.md +75 -0
  168. package/prompts/core.md +264 -0
  169. package/prompts/design.md +218 -0
  170. package/prompts/dist/2d-game.md +1530 -0
  171. package/prompts/dist/3d-app.md +1672 -0
  172. package/prompts/dist/ar-app.md +1548 -0
  173. package/prompts/dist/concept.md +49 -0
  174. package/prompts/dist/design.md +498 -0
  175. package/prompts/dist/ui-app.md +1134 -0
  176. package/prompts/index.md +37 -0
  177. package/prompts/intake-prompt.md +33 -0
  178. package/prompts/namer-prompt.md +12 -0
  179. package/prompts/router-prompt.md +50 -0
  180. package/prompts/select.ts +111 -0
  181. package/prompts/ui-design.md +203 -0
  182. package/prompts/ui.md +803 -0
  183. package/src/animate/animate.ts +238 -0
  184. package/src/animate/bezier.ts +138 -0
  185. package/src/animate/easings.ts +126 -0
  186. package/src/bridges.d.ts +1345 -0
  187. package/src/canvas/Canvas.ts +305 -0
  188. package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
  189. package/src/compile/__tests__/assetMacro.test.ts +74 -0
  190. package/src/compile/__tests__/assetName.test.ts +55 -0
  191. package/src/compile/__tests__/compile.test.ts +287 -0
  192. package/src/compile/__tests__/detectEntry.test.ts +132 -0
  193. package/src/compile/__tests__/fontMacro.test.ts +199 -0
  194. package/src/compile/aspectMacro.ts +86 -0
  195. package/src/compile/assetIconMacro.ts +384 -0
  196. package/src/compile/assetMacro.ts +146 -0
  197. package/src/compile/assetName.ts +50 -0
  198. package/src/compile/bundler.ts +287 -0
  199. package/src/compile/compileProject.ts +127 -0
  200. package/src/compile/detectEntry.ts +128 -0
  201. package/src/compile/fontMacro.ts +459 -0
  202. package/src/compile/fontRegistry.ts +78 -0
  203. package/src/compile/header.ts +67 -0
  204. package/src/compile/index.ts +100 -0
  205. package/src/compile/libraryImports.ts +52 -0
  206. package/src/compile/liteMaterial.ts +247 -0
  207. package/src/compile/sceneEditor.ts +88 -0
  208. package/src/compile/serverSplit.ts +233 -0
  209. package/src/compile/serverTypes.ts +227 -0
  210. package/src/compile/sfnt.ts +98 -0
  211. package/src/compile/shaderSchema.ts +202 -0
  212. package/src/compile/shaderTargets.ts +77 -0
  213. package/src/compile/sourcemap.ts +25 -0
  214. package/src/core/Aspect.ts +568 -0
  215. package/src/core/InspectorUI.ts +212 -0
  216. package/src/core/StateMachine.ts +308 -0
  217. package/src/core/__tests__/stateMachine.test.ts +132 -0
  218. package/src/core/color.ts +66 -0
  219. package/src/core/compWrite.ts +42 -0
  220. package/src/core/events.ts +38 -0
  221. package/src/core/fields.ts +120 -0
  222. package/src/core/registry.ts +23 -0
  223. package/src/core/signals.ts +277 -0
  224. package/src/core/time.ts +84 -0
  225. package/src/g2/Camera2D.ts +40 -0
  226. package/src/g2/CharacterController2D.ts +276 -0
  227. package/src/g2/Node2D.ts +267 -0
  228. package/src/g2/OneWay2D.ts +66 -0
  229. package/src/g2/Physics2D.ts +346 -0
  230. package/src/g2/Scene2D.ts +209 -0
  231. package/src/g2/Shape2D.ts +259 -0
  232. package/src/g2/Sprite.ts +89 -0
  233. package/src/g2/SpriteAnimation.ts +171 -0
  234. package/src/g2/SpriteSheet.ts +166 -0
  235. package/src/g2/Texture2D.ts +47 -0
  236. package/src/g2/Tilemap.ts +41 -0
  237. package/src/g2/Tileset.ts +71 -0
  238. package/src/g2/Trigger2D.ts +77 -0
  239. package/src/g2/autotile.ts +433 -0
  240. package/src/g2/cells.ts +91 -0
  241. package/src/g2/defineScene2d.ts +381 -0
  242. package/src/g2/groups2d.ts +106 -0
  243. package/src/g2/loop.ts +50 -0
  244. package/src/g2/scenarios2d.ts +69 -0
  245. package/src/g2/touch.ts +83 -0
  246. package/src/gl/Camera.ts +160 -0
  247. package/src/gl/CameraPlace.ts +52 -0
  248. package/src/gl/CharacterController.ts +238 -0
  249. package/src/gl/Gearbox.ts +212 -0
  250. package/src/gl/Geometry.ts +279 -0
  251. package/src/gl/IK.ts +193 -0
  252. package/src/gl/InstancedMesh.ts +132 -0
  253. package/src/gl/Light.ts +135 -0
  254. package/src/gl/Lightmap.ts +402 -0
  255. package/src/gl/Locomotion.ts +498 -0
  256. package/src/gl/Material.ts +279 -0
  257. package/src/gl/Mesh.ts +83 -0
  258. package/src/gl/Model.ts +124 -0
  259. package/src/gl/NavAgent.ts +337 -0
  260. package/src/gl/NavMesh.ts +397 -0
  261. package/src/gl/Node.ts +350 -0
  262. package/src/gl/Noise.ts +30 -0
  263. package/src/gl/Particles.ts +676 -0
  264. package/src/gl/Physics.ts +222 -0
  265. package/src/gl/Plane.ts +53 -0
  266. package/src/gl/Ragdoll.ts +270 -0
  267. package/src/gl/Ray.ts +16 -0
  268. package/src/gl/Scene.ts +505 -0
  269. package/src/gl/Shape.ts +409 -0
  270. package/src/gl/Terrain.ts +1092 -0
  271. package/src/gl/Texture.ts +63 -0
  272. package/src/gl/Trigger.ts +45 -0
  273. package/src/gl/Vehicle.ts +473 -0
  274. package/src/gl/Wheel.ts +240 -0
  275. package/src/gl/animation/AnimationClip.ts +204 -0
  276. package/src/gl/animation/Animator.ts +329 -0
  277. package/src/gl/animation/Layer.ts +39 -0
  278. package/src/gl/animation/Loop.ts +31 -0
  279. package/src/gl/animation/Playback.ts +52 -0
  280. package/src/gl/animation/core.ts +670 -0
  281. package/src/gl/controls.ts +95 -0
  282. package/src/gl/physicsEvents.ts +20 -0
  283. package/src/gl/scenarios.ts +291 -0
  284. package/src/gl/state.ts +6 -0
  285. package/src/gl/terrainMesh.ts +219 -0
  286. package/src/gl/touch.ts +68 -0
  287. package/src/host.d.ts +61 -0
  288. package/src/inject.ts +203 -0
  289. package/src/math/Mathf.ts +118 -0
  290. package/src/math/mat4.ts +278 -0
  291. package/src/math/quat.ts +232 -0
  292. package/src/math/vec.ts +255 -0
  293. package/src/net/codec.ts +119 -0
  294. package/src/net/core.ts +384 -0
  295. package/src/net/index.ts +181 -0
  296. package/src/net/replication.ts +622 -0
  297. package/src/plugins/camera.ts +81 -0
  298. package/src/plugins/geolocation.ts +123 -0
  299. package/src/plugins/oauth.ts +61 -0
  300. package/src/plugins/permission.ts +7 -0
  301. package/src/plugins/push.ts +132 -0
  302. package/src/plugins/qr.ts +73 -0
  303. package/src/plugins/service.ts +47 -0
  304. package/src/runtime/app.ts +101 -0
  305. package/src/runtime/appEvents.ts +54 -0
  306. package/src/runtime/channel.ts +61 -0
  307. package/src/runtime/clipboard.ts +20 -0
  308. package/src/runtime/datetime.ts +329 -0
  309. package/src/runtime/device.ts +293 -0
  310. package/src/runtime/fetch.ts +77 -0
  311. package/src/runtime/files.ts +108 -0
  312. package/src/runtime/input.ts +175 -0
  313. package/src/runtime/media.ts +111 -0
  314. package/src/runtime/misc.ts +16 -0
  315. package/src/runtime/net.ts +36 -0
  316. package/src/runtime/rpc.ts +218 -0
  317. package/src/runtime/service.ts +83 -0
  318. package/src/runtime/share.ts +9 -0
  319. package/src/runtime/storage.ts +13 -0
  320. package/src/runtime/touch.ts +76 -0
  321. package/src/scene/defineScene.ts +1396 -0
  322. package/src/scene/editorPlugins.ts +110 -0
  323. package/src/scene/gizmos.ts +148 -0
  324. package/src/scene/grammar.ts +120 -0
  325. package/src/scene/level.ts +296 -0
  326. package/src/scene/material.ts +188 -0
  327. package/src/server/auth/appConfig.ts +12 -0
  328. package/src/server/auth/global.ts +80 -0
  329. package/src/server/auth/host.ts +318 -0
  330. package/src/server/auth/models.ts +83 -0
  331. package/src/server/auth/types.ts +50 -0
  332. package/src/server/channel.ts +56 -0
  333. package/src/server/context.ts +36 -0
  334. package/src/server/db/defineDb.ts +237 -0
  335. package/src/server/db/fields.ts +132 -0
  336. package/src/server/db/httpTransport.ts +93 -0
  337. package/src/server/db/index.ts +7 -0
  338. package/src/server/db/marci/query.ts +412 -0
  339. package/src/server/db/types.ts +202 -0
  340. package/src/server/errors.ts +12 -0
  341. package/src/server/host.ts +74 -0
  342. package/src/server/inject.ts +13 -0
  343. package/src/server/runtime.ts +133 -0
  344. package/src/server/validate.ts +87 -0
  345. package/src/ui/NativeView.ts +142 -0
  346. package/src/ui/UI.ts +39 -0
  347. package/src/ui/UIBottomSheet.ts +139 -0
  348. package/src/ui/UIButton.ts +101 -0
  349. package/src/ui/UIContainer.ts +60 -0
  350. package/src/ui/UIImage.ts +83 -0
  351. package/src/ui/UIInput.ts +185 -0
  352. package/src/ui/UIModal.ts +139 -0
  353. package/src/ui/UINode.ts +830 -0
  354. package/src/ui/UIPager.ts +362 -0
  355. package/src/ui/UIPopover.ts +100 -0
  356. package/src/ui/UIScreen.ts +123 -0
  357. package/src/ui/UIScrollable.ts +87 -0
  358. package/src/ui/UISpacer.ts +14 -0
  359. package/src/ui/UITabs.ts +236 -0
  360. package/src/ui/UIText.ts +51 -0
  361. package/src/ui/UIVideo.ts +88 -0
  362. package/src/ui/UIVirtualizedList.ts +241 -0
  363. package/src/ui/UIWidget.ts +127 -0
  364. package/src/ui/fonts.ts +13 -0
  365. package/src/ui/presentable.ts +117 -0
  366. package/src/ui/router.ts +132 -0
  367. package/src/ui/theme.ts +84 -0
@@ -0,0 +1,218 @@
1
+ # Design rules
2
+
3
+ ## Folder layout
4
+
5
+ ```
6
+ design/
7
+ screens/<id>.ts one file = one screen; default-exports the screen; the FILENAME is its identity
8
+ shared/tokens.ts the brand: colors, spacing, radius, type scale — every screen's only source of values
9
+ shared/ui.ts the component kit: buttons, fields, cards, sheets — screens compose these
10
+ shared/tabs.ts the app's tab bar, declared ONCE via defineTabs (see below)
11
+ meta.json the app map: descriptions, roles, groups, edges — READ here, WRITE via design_map
12
+ spec.md the concept narrative: data model, actors, rules & decisions
13
+ assets/ vendored icons/fonts and images (listed under [Assets])
14
+ ```
15
+
16
+ ## Build the brand kit first
17
+
18
+ A design that looks designed starts from a kit, not from screens. On a new design, before the first
19
+ screen: `shared/tokens.ts` (a real palette — surfaces, text tiers, one or two accents, status
20
+ colors; a spacing/radius/type scale), then `shared/ui.ts` with the components the app will clearly
21
+ need. The kit outlives the design: when the app is built, it IMPORTS `shared/tokens.ts` (and the
22
+ presentational components of `shared/ui.ts`) unchanged — so build tokens on `theme()`, one live
23
+ table for design and app alike, and shape components as things worth keeping. Screens then read as
24
+ composition:
25
+
26
+ ```ts
27
+ // design/shared/tokens.ts — surfaces dark-to-light, text in tiers, accents as a family.
28
+ // ONE theme() call registers the vars and returns the accessors ("var(--x)" strings); the system
29
+ // key `color` in the same table sets the app-wide default text color. Re-calling theme() with new
30
+ // values (dark mode, brand swap) restyles every screen — and later the built app — live.
31
+ const palette = {
32
+ bg: "#080808", card: "#161618", cardAlt: "#1d1d20", field: "#101012",
33
+ border: "#2a2a2e", text: "#ffffff", muted: "#8a8a93", faint: "#5a5b62",
34
+ accent: "#00BFC2", accentPressed: "#00999b", accentDeep: "#0c4e4f", onAccent: "#05201f",
35
+ success: "#30D158", danger: "#F83131", scrim: "#000000b3",
36
+ // theme SYSTEM keys — SDK-rendered chrome reads these. `color` = default text color everywhere;
37
+ // the other four brand the tab bar (defineTabs here, UITabs in the built app). Mirror the brand:
38
+ color: "#ffffff",
39
+ primaryColor: "#00BFC2", mutedColor: "#8a8a93", tabbarBg: "#161618", screenBg: "#080808",
40
+ }
41
+ export const colors: { [K in keyof typeof palette]: string } = theme(palette)
42
+ export const spacing = { xs: 4, sm: 8, md: 12, lg: 16, xl: 20, xxl: 24 }
43
+ export const radius = { sm: 8, md: 12, lg: 16, pill: 999 }
44
+ ```
45
+
46
+ ```ts
47
+ // design/shared/ui.ts — excerpts; the kit grows with the design
48
+ import { colors, spacing, radius } from "./tokens"
49
+
50
+ export const PrimaryButton = (label: string, o: { name?: string, disabled?: boolean } = {}) =>
51
+ UIButton(UIText(label).style({ fontSize: 16, fontWeight: 700, color: o.disabled ? colors.muted : colors.onAccent }))
52
+ .style({ height: 52, borderRadius: radius.md, bgColor: o.disabled ? colors.accentDeep : colors.accent,
53
+ justifyContent: "center", alignItems: "center", name: o.name, onPressed: { bgColor: colors.accentPressed } })
54
+
55
+ export const SectionLabel = (t: string) =>
56
+ UIText(t.toUpperCase()).style({ fontSize: 11, fontWeight: 600, letterSpacing: 2, color: colors.faint })
57
+
58
+ // A field is a STATIC MOCK — the value is drawn as text (see ui rules); passwords as dots.
59
+ export const Field = (o: { label?: string, value?: string, placeholder?: string, focused?: boolean }) =>
60
+ UIColumn(
61
+ o.label ? SectionLabel(o.label) : null,
62
+ UIRow(UIText(o.value ?? o.placeholder ?? "").style({ flexGrow: 1, fontSize: 16, color: o.value ? colors.text : colors.muted }))
63
+ .style({ height: 52, px: 16, alignItems: "center", bgColor: colors.field, borderRadius: radius.md,
64
+ border: `1px solid ${o.focused ? colors.accent : colors.border}` }),
65
+ ).style({ gap: spacing.sm })
66
+
67
+ // Bottom sheet shell — a real modal: the scrim is overlayColor, the box is just the bottom stack.
68
+ export const Sheet = (...children: UINodeChild[]) => {
69
+ const sheet = UIWidget(children).style({
70
+ left: 0, right: 0, bottom: 0, px: spacing.lg, pb: "calc(safe-bottom + 16px)", gap: spacing.sm,
71
+ overlayColor: colors.scrim,
72
+ })
73
+ return sheet.onOverlayTap(() => sheet.hide())
74
+ }
75
+
76
+ // Full-screen confirm — full-inset box, centered card, NO onOverlayTap (a confirm demands a choice).
77
+ export const ConfirmDialog = (o: { title: string, body?: string, confirmLabel: string, confirmName: string }) =>
78
+ UIWidget(
79
+ UIColumn(
80
+ UIText(o.title).style({ fontSize: 17, fontWeight: 700, color: colors.text, textAlign: "center" }),
81
+ o.body ? UIText(o.body).style({ fontSize: 14, color: colors.muted, textAlign: "center", lineHeight: "1.4em" }) : null,
82
+ PrimaryButton("Cancel", { name: "cancel" }),
83
+ ).style({ bgColor: colors.card, borderRadius: radius.lg, p: spacing.xl, gap: spacing.lg, width: "86%", maxWidth: 360 }),
84
+ ).style({ top: 0, left: 0, right: 0, bottom: 0, justifyContent: "center", alignItems: "center", overlayColor: colors.scrim })
85
+ ```
86
+
87
+ ## Screen rules
88
+
89
+ - **One file = one screen.** `screens/<id>.ts` default-exports either a value
90
+ (`export default UIScreen(...).style({...})`) or a function of state (below). Ids are
91
+ lowercase `[a-z0-9-]`.
92
+ - **Screens are islands.** A screen imports ONLY from `../shared/` — never another screen, no props.
93
+ - **Mock data is the domain.** Realistic inline mock data at the top of the file — the entities and
94
+ fields ARE the future schema. Real names, real prices, plausible dates, in the product's language
95
+ (match the user's) — never "Lorem ipsum" or "Item 1". Where a list can be empty, design the empty
96
+ state too.
97
+ - Give a `name` style (`.style({ name: "submit" })`) to elements that edges refer to — nothing else
98
+ needs names.
99
+
100
+ ## Screen states (variants)
101
+
102
+ A screen with more than one look (list vs empty, sheet open, confirm dialog) is ONE file whose
103
+ default export is a function of a state string typed as a string-literal union — the union IS the
104
+ state list, and the parameter default is the canonical state the board shows first. Overlays are
105
+ shown from a state branch, never embedded in the layout:
106
+
107
+ ```ts
108
+ // design/screens/schedule.ts
109
+ import { colors, spacing } from "../shared/tokens"
110
+ import { mainTabs } from "../shared/tabs"
111
+ import { Sheet, PrimaryButton, SectionLabel, ClassCard, EmptyDay } from "../shared/ui"
112
+
113
+ const classes = [
114
+ { start: "18:00", end: "19:00", title: "Calisthenics", trainer: "A. Razgulin", price: 800, booked: true },
115
+ { start: "19:30", end: "21:00", title: "Acrobatics workshop", trainer: "A. Razgulin", price: 1000, seats: 2 },
116
+ ]
117
+
118
+ const FilterSheet = () => Sheet(
119
+ /* chip groups… */
120
+ PrimaryButton("Show 1 class", { name: "apply" }),
121
+ )
122
+
123
+ export default (state: "default" | "empty" | "filters" = "default") => {
124
+ if (state === "filters") FilterSheet().show()
125
+ return UIScreen(
126
+ UIScrollable(
127
+ SectionLabel("Today"),
128
+ state === "empty" ? EmptyDay() : UIColumn(classes.map((c) => ClassCard(c, { name: "class" }))).style({ gap: spacing.sm }),
129
+ ).style({ flexGrow: 1, flexShrink: 1, px: spacing.xl, pt: spacing.md, gap: spacing.lg }),
130
+ mainTabs.bar("schedule"),
131
+ ).style({ bgColor: colors.bg, pt: "safe-top" })
132
+ }
133
+ ```
134
+
135
+ Derive per-state data at the top (`const items = state === "empty" ? [] : MOCK`). The board shows a
136
+ state switcher; edges may target `id@state`.
137
+
138
+ ## The map — design_map, never meta.json
139
+
140
+ `design/meta.json` is the app map: every screen's description/group/role and the edges between
141
+ screens. You READ it from `[File contents]`; you change it ONLY through the `design_map` tool —
142
+ never with a `<file>` write (positions on it are the developer's, and the board may have edited it
143
+ while you were replying). In the same reply that creates screen files, register them:
144
+
145
+ ```
146
+ design_map ops: [
147
+ { op: "screen", id: "login", desc: "Phone + password sign-in", group: "Onboarding", role: "auth" },
148
+ { op: "screen", id: "schedule", desc: "Client home — day schedule", role: "list" },
149
+ { op: "edge", from: "login", to: "schedule", label: "Sign in", activator: "login" },
150
+ { op: "edge", from: "schedule", to: "schedule@filters", label: "Filters", activator: "filters" }
151
+ ]
152
+ ```
153
+
154
+ - New screens get NO position from you — the board auto-places them next to their edge neighbours.
155
+ - **Edges are forward intent only.** Never draw back/dismiss/logout edges (the navigation stack
156
+ implies returns), and never draw edges between tab screens (the bar already navigates).
157
+ - An edge to the same screen's `id@state` is a *state link* — "tapping X puts this screen into
158
+ state Y"; the board renders it as a chip on the activator element.
159
+ - **Group every screen** by user-facing area (2–6 per group: Onboarding, Checkout…), **tag its
160
+ `role`** (`list`, `detail`, `form`, `auth`, `modal`…). Don't regroup existing screens unless asked.
161
+
162
+ ## The tab bar
163
+
164
+ Declared ONCE in `shared/tabs.ts` — the board discovers it from source and renders it as a rail
165
+ with lanes; tab switching needs NO edges. `defineTabs` is an SDK global: the standard themed
166
+ bottom bar, the same look the built app's `UITabs` renders. The keys are screen ids (each tab's
167
+ root, in tab order), literals only; icons are always `assetIcon(...)` calls:
168
+
169
+ ```ts
170
+ // design/shared/tabs.ts — this declaration is the whole file
171
+ export const mainTabs = defineTabs({
172
+ schedule: { label: "Schedule", icon: assetIcon("lucide:calendar") },
173
+ profile: { label: "Profile", icon: assetIcon("lucide:user") },
174
+ })
175
+ ```
176
+
177
+ A screen that shows the bar mounts it with a literal tab id — roots AND pushed details that keep
178
+ the bar; a screen that doesn't mount it is a full-screen push. Mount the bar alone when the screen
179
+ owns its layout (`mainTabs.bar("schedule")`, as above) or wrap content with
180
+ `mainTabs.screen("home", [...])`. Restyle through the theme's system keys — `primaryColor`,
181
+ `mutedColor`, `tabbarBg`, `screenBg`, set in `shared/tokens.ts` — never by reimplementing the
182
+ bar. Keep the `defineTabs({...})` declaration and `.screen("<tab>", ...)` / `.bar("<tab>")` call
183
+ shapes intact — the board parses them.
184
+
185
+ ## Icons & fonts
186
+
187
+ `assetIcon("pack:name")` inlines a registry icon at compile time — the ONLY way to make an icon
188
+ (never hand-write its `{ svg }` result — that renders blank). Use real icons freely on every
189
+ screen. Vendored copies (`design/assets/icons/`, listed under `[Assets]`) resolve first; anything
190
+ else is fetched from the icon registry automatically. The main pack is `lucide` (kebab-case names:
191
+ `"lucide:bell"`, `"lucide:chevron-right"`); an unknown name is a compile error with "did you mean"
192
+ suggestions. Wrap each icon in a tiny factory in `shared/ui.ts`
193
+ (`Icon.bell = (c, s = 20) => UIImage(assetIcon("lucide:bell")).style({ width: s, height: s, tintColor: c })`).
194
+
195
+ `font("id")` works the same way — registry families load from the font CDN, no vendoring needed:
196
+ `theme({ fontFamily: font("manrope") })`, or per-node `.style({ fontFamily: font("rubik") })`.
197
+ An unknown id or weight is a compile error listing what exists. Only project font files
198
+ (`font("./Brand.ttf")`) must already be pushed.
199
+
200
+ ## spec.md — the concept
201
+
202
+ The narrative half of the design: the **data model** (entities + fields), the **actors** (who uses
203
+ the app, what each may do), and the **rules & decisions** (validation, edge cases, choices made).
204
+ Prose, co-owned with the developer — edit it with normal `<file>` writes; half-filled is fine. Link
205
+ screens as `[[screen-id]]`. The mock data at the top of each screen is the first draft of the data
206
+ model — promote entities that stabilize into spec.md tables. When you make a design decision worth
207
+ keeping, write it down here instead of leaving it in chat.
208
+
209
+ ## Working style
210
+
211
+ - Read meta.json, `shared/tokens.ts` and the `shared/ui.ts` signatures before changing anything;
212
+ open only the screens you need.
213
+ - Design in coherent flows (onboarding → main → detail), not isolated screens; a screen is a
214
+ moment in a flow. Prefer several focused screens over one mega-screen.
215
+ - The developer watches the board live — your files render as tiles the moment they land, and the
216
+ selected tile arrives as `[Design]` context: treat it as the subject of an ambiguous instruction.
217
+ - Make it look designed: every value from tokens, one accent doing the talking, realistic content
218
+ density, empty states designed, press feedback on tappables.