@bongos/core 1.24.79 → 1.24.81

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 (413) hide show
  1. package/.bongos-core.json +554 -394
  2. package/.claude/skills/ask-for-help/SKILL.md +1 -1
  3. package/.claude/skills/builder-sequence/SKILL.md +1 -1
  4. package/.claude/skills/design/SKILL.md +1 -1
  5. package/.claude/skills/goal-create/SKILL.md +1 -1
  6. package/.claude/skills/planning-session/SKILL.md +1 -1
  7. package/clients/bongos-client/README.md +1 -1
  8. package/clients/bongos-client/bongos-client.global.js +8 -0
  9. package/clients/bongos-client/index.cjs +8 -0
  10. package/clients/bongos-client/index.d.ts +11 -0
  11. package/clients/bongos-client/index.mjs +8 -0
  12. package/docs/adr/0274-one-kernel-three-role-packs.md +2 -2
  13. package/docs/adr/0399-the-visor-is-glass-over-the-scene-and-owns-no-camera.md +91 -0
  14. package/docs/adr/0400-a-chain-reserves-work-and-each-sub-quest-is-still-claimed-alone.md +109 -0
  15. package/docs/adr/0401-one-options-menu-opens-every-settings-screen-in-a-frame.md +53 -0
  16. package/docs/adr/0402-helm-is-the-halls-look-and-the-hall-is-dark-only.md +142 -0
  17. package/docs/adr/README.md +4 -0
  18. package/docs/api/openapi.json +195 -3
  19. package/docs/api-reference.md +8 -4
  20. package/docs/architecture.md +7 -3
  21. package/docs/copy-inventory.md +393 -378
  22. package/docs/copy-registry.json +722 -578
  23. package/docs/design/characters/character-sprites-source.webp +0 -0
  24. package/docs/file-map.md +7 -8
  25. package/docs/module-api-changelog.md +4 -0
  26. package/docs/modules-contract.md +5 -0
  27. package/docs/onboarding/slash-commands.md +1 -1
  28. package/docs/packs/{engineer.md → artisan.md} +5 -5
  29. package/docs/packs/artist.md +50 -4
  30. package/docs/page-inventory.json +16 -7
  31. package/docs/page-readings.json +3184 -3338
  32. package/docs/{packs/ideator.md → recipes/ideation-playbook.md} +5 -48
  33. package/migrations/core_296_crafts_artisan_artist.sql +72 -0
  34. package/migrations/core_297_builder_character.sql +30 -0
  35. package/modules/copy-desk/proposals.js +1 -1
  36. package/modules/economy/credits-by-craft.js +29 -15
  37. package/modules/hall-ui/public/ai-studio.html +6 -4
  38. package/modules/hall-ui/public/ai-studio.states.json +1 -0
  39. package/modules/hall-ui/public/atlas.html +5 -5
  40. package/modules/hall-ui/public/atlas.js +3 -1
  41. package/modules/hall-ui/public/atlas.states.json +1 -0
  42. package/modules/hall-ui/public/blockers.html +5 -5
  43. package/modules/hall-ui/public/board-room.html +4 -4
  44. package/modules/hall-ui/public/board-room.states.json +1 -0
  45. package/modules/hall-ui/public/characters/artisan.png +0 -0
  46. package/modules/hall-ui/public/characters/artist.png +0 -0
  47. package/modules/hall-ui/public/characters/patron.png +0 -0
  48. package/modules/hall-ui/public/city.css +3 -4
  49. package/modules/hall-ui/public/city.html +9 -9
  50. package/modules/hall-ui/public/city.js +17 -56
  51. package/modules/hall-ui/public/city.states.json +7 -32
  52. package/modules/hall-ui/public/collab.html +4 -4
  53. package/modules/hall-ui/public/collab.states.json +1 -0
  54. package/modules/hall-ui/public/commands.html +4 -4
  55. package/modules/hall-ui/public/commands.states.json +1 -0
  56. package/modules/hall-ui/public/controls.css +63 -11
  57. package/modules/hall-ui/public/copy-desk.html +4 -4
  58. package/modules/hall-ui/public/copy-desk.states.json +1 -0
  59. package/modules/hall-ui/public/craft-mode.js +258 -64
  60. package/modules/hall-ui/public/deploy.html +4 -4
  61. package/modules/hall-ui/public/deploy.states.json +1 -0
  62. package/modules/hall-ui/public/diagram-viewer.js +2 -1
  63. package/modules/hall-ui/public/dom-utils.js +1 -1
  64. package/modules/hall-ui/public/goal-map.html +9 -6
  65. package/modules/hall-ui/public/goals.html +5 -5
  66. package/modules/hall-ui/public/goals.states.json +1 -0
  67. package/modules/hall-ui/public/government.html +4 -4
  68. package/modules/hall-ui/public/government.states.json +1 -0
  69. package/modules/hall-ui/public/hall-render.js +3 -1
  70. package/modules/hall-ui/public/home-city-draw.js +3 -3
  71. package/modules/hall-ui/public/home-city.css +4 -0
  72. package/modules/hall-ui/public/home-city.js +17 -9
  73. package/modules/hall-ui/public/home-gallery.js +8 -1
  74. package/modules/hall-ui/public/home-idea-box.css +2 -2
  75. package/modules/hall-ui/public/home-idea-box.js +3 -3
  76. package/modules/hall-ui/public/idea.html +5 -5
  77. package/modules/hall-ui/public/idea.states.json +1 -0
  78. package/modules/hall-ui/public/ideas.html +5 -5
  79. package/modules/hall-ui/public/ideas.states.json +1 -0
  80. package/modules/hall-ui/public/index-founding.states.json +1 -0
  81. package/modules/hall-ui/public/index-genesis-decide.states.json +1 -0
  82. package/modules/hall-ui/public/index-genesis-demo.states.json +1 -0
  83. package/modules/hall-ui/public/index-genesis.states.json +1 -0
  84. package/modules/hall-ui/public/index.html +11 -7
  85. package/modules/hall-ui/public/index.states.json +1 -0
  86. package/modules/hall-ui/public/market-watch-item.html +4 -4
  87. package/modules/hall-ui/public/market-watch-item.states.json +1 -0
  88. package/modules/hall-ui/public/market-watch-rules.html +4 -4
  89. package/modules/hall-ui/public/market-watch-rules.states.json +1 -0
  90. package/modules/hall-ui/public/market-watch.html +6 -9
  91. package/modules/hall-ui/public/market-watch.js +22 -45
  92. package/modules/hall-ui/public/market-watch.states.json +1 -0
  93. package/modules/hall-ui/public/modules.html +4 -4
  94. package/modules/hall-ui/public/modules.states.json +1 -0
  95. package/modules/hall-ui/public/money.html +4 -4
  96. package/modules/hall-ui/public/money.states.json +1 -0
  97. package/modules/hall-ui/public/my-agents.html +4 -4
  98. package/modules/hall-ui/public/my-agents.states.json +1 -0
  99. package/modules/hall-ui/public/options-menu.js +409 -0
  100. package/modules/hall-ui/public/paintbrush.js +3 -3
  101. package/modules/hall-ui/public/palette.js +11 -13
  102. package/modules/hall-ui/public/primer.html +5 -5
  103. package/modules/hall-ui/public/primer.states.json +1 -0
  104. package/modules/hall-ui/public/profile-crafts.js +1 -1
  105. package/modules/hall-ui/public/profile-roles.js +23 -19
  106. package/modules/hall-ui/public/profile.css +1 -1
  107. package/modules/hall-ui/public/profile.html +19 -18
  108. package/modules/hall-ui/public/profile.js +19 -18
  109. package/modules/hall-ui/public/profile.states.json +5 -4
  110. package/modules/hall-ui/public/project-settings.html +4 -4
  111. package/modules/hall-ui/public/roster.html +4 -4
  112. package/modules/hall-ui/public/roster.js +3 -3
  113. package/modules/hall-ui/public/roster.states.json +1 -0
  114. package/modules/hall-ui/public/settings.css +24 -4
  115. package/modules/hall-ui/public/settings.html +21 -17
  116. package/modules/hall-ui/public/settings.js +44 -44
  117. package/modules/hall-ui/public/settings.states.json +1 -0
  118. package/modules/hall-ui/public/shell-game.css +110 -0
  119. package/modules/hall-ui/public/shell-game.js +316 -3
  120. package/modules/hall-ui/public/shell.js +15 -66
  121. package/modules/hall-ui/public/sky-interaction.js +7 -0
  122. package/modules/hall-ui/public/speciality-tools.js +1 -2
  123. package/modules/hall-ui/public/street-card.states.json +1 -0
  124. package/modules/hall-ui/public/street-inside.js +3 -4
  125. package/modules/hall-ui/public/street.css +1 -5
  126. package/modules/hall-ui/public/street.html +6 -10
  127. package/modules/hall-ui/public/street.js +8 -59
  128. package/modules/hall-ui/public/street.states.json +7 -32
  129. package/modules/hall-ui/public/studio.html +5 -5
  130. package/modules/hall-ui/public/studio.states.json +1 -0
  131. package/modules/hall-ui/public/style.css +197 -112
  132. package/modules/hall-ui/public/task-detail.js +5 -4
  133. package/modules/hall-ui/public/task.html +5 -5
  134. package/modules/hall-ui/public/task.states.json +1 -0
  135. package/modules/hall-ui/public/thinking.css +10 -0
  136. package/modules/hall-ui/public/thinking.html +9 -6
  137. package/modules/hall-ui/public/thinking.states.json +1 -0
  138. package/modules/hall-ui/public/tweak-editor.html +5 -5
  139. package/modules/hall-ui/public/tweak-editor.js +5 -1
  140. package/modules/hall-ui/public/tweak-editor.states.json +1 -0
  141. package/modules/hall-ui/public/update-pill.js +91 -2
  142. package/modules/hall-ui/public/visor.css +80 -0
  143. package/modules/hall-ui/public/visor.js +316 -0
  144. package/modules/hall-ui/public/watch-repo-invite.js +159 -0
  145. package/modules/hall-ui/public/watch.html +6 -5
  146. package/modules/hall-ui/public/watch.js +17 -2
  147. package/modules/hall-ui/public/watch.states.json +1 -0
  148. package/modules/hall-ui/public/welcome-boot.js +15 -6
  149. package/modules/hall-ui/public/work-founding.states.json +1 -0
  150. package/modules/hall-ui/public/work.html +5 -5
  151. package/modules/hall-ui/public/work.states.json +1 -0
  152. package/modules/hall-ui/records/builders-roster.md +2 -2
  153. package/modules/hall-ui/records/craft-mode.md +13 -11
  154. package/modules/hall-ui/records/game-mode.md +2 -2
  155. package/modules/hall-ui/records/governor-street.md +1 -1
  156. package/modules/hall-ui/records/home-city.md +3 -1
  157. package/modules/hall-ui/records/market-watch-settings.md +2 -0
  158. package/modules/hall-ui/records/options-menu.md +15 -0
  159. package/modules/hall-ui/records/profile-roles.md +11 -11
  160. package/modules/hall-ui/records/sky.md +3 -3
  161. package/modules/hall-ui/records/start-screen.md +25 -0
  162. package/modules/hall-ui/records/tweak-editor.md +1 -1
  163. package/modules/hall-ui/records/update-pill.md +12 -0
  164. package/modules/hall-ui/records/visor.md +23 -0
  165. package/modules/hall-ui/records/welcome-tower.md +5 -5
  166. package/modules/hall-ui/specimens/components.states.json +2 -1
  167. package/modules/ideas/ideator-stats.js +3 -1
  168. package/modules/ideas/inbox.js +2 -2
  169. package/modules/lifecycle/activity.js +1 -1
  170. package/modules/lifecycle/cascade.js +4 -4
  171. package/modules/lifecycle/goal-spec-task.js +1 -1
  172. package/modules/lifecycle/help-requests.js +19 -15
  173. package/modules/lifecycle/kickoff-checklist.js +3 -3
  174. package/modules/lifecycle/kickoff-seed.js +1 -1
  175. package/modules/lifecycle/migrations/lifecycle_021_crafts_artisan_artist.sql +29 -0
  176. package/modules/lifecycle/mingle.js +4 -4
  177. package/modules/lifecycle/page-tweak-write.js +1 -1
  178. package/modules/lifecycle/routes/task-write-routes.js +3 -1
  179. package/modules/lifecycle/routes/tasks.js +3 -3
  180. package/modules/lifecycle/ship-card.js +2 -3
  181. package/modules/lifecycle/task-classifier.js +39 -29
  182. package/modules/lifecycle/tests/cascade.mjs +7 -7
  183. package/modules/onboarding/founding-mode.js +3 -0
  184. package/modules/onboarding/genesis-home.js +21 -1
  185. package/modules/onboarding/routes/onboarding.js +2 -0
  186. package/modules/page-notes/notes.js +3 -2
  187. package/modules/page-notes/split.js +1 -1
  188. package/modules/platform-identity/craft-rollup.js +35 -7
  189. package/modules/platform-identity/migrations/platform_identity_036_crafts_artisan_artist.sql +45 -0
  190. package/modules/platform-identity/platform-identity.js +2 -2
  191. package/modules/platform-identity/routes/community-leaderboard.js +2 -1
  192. package/modules/platform-identity/routes/community-search.js +2 -1
  193. package/modules/platform-identity/routes/sso.js +2 -1
  194. package/modules/platform-identity/tests/platform-identity.mjs +6 -6
  195. package/modules/public-landing/public/community.html +3 -5
  196. package/modules/public-landing/public/index.html +1 -1
  197. package/modules/public-landing/public/projects.html +1 -1
  198. package/modules/specialities/migrations/specialities_004_crafts_artisan_artist.sql +30 -0
  199. package/modules/specialities/routes/specialities.js +2 -2
  200. package/modules/status-ui/public/status.js +1 -1
  201. package/modules/ui-design/kit/fixtures/community-leaderboard.json +10 -10
  202. package/modules/ui-design/kit/fixtures/community-search.json +2 -2
  203. package/modules/ui-design/kit/fixtures/scouting-recruiter.json +1 -1
  204. package/modules/ui-design/public/brand.html +2 -2
  205. package/package-lock.json +2 -2
  206. package/package.json +1 -1
  207. package/release-notes.json +76 -0
  208. package/scripts/bongos/autobongos-loop.js +1 -1
  209. package/scripts/bongos/discipline-modes.json +7 -12
  210. package/scripts/bongos/fitness.js +1 -1
  211. package/scripts/bongos/gen-hall-sitemap.js +7 -7
  212. package/scripts/bongos/grade-smoke.js +2 -2
  213. package/scripts/bongos/init.js +2 -2
  214. package/scripts/bongos/newcomer-floor.config.json +1 -2
  215. package/scripts/bongos/newcomer-floor.js +4 -3
  216. package/scripts/bongos/newcomer-floor.templates.json +10 -12
  217. package/scripts/bongos/newcomer-floor.test.js +47 -38
  218. package/scripts/bongos/role-pack-guard.js +5 -4
  219. package/scripts/bongos/seed-tasks.example.json +3 -3
  220. package/scripts/bongos/setup.js +20 -107
  221. package/scripts/bongos/start.js +2 -2
  222. package/scripts/bongos/task.js +5 -4
  223. package/scripts/bongos/triage.js +1 -1
  224. package/scripts/bongos/worktree.js +16 -4
  225. package/scripts/hall-preview/README.md +2 -3
  226. package/scripts/setup-builder.js +6 -46
  227. package/src/bongos/auth-admission.js +8 -8
  228. package/src/bongos/craft-mode.js +2 -0
  229. package/src/bongos/db.js +39 -1
  230. package/src/bongos/github-repos.js +78 -0
  231. package/src/bongos/module-scope-map.js +22 -0
  232. package/src/bongos/role-stats.js +27 -11
  233. package/src/bongos/routes/github.js +100 -2
  234. package/src/bongos/routes/me.js +33 -0
  235. package/src/bongos/serve-internal.js +33 -11
  236. package/src/crafts.js +66 -0
  237. package/src/hall-helm.js +79 -0
  238. package/src/module-api.js +6 -1
  239. package/src/module-loader/manifest-schema.js +16 -0
  240. package/src/modules.js +2 -2
  241. package/src/role-responsibilities.js +6 -5
  242. package/tests/acclaim_feed_evidence_db.mjs +1 -1
  243. package/tests/activity_rollup_as_of.mjs +1 -1
  244. package/tests/api_alias_caller_ratchet.mjs +3 -3
  245. package/tests/application_lifecycle.mjs +1 -1
  246. package/tests/artist_review.mjs +1 -1
  247. package/tests/artist_review_goal.mjs +1 -1
  248. package/tests/blocker_hall_live_proof.mjs +1 -1
  249. package/tests/blocker_tasks_named_db.mjs +2 -2
  250. package/tests/canonical_profile_url.mjs +1 -1
  251. package/tests/cap_newcomer_tasks.mjs +13 -13
  252. package/tests/character_creation.mjs +294 -0
  253. package/tests/claim_gate_open_blocker.mjs +2 -2
  254. package/tests/claim_gate_rebase.mjs +6 -6
  255. package/tests/claude_materialize.mjs +1 -1
  256. package/tests/clawback_confirmed_backlog.mjs +3 -3
  257. package/tests/collab_page.mjs +8 -9
  258. package/tests/collab_self_settling.mjs +2 -2
  259. package/tests/community_leaderboard_route.mjs +13 -5
  260. package/tests/community_proof_db.mjs +3 -0
  261. package/tests/community_search_route.mjs +7 -6
  262. package/tests/conductor.mjs +1 -1
  263. package/tests/conductor_main_e2e.mjs +8 -8
  264. package/tests/copy_desk_flags_db.mjs +1 -1
  265. package/tests/copy_desk_page_approve.mjs +2 -2
  266. package/tests/copy_desk_page_claim.mjs +2 -2
  267. package/tests/copy_desk_page_next.mjs +1 -1
  268. package/tests/copy_desk_page_release.mjs +1 -1
  269. package/tests/copy_desk_page_submit.mjs +2 -2
  270. package/tests/core_258_box_session_claims_db.mjs +1 -1
  271. package/tests/craft_mode.mjs +48 -34
  272. package/tests/craft_mode_home.mjs +20 -20
  273. package/tests/craft_mode_looks.mjs +16 -15
  274. package/tests/craft_mode_nav.mjs +31 -29
  275. package/tests/craft_review_mode.mjs +46 -41
  276. package/tests/crafts_vocabulary.mjs +70 -0
  277. package/tests/cross_discipline_priority_direction.mjs +5 -5
  278. package/tests/design_reference.mjs +1 -1
  279. package/tests/fitness.mjs +7 -11
  280. package/tests/funded_project_pays_proof_db.mjs +1 -1
  281. package/tests/genesis_home.mjs +21 -1
  282. package/tests/github_chip.mjs +3 -3
  283. package/tests/github_repo_invite.mjs +379 -0
  284. package/tests/goal_criterion_confirm_ui.mjs +1 -1
  285. package/tests/goal_invite_consent.mjs +1 -1
  286. package/tests/goal_map_page.mjs +2 -2
  287. package/tests/goal_sort_staleness.mjs +1 -1
  288. package/tests/goal_spec_task.mjs +1 -1
  289. package/tests/goal_spec_task_db.mjs +3 -3
  290. package/tests/grade_engine.mjs +2 -2
  291. package/tests/grader_no_artifact.mjs +1 -1
  292. package/tests/grader_prompt_fencing.mjs +1 -1
  293. package/tests/grader_prompt_window_bound.mjs +1 -1
  294. package/tests/grader_reader_lens.mjs +2 -2
  295. package/tests/grader_severity_gate.mjs +1 -1
  296. package/tests/grader_unbacked_score.mjs +1 -1
  297. package/tests/hall_approval_queue.mjs +1 -1
  298. package/tests/hall_board_world.mjs +2 -2
  299. package/tests/hall_builders_page_pass.mjs +3 -2
  300. package/tests/hall_city.mjs +16 -30
  301. package/tests/hall_controls.mjs +52 -4
  302. package/tests/hall_fullscreen.mjs +27 -3
  303. package/tests/hall_helm.mjs +187 -0
  304. package/tests/hall_kit_charts.mjs +1 -1
  305. package/tests/hall_landing_boot.mjs +1 -1
  306. package/tests/hall_my_agents.mjs +16 -16
  307. package/tests/hall_nav.mjs +22 -15
  308. package/tests/hall_options_menu.mjs +247 -0
  309. package/tests/hall_oversight_world.mjs +1 -1
  310. package/tests/hall_palette.mjs +8 -9
  311. package/tests/hall_profile_world.mjs +3 -3
  312. package/tests/hall_record_world.mjs +6 -4
  313. package/tests/hall_settings_world.mjs +2 -1
  314. package/tests/hall_sitemap.mjs +6 -5
  315. package/tests/hall_start_screen.mjs +307 -0
  316. package/tests/hall_street.mjs +15 -28
  317. package/tests/hall_street_inside.mjs +17 -9
  318. package/tests/hall_studio_world.mjs +3 -3
  319. package/tests/hall_topbar_320.mjs +4 -2
  320. package/tests/hall_visor.mjs +224 -0
  321. package/tests/help_requests.mjs +47 -15
  322. package/tests/helpers.mjs +4 -4
  323. package/tests/home_city.mjs +6 -4
  324. package/tests/home_city_widget.mjs +33 -14
  325. package/tests/home_gallery_widget.mjs +4 -4
  326. package/tests/home_idea_box.mjs +6 -6
  327. package/tests/hub_community_page.mjs +3 -3
  328. package/tests/hub_craft_rollup.mjs +75 -36
  329. package/tests/hub_recent_ships.mjs +3 -2
  330. package/tests/idea_cascade.mjs +2 -2
  331. package/tests/idea_credit_streams_db.mjs +1 -1
  332. package/tests/idea_detail_page.mjs +1 -1
  333. package/tests/idea_ideate_full.mjs +5 -2
  334. package/tests/idea_spark_hall.mjs +1 -1
  335. package/tests/init.mjs +3 -3
  336. package/tests/instance_manifest.mjs +2 -2
  337. package/tests/kickoff_checklist.mjs +1 -1
  338. package/tests/leaderboard_roles.mjs +34 -25
  339. package/tests/lifecycle_claim_ladder_refs.mjs +55 -0
  340. package/tests/lightbulb.mjs +14 -10
  341. package/tests/main_discipline.mjs +8 -8
  342. package/tests/markdown_line_endings.mjs +1 -1
  343. package/tests/market_watch_pages.mjs +52 -74
  344. package/tests/me_streak_leaderboard_queries.mjs +3 -3
  345. package/tests/migration_allocation.mjs +1 -1
  346. package/tests/mingle.mjs +36 -21
  347. package/tests/module-scope-map.mjs +22 -2
  348. package/tests/module_api.mjs +1 -0
  349. package/tests/module_contributions.mjs +13 -13
  350. package/tests/module_manifest.mjs +29 -0
  351. package/tests/module_skills_hook.mjs +2 -2
  352. package/tests/modules.mjs +14 -7
  353. package/tests/nav_permission_atoms.mjs +2 -1
  354. package/tests/needs_rebase.mjs +1 -1
  355. package/tests/newcomer_restock.mjs +13 -13
  356. package/tests/page_notes_panel.mjs +22 -22
  357. package/tests/page_tweak_no_block.mjs +1 -1
  358. package/tests/paintbrush.mjs +7 -7
  359. package/tests/privacy_matrix.mjs +1 -0
  360. package/tests/profile_activity.mjs +20 -23
  361. package/tests/profile_earnings.mjs +1 -1
  362. package/tests/profile_nudge_prefs.mjs +4 -4
  363. package/tests/profile_role_headline.mjs +73 -46
  364. package/tests/profile_role_stats.mjs +55 -45
  365. package/tests/profile_rollup_consent.mjs +19 -6
  366. package/tests/profile_route.mjs +12 -12
  367. package/tests/profile_ui_cross_project.mjs +4 -4
  368. package/tests/project_invite_suggestions.mjs +2 -2
  369. package/tests/promote_goal_id.mjs +1 -1
  370. package/tests/publish_manifest.mjs +1 -1
  371. package/tests/rank_floor_wiring.mjs +1 -1
  372. package/tests/regrade_actual_minutes.mjs +1 -1
  373. package/tests/removal_proposal.mjs +2 -2
  374. package/tests/reward_gate.mjs +4 -4
  375. package/tests/reward_mode_cost_plus_only.mjs +1 -1
  376. package/tests/role_responsibilities.mjs +18 -12
  377. package/tests/role_stats_db.mjs +17 -16
  378. package/tests/scouting_rollup_fanout.mjs +5 -5
  379. package/tests/seed_tasks.mjs +5 -2
  380. package/tests/session_earnings_mirror_db.mjs +1 -1
  381. package/tests/session_reward_on_land_db.mjs +1 -1
  382. package/tests/session_reward_reconcile_db.mjs +2 -2
  383. package/tests/sessions_kit_pager.mjs +1 -1
  384. package/tests/settings_art_key_absent.mjs +2 -2
  385. package/tests/settings_main_role.mjs +21 -20
  386. package/tests/setup_flow.mjs +3 -3
  387. package/tests/setup_smoke.mjs +20 -0
  388. package/tests/ship_card.mjs +6 -6
  389. package/tests/specialities.mjs +16 -4
  390. package/tests/speciality_db_shape.mjs +6 -6
  391. package/tests/speciality_injection.mjs +17 -17
  392. package/tests/speciality_offer_ui.mjs +5 -5
  393. package/tests/speciality_offered.mjs +6 -5
  394. package/tests/speciality_session_skills.mjs +7 -7
  395. package/tests/speciality_skills.mjs +11 -11
  396. package/tests/speciality_walkthrough_ui.mjs +2 -2
  397. package/tests/sso_checkin_identity_spoof.mjs +2 -1
  398. package/tests/task_classifier_vocab.mjs +10 -0
  399. package/tests/task_cli.mjs +11 -3
  400. package/tests/task_criteria_unlink_db.mjs +2 -2
  401. package/tests/task_discipline_required.mjs +38 -16
  402. package/tests/task_goal_required.mjs +4 -4
  403. package/tests/task_needs_db.mjs +1 -1
  404. package/tests/tweak_replaces_artist_review.mjs +1 -1
  405. package/tests/update_pill.mjs +153 -2
  406. package/tests/upkeep_home.mjs +1 -1
  407. package/tests/v3_c1_options_proof.mjs +145 -0
  408. package/tests/visual_review.mjs +3 -3
  409. package/tests/watch_applications_queue.mjs +8 -5
  410. package/tests/watch_sealed_floor.mjs +3 -1
  411. package/tests/welcome_boot.mjs +12 -9
  412. package/tests/welcome_boot_browser.mjs +13 -13
  413. package/tests/worktree_helper.mjs +16 -1
@@ -32,15 +32,19 @@
32
32
  grounds in both modes with ~9% of headroom. tests/hall_tokens.mjs measures
33
33
  them; do not hand-tune one without re-running it.
34
34
 
35
- b. THE HALL KEEPS BOTH MODES, ON ITS OWN SWITCH. The apex went dark only
36
- (ADR 0204), so light is the hall's alone. shell.js writes
37
- html[data-theme] — NOT the world's html[data-mode] — so the dark tier is
38
- written twice on THAT pair: html[data-theme="dark"] and, for first paint
39
- before the script runs, @media (prefers-color-scheme: dark)
40
- html:not([data-theme]). Both bodies are byte-identical; the twins rule is
41
- what keeps them so. html[data-theme="dark"] is (0,1,1) and outranks the
42
- pack's injected :root (0,1,0), which is what lets dark win over the pack
43
- while the instance's accent survives.
35
+ b. THE HALL IS DARK ONLY, AND ITS DARK TIER IS HELM (task 1005192, ADR
36
+ 0402). The server stamps html[data-theme="dark"] on every hall page and
37
+ shell.js sets it again; nothing offers light. The attribute is the
38
+ hall's own — NOT the world's html[data-mode] — and the dark tier is
39
+ still written twice on that pair: html[data-theme="dark"] and @media
40
+ (prefers-color-scheme: dark) html:not([data-theme]), for a page read
41
+ without the server's stamp. Both bodies are byte-identical; the twins
42
+ rule is what keeps them so. html[data-theme="dark"] is (0,1,1) and
43
+ outranks the pack's injected :root (0,1,0), which is what lets the night
44
+ win over the pack while the instance's accent survives. The light values
45
+ in :root are no longer rendered by the hall; they stay until the light
46
+ tier's own removal (the ADR 0204 precedent), so the sheets and tests
47
+ that still measure light keep measuring.
44
48
 
45
49
  c. --line IS A WIDTH HERE, NOT A COLOUR (DESIGN.md warns about exactly this
46
50
  name). The hairline's COLOUR is --rule / --rule-soft.
@@ -253,9 +257,67 @@
253
257
  --plate: none;
254
258
  --plate-blend: lighten;
255
259
  --plate-veil: none;
256
- }
257
260
 
258
- /* ---------- dark theme ----------
261
+ /* ---- HELM: the hall's look (task 1005192, ADR 0402). The kit's recipes,
262
+ named once here so no page sheet types one in. None of them flips
263
+ with the mode; the Helm NEUTRALS are the dark tier below, which is
264
+ the only tier the hall renders.
265
+
266
+ TYPE, TWO VOICES. The name voice names a thing (a title, a button, an
267
+ eyebrow): the display face in wide tracked capitals. Everything said
268
+ to you is the body face in plain sentences. --helm-display and
269
+ --helm-body are the Helm faces themselves; html[data-faces="helm"]
270
+ (below the dark twins) hands them to --font-display / --font-body for
271
+ a hall whose pack has not chosen faces of its own. ---- */
272
+ --helm-display: "Barlow Condensed", "Arial Narrow", "Segoe UI", system-ui, sans-serif;
273
+ --helm-body: "Barlow", "Segoe UI", system-ui, -apple-system, sans-serif;
274
+ --name-face: var(--font-display);
275
+ --name-weight: 500;
276
+ --name-weight-lit: 600;
277
+ --name-case: uppercase;
278
+ --name-space: .24em;
279
+ --name-space-wide: .3em;
280
+ --name-space-tight: .16em;
281
+ /* a title's glow: the soft ink, never the accent (the accent is for what you
282
+ can act on) */
283
+ --name-glow: 0 0 22px color-mix(in srgb, var(--ink-soft) 45%, transparent);
284
+
285
+ /* SHAPE, THREE MOVES (the arc is the visor's and is not in this slice).
286
+ THE CUT CORNER is anything you can press: top-left and bottom-right cut,
287
+ no pill. A clip-path clips an outline, so a cut control's focus is the
288
+ inset two-tone ring --press-focus: the focus colour on the edge, then a
289
+ band of the ground, so one of the two reads on any fill. */
290
+ --cut: 12px;
291
+ --cut-sm: 8px;
292
+ --cut-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
293
+ --cut-path-sm: polygon(var(--cut-sm) 0, 100% 0, 100% calc(100% - var(--cut-sm)), calc(100% - var(--cut-sm)) 100%, 0 100%, 0 var(--cut-sm));
294
+ --press-radius: 0px;
295
+ --press-fill: var(--surface-2);
296
+ --press-focus: inset 0 0 0 2px var(--focus), inset 0 0 0 4px var(--bg);
297
+ /* THE SEGMENT is progress: one small skewed bar per step. */
298
+ --seg-w: 40px;
299
+ --seg-h: 8px;
300
+ --seg-gap: var(--ds-space-hair);
301
+ --seg-skew: -28deg;
302
+
303
+ /* THE PANEL OVER ART: the ground at 72%, closed left and right by the strong
304
+ hairline. --helm-inset is how far a full-height panel stands off the left
305
+ edge: nothing on a phone, growing to its full step on a desk, with no
306
+ breakpoint. */
307
+ --night-glass: color-mix(in srgb, var(--bg) 72%, transparent);
308
+ --line-strong: 1.5px;
309
+ --helm-panel-w: 400px;
310
+ --helm-row: 60px;
311
+ --helm-mark: 60px;
312
+ --helm-inset: clamp(0px, calc((100vw - var(--helm-panel-w)) * .1), 96px);
313
+ }
314
+
315
+ /* ---------- dark theme: the Helm neutrals ----------
316
+ The only tier the hall renders (task 1005192, ADR 0402). Each colour has one
317
+ job: NIGHT is the ground and every panel (--bg; --bg-card is the night
318
+ lifted a step, for a panel at rest); ICE is information you read
319
+ (--ink-soft, and the hairlines as ice at 40% and 20%); WHITE is names and
320
+ numbers (--ink); the pack's --accent is only what you can act on.
259
321
  Only the NEUTRALS and the mode-dependent derivations flip; the pack's
260
322
  accent/sea/terracotta + fonts survive (the Unpinned Accent Rule — a dark
261
323
  block may pin no accent literal, or a re-themed instance cannot reach dark),
@@ -265,24 +327,24 @@
265
327
 
266
328
  html[data-theme="dark"] {
267
329
  color-scheme: dark;
268
- --bg: #000000;
269
- --bg-card: #101012;
270
- --bg-deep: #000000;
271
- --bg-frame: #08080a;
330
+ --bg: #050d16;
331
+ --bg-card: #0a1622;
332
+ --bg-deep: #050d16;
333
+ --bg-frame: #07111b;
272
334
  --ink: #ffffff;
273
- --ink-soft: #c0c0c0;
274
- --ink-faint: #a8a8a8;
275
- --rule: rgba(255, 255, 255, .16);
276
- --rule-soft: rgba(255, 255, 255, .08);
277
- --glass: rgba(255, 255, 255, .11);
278
- --glass-strong: rgba(255, 255, 255, .17);
279
- --glass-edge: rgba(255, 255, 255, .13);
335
+ --ink-soft: #c8f1f7;
336
+ --ink-faint: #a9cdd4;
337
+ --rule: rgba(200, 241, 247, .4);
338
+ --rule-soft: rgba(200, 241, 247, .2);
339
+ --glass: rgba(200, 241, 247, .1);
340
+ --glass-strong: rgba(200, 241, 247, .16);
341
+ --glass-edge: rgba(200, 241, 247, .2);
280
342
  --glass-blur: 18px;
281
- --void: #000000;
343
+ --void: #050d16;
282
344
  --void-ink: var(--ink);
283
- --void-edge: rgba(255, 255, 255, .16);
345
+ --void-edge: rgba(200, 241, 247, .4);
284
346
  --accent-ink: var(--accent);
285
- --accent-tint: color-mix(in srgb, var(--accent) 22%, #0b0a09);
347
+ --accent-tint: color-mix(in srgb, var(--accent) 22%, #050d16);
286
348
  --accent-glow: 0 8px 28px color-mix(in srgb, var(--accent) 38%, transparent);
287
349
  --ok: #4ade80;
288
350
  --ok-weak: color-mix(in srgb, #4ade80 14%, var(--bg-card));
@@ -293,36 +355,36 @@ html[data-theme="dark"] {
293
355
  --info: color-mix(in srgb, var(--sea) 80%, #ffffff);
294
356
  --info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
295
357
  --focus: var(--accent);
296
- --label-face: var(--font-body);
358
+ --label-face: var(--font-display);
297
359
  --label-size: var(--ds-text-2xs-plus);
298
- --label-space: .1em;
360
+ --label-space: .2em;
299
361
  --type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
300
362
  --surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
301
- --plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
363
+ --plate-veil: linear-gradient(to bottom, rgba(5, 13, 22, .82), rgba(5, 13, 22, .93));
302
364
  }
303
365
  html[data-theme="dark"] body { background: var(--bg); }
304
366
 
305
367
  @media (prefers-color-scheme: dark) {
306
368
  html:not([data-theme]) {
307
369
  color-scheme: dark;
308
- --bg: #000000;
309
- --bg-card: #101012;
310
- --bg-deep: #000000;
311
- --bg-frame: #08080a;
370
+ --bg: #050d16;
371
+ --bg-card: #0a1622;
372
+ --bg-deep: #050d16;
373
+ --bg-frame: #07111b;
312
374
  --ink: #ffffff;
313
- --ink-soft: #c0c0c0;
314
- --ink-faint: #a8a8a8;
315
- --rule: rgba(255, 255, 255, .16);
316
- --rule-soft: rgba(255, 255, 255, .08);
317
- --glass: rgba(255, 255, 255, .11);
318
- --glass-strong: rgba(255, 255, 255, .17);
319
- --glass-edge: rgba(255, 255, 255, .13);
375
+ --ink-soft: #c8f1f7;
376
+ --ink-faint: #a9cdd4;
377
+ --rule: rgba(200, 241, 247, .4);
378
+ --rule-soft: rgba(200, 241, 247, .2);
379
+ --glass: rgba(200, 241, 247, .1);
380
+ --glass-strong: rgba(200, 241, 247, .16);
381
+ --glass-edge: rgba(200, 241, 247, .2);
320
382
  --glass-blur: 18px;
321
- --void: #000000;
383
+ --void: #050d16;
322
384
  --void-ink: var(--ink);
323
- --void-edge: rgba(255, 255, 255, .16);
385
+ --void-edge: rgba(200, 241, 247, .4);
324
386
  --accent-ink: var(--accent);
325
- --accent-tint: color-mix(in srgb, var(--accent) 22%, #0b0a09);
387
+ --accent-tint: color-mix(in srgb, var(--accent) 22%, #050d16);
326
388
  --accent-glow: 0 8px 28px color-mix(in srgb, var(--accent) 38%, transparent);
327
389
  --ok: #4ade80;
328
390
  --ok-weak: color-mix(in srgb, #4ade80 14%, var(--bg-card));
@@ -333,16 +395,27 @@ html[data-theme="dark"] body { background: var(--bg); }
333
395
  --info: color-mix(in srgb, var(--sea) 80%, #ffffff);
334
396
  --info-weak: color-mix(in srgb, var(--info) 14%, var(--bg-card));
335
397
  --focus: var(--accent);
336
- --label-face: var(--font-body);
398
+ --label-face: var(--font-display);
337
399
  --label-size: var(--ds-text-2xs-plus);
338
- --label-space: .1em;
400
+ --label-space: .2em;
339
401
  --type-halo: 0 2px 18px rgba(0, 0, 0, .94), 0 0 54px rgba(0, 0, 0, .72);
340
402
  --surface-2: color-mix(in srgb, var(--ink) 6%, var(--bg-card));
341
- --plate-veil: linear-gradient(to bottom, rgba(0, 0, 0, .82), rgba(0, 0, 0, .93));
403
+ --plate-veil: linear-gradient(to bottom, rgba(5, 13, 22, .82), rgba(5, 13, 22, .93));
342
404
  }
343
405
  html:not([data-theme]) body { background: var(--bg); }
344
406
  }
345
407
 
408
+ /* The Helm faces (task 1005192, ADR 0402). The server stamps data-faces="helm"
409
+ on a hall page whose pack still names the platform's default faces
410
+ (src/hall-helm.js) and links the two families. (0,1,1) outranks the pack's
411
+ spliced :root, so the hall reads Barlow while the landing keeps the pack's
412
+ face; a hall that wears faces of its own never gets the attribute and keeps
413
+ them. */
414
+ html[data-faces="helm"] {
415
+ --font-display: var(--helm-display);
416
+ --font-body: var(--helm-body);
417
+ }
418
+
346
419
  /* The Kill Switch Rule (DESIGN.md). Nothing escapes it, and no motion is
347
420
  authored in JavaScript, because JavaScript motion escapes it. */
348
421
  @media (prefers-reduced-motion: reduce) {
@@ -712,6 +785,16 @@ html[data-theme="dark"] .brand-mark__mark { --mark-ink: #e2e1e4; }
712
785
  .founding-band { flex-wrap: wrap; row-gap: 2px; padding: 8px 16px; }
713
786
  .founding-band__desc { display: none; }
714
787
  .founding-band__stage { margin-left: 0; white-space: normal; }
788
+ /* task 1005148, the visor (visor.css): the top of a phone belongs to the scene and the shell’s
789
+ corner buttons, so the compass and the place line step aside and all three pills share the
790
+ bottom row: the main action, Actions (its dots and key only), the sprite with the credits. */
791
+ html[data-game="on"] .visor:not([hidden]) { --visor-inset-right: var(--ds-space-gutter-narrow); --visor-inset-left: var(--ds-space-gutter-narrow); --visor-inset-bottom: 40px; }
792
+ html[data-game="on"] .visor__place, html[data-game="on"] .visor__cell, html[data-game="on"] .visor__mark { display: none; }
793
+ html[data-game="on"] .visor__pill--actions { top: auto; right: auto; left: 50%; bottom: var(--visor-inset-bottom); transform: translateX(-50%); padding: 0 var(--ds-space-xs); }
794
+ html[data-game="on"] .visor__pill--actions > span:not(.visor__dots) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
795
+ html[data-game="on"] .visor__sheet { top: auto; bottom: calc(var(--visor-inset-bottom) + 56px); right: var(--visor-inset-right); max-height: 70vh; }
796
+ html[data-game="on"] .visor__me .visor__name { display: none; }
797
+ html[data-game="on"] .visor__me { padding: 4px var(--ds-space-xs) 4px 4px; }
715
798
  }
716
799
  /* task 1004424 (BV2.PS10): THE FOUNDING MARK. A pill in .rank-badge's grammar (same
717
800
  height, type and radius) so it sits beside a rank without competing with it; the
@@ -1172,23 +1255,7 @@ html[data-handoff="on"] .app-content { padding: 0; }
1172
1255
  .topbar-menu:hover { color: var(--ink); }
1173
1256
  .topbar-menu svg { width: 16px; height: 16px; }
1174
1257
 
1175
- .theme-toggle {
1176
- display: inline-flex;
1177
- align-items: center;
1178
- justify-content: center;
1179
- width: 32px; height: 32px;
1180
- border: 0;
1181
- border-radius: var(--radius-pill);
1182
- background: none;
1183
- color: var(--ink-soft);
1184
- cursor: pointer;
1185
- padding: 0;
1186
- flex-shrink: 0;
1187
- }
1188
- .theme-toggle:hover { color: var(--ink); }
1189
- .theme-toggle svg { width: 16px; height: 16px; }
1190
-
1191
- /* task 1475: the accessibility zoom control — sibling of the theme toggle.
1258
+ /* task 1475: the accessibility zoom control.
1192
1259
  Widens to fit the "125%"/"150%" label when zoom is active. */
1193
1260
  .zoom-toggle {
1194
1261
  display: inline-flex;
@@ -1255,7 +1322,15 @@ html[data-fullscreen="on"] .app-topbar {
1255
1322
  pointer-events: none;
1256
1323
  }
1257
1324
  html[data-fullscreen="on"] .app-topbar > :not(.topbar-side),
1258
- html[data-fullscreen="on"] .topbar-side > :not(.fullscreen-toggle) { display: none; }
1325
+ html[data-fullscreen="on"] .topbar-side > :not(.fullscreen-toggle):not(.upd-pill) { display: none; }
1326
+ /* task 1005191: the Update pill stays with the bars away. Game mode opens every page
1327
+ this way, and an update nobody can see is an update nobody takes. */
1328
+ html[data-fullscreen="on"] .upd-pill {
1329
+ pointer-events: auto;
1330
+ min-height: 36px;
1331
+ margin-right: 8px;
1332
+ box-shadow: var(--shadow-pop);
1333
+ }
1259
1334
  /* task 1004430: the way back must read on ANY ground. The hall's glass is
1260
1335
  near-clear, so over the black sky in the light theme it was a dark glyph on
1261
1336
  black — the page looked stuck without its bars. The card tone plus a drop
@@ -1281,6 +1356,16 @@ html[data-fullscreen="on"] .fullscreen-toggle:hover { color: var(--accent-ink);
1281
1356
  /* A page with no full-screen layout of its own steps its content clear of the
1282
1357
  corner button; the sky and the studio lay themselves out (shell.js `plain`). */
1283
1358
  html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-top: 60px; }
1359
+ /* EMBEDDED (html[data-embed="on"], shell-game.js; task 1005144, ADR 0401): a screen
1360
+ opened inside the options menu's frame. The menu is the chrome, so the page keeps
1361
+ none of its own — no sidebar, scrim, foot or top bar — and sits on the frame's
1362
+ ground. The page keeps its one <header> in the DOM (hidden), as full screen does. */
1363
+ html[data-embed="on"] .app-sidebar,
1364
+ html[data-embed="on"] .app-scrim,
1365
+ html[data-embed="on"] .app-foot,
1366
+ html[data-embed="on"] .app-topbar { display: none; }
1367
+ html[data-embed="on"] .app-body { margin-left: 0; }
1368
+ html[data-embed="on"] .app-content { padding-top: 0; }
1284
1369
  /* Said once on entering, since the choice is remembered and a page can open in it. */
1285
1370
  .fullscreen-hint {
1286
1371
  position: fixed;
@@ -1313,7 +1398,8 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
1313
1398
  flex-shrink: 0;
1314
1399
  }
1315
1400
  .craft-switch__opt,
1316
- .craft-switch__open {
1401
+ .craft-switch__open,
1402
+ .craft-switch__me {
1317
1403
  display: inline-flex;
1318
1404
  align-items: center;
1319
1405
  gap: 6px;
@@ -1330,10 +1416,12 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
1330
1416
  white-space: nowrap;
1331
1417
  }
1332
1418
  .craft-switch__opt:hover,
1333
- .craft-switch__open:hover { color: var(--ink); background: var(--glass); }
1419
+ .craft-switch__open:hover,
1420
+ .craft-switch__me:hover { color: var(--ink); background: var(--glass); }
1334
1421
  .craft-switch__opt[aria-pressed="true"] { color: var(--ink); background: var(--glass-strong); }
1335
1422
  .craft-switch__opt:focus-visible,
1336
- .craft-switch__open:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
1423
+ .craft-switch__open:focus-visible,
1424
+ .craft-switch__me:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
1337
1425
  .craft-switch__icon { width: 15px; height: 15px; flex-shrink: 0; }
1338
1426
  .craft-switch__open { display: none; }
1339
1427
  @media (max-width: 1180px) {
@@ -1344,7 +1432,23 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
1344
1432
  .craft-switch { padding: 2px; }
1345
1433
  .craft-switch__opt[aria-pressed="false"] { display: none; }
1346
1434
  .craft-switch--unset .craft-switch__open { display: inline-flex; padding: 0 7px; }
1347
- }
1435
+ .craft-switch__me { padding: 0 2px; }
1436
+ .craft-switch__me .craft-switch__label { display: none; }
1437
+ }
1438
+
1439
+ /* THE CHARACTER (task 1005147). A builder who holds a character wears its sprite in
1440
+ the top bar in place of the switch: one button, which offers "Change character"
1441
+ (signing out). The sprites are pixel art, so they scale by whole pixels. */
1442
+ .craft-sprite { display: block; image-rendering: pixelated; object-fit: contain; }
1443
+ .craft-switch__me { padding: 0 10px 0 4px; color: var(--ink); }
1444
+ /* The chip is the figure's head: the portrait cropped round its top third. */
1445
+ .craft-sprite--chip { width: 26px; height: 26px; border-radius: var(--radius-pill); object-fit: cover; object-position: 50% 22%; }
1446
+ /* Character creation: each door is the owner's portrait — the figure on its plinth
1447
+ in the torch-lit hall — filling the top of the door, the words beneath it. */
1448
+ .craft-plinth { display: block; overflow: hidden; }
1449
+ .craft-sprite--door { width: 100%; height: auto; aspect-ratio: 250 / 290; transition: transform 200ms cubic-bezier(.2, .7, .3, 1); }
1450
+ .craft-door--character:hover .craft-sprite--door,
1451
+ .craft-door--character:focus-visible .craft-sprite--door { transform: scale(1.03); }
1348
1452
 
1349
1453
  /* The picker: a dialog over a scrim, four doors in a row above the
1350
1454
  "ask me again" box. Each door carries its scene from the approved prototype,
@@ -1427,7 +1531,8 @@ html.setup-gate-open { overflow: hidden; }
1427
1531
  .setup-gate__craft[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-tint); }
1428
1532
  /* The save is the shared primary door (controls.css, task 1005084). */
1429
1533
  .setup-gate__save { margin-top: 12px; }
1430
- .setup-gate__err { margin: 8px 0 0; font-size: 14px; color: var(--danger); }
1534
+ .setup-gate__err,
1535
+ .craft-picker__error { margin: 8px 0 0; font-size: 14px; color: var(--danger); }
1431
1536
  .setup-gate__foot { margin: 24px 0 0; font-size: 14px; }
1432
1537
  .setup-gate__foot a { color: var(--ink-soft); }
1433
1538
  @media (max-width: 640px) { .setup-gate__panel { padding: 28px 20px 20px; border-radius: 18px; } }
@@ -1525,9 +1630,9 @@ html.setup-gate-open { overflow: hidden; }
1525
1630
  overflow: hidden;
1526
1631
  background: #101012;
1527
1632
  }
1528
- .craft-art--artistry { background: #0c1122; }
1633
+ .craft-art--artist { background: #0c1122; }
1529
1634
  .craft-art--ideating { background: #05060d; }
1530
- .craft-art--governing { background: #000; }
1635
+ .craft-art--patron { background: #000; }
1531
1636
  .craft-art__dot { position: absolute; border-radius: 999px; box-sizing: border-box; }
1532
1637
  .craft-art__dot--star { background: #d8dcf0; }
1533
1638
  .craft-art__dot--lit { background: var(--accent); border-radius: 0; }
@@ -1592,6 +1697,11 @@ html.setup-gate-open { overflow: hidden; }
1592
1697
  .craft-door__head { padding: 10px 16px 0; }
1593
1698
  .craft-door__name { font-size: 18px; }
1594
1699
  .craft-door__line { flex: 0 0 100%; padding: 0 16px; box-sizing: border-box; }
1700
+ /* A phone stacks the three as rows: the portrait on the left, the words beside it. */
1701
+ .craft-door.craft-door--character { display: grid; grid-template-columns: 86px minmax(0, 1fr); grid-template-rows: auto 1fr; align-content: start; gap: 4px 14px; padding: 0; }
1702
+ .craft-plinth { grid-row: 1 / span 2; width: 86px; }
1703
+ .craft-door.craft-door--character > .craft-door__head { padding: 12px 14px 0 0; }
1704
+ .craft-door.craft-door--character > .craft-door__line { padding: 0 14px 12px 0; }
1595
1705
  }
1596
1706
 
1597
1707
  /* THE CRAFT MODE LOOKS (task 1004495; direction docs/design/craft-mode-direction.md).
@@ -1601,37 +1711,30 @@ html.setup-gate-open { overflow: hidden; }
1601
1711
  what to press: the accent stays the action colour in every mode. Light values
1602
1712
  clear 5.4:1 on the hall's paper; the dark values are the prototype's. Light
1603
1713
  keeps the paper ground; only dark changes the ground and the glass. */
1604
- html[data-craft="artistry"] { --craft: #2e3c6e; --craft-on: #f1e6d2; }
1605
- html[data-craft="ideating"] { --craft: #7a5a0c; --craft-on: #fdf6dd; }
1606
- html[data-craft="governing"] { --craft: #33479e; --craft-on: #eef1ff; }
1607
- html[data-theme="dark"][data-craft="artistry"] {
1714
+ html[data-craft="artist"] { --craft: #2e3c6e; --craft-on: #f1e6d2; }
1715
+ html[data-craft="patron"] { --craft: #33479e; --craft-on: #eef1ff; }
1716
+ html[data-theme="dark"][data-craft="artist"] {
1608
1717
  --craft: #f1e6d2; --craft-on: #0c1122;
1609
1718
  --bg: #07080d; --bg-frame: #0a0b12;
1610
1719
  --glass: rgba(150, 170, 230, .11); --glass-strong: rgba(170, 190, 240, .17);
1611
1720
  --glass-edge: rgba(241, 230, 210, .16);
1612
1721
  }
1613
- html[data-theme="dark"][data-craft="ideating"] {
1614
- --craft: #f2d27a; --craft-on: #1d1604;
1615
- --bg: #05060d;
1616
- --glass: rgba(140, 150, 225, .10); --glass-strong: rgba(160, 170, 240, .16);
1617
- --glass-edge: rgba(242, 210, 122, .16);
1618
- }
1619
- html[data-theme="dark"][data-craft="governing"] {
1722
+ html[data-theme="dark"][data-craft="patron"] {
1620
1723
  --craft: #aabeff; --craft-on: #0a1030;
1621
1724
  --glass-edge: rgba(170, 190, 255, .16);
1622
1725
  }
1623
1726
  /* The shared treatment: the switch's current pill, the current tab and the top
1624
1727
  bar's hairline take the mode colour. */
1625
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .craft-switch__opt[aria-pressed="true"] {
1728
+ html:is([data-craft="artist"], [data-craft="patron"]) .craft-switch__opt[aria-pressed="true"] {
1626
1729
  background: var(--craft); color: var(--craft-on);
1627
1730
  }
1628
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .nav-item--active {
1731
+ html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active {
1629
1732
  background: color-mix(in srgb, var(--craft) 14%, transparent); color: var(--craft);
1630
1733
  }
1631
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .nav-item--active .nav-icon,
1632
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .nav-item--active .nav-item__label { color: var(--craft); }
1633
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .nav-item--active::before { background: var(--craft); }
1634
- html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing"]) .app-topbar {
1734
+ html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active .nav-icon,
1735
+ html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active .nav-item__label { color: var(--craft); }
1736
+ html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active::before { background: var(--craft); }
1737
+ html:is([data-craft="artist"], [data-craft="patron"]) .app-topbar {
1635
1738
  border-bottom-color: color-mix(in srgb, var(--craft) 30%, transparent);
1636
1739
  }
1637
1740
  /* The header mark: the mode's own words beside the page title (craft-mode.js
@@ -1735,7 +1838,7 @@ html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing
1735
1838
  .craft-plate .craft-art { width: calc(100% / .582); transform: scale(.582); }
1736
1839
  }
1737
1840
  /* The plate follows the theme (owner, 2026-10-03): light shows each scene's day. */
1738
- html[data-theme="light"] .craft-plate .craft-art--artistry { background: #dfe3ef; }
1841
+ html[data-theme="light"] .craft-plate .craft-art--artist { background: #dfe3ef; }
1739
1842
  html[data-theme="light"] .craft-plate .craft-art__dot--star { background: #2e3c6e; }
1740
1843
  html[data-theme="light"] .craft-plate .craft-art__moon { background: #f3c98b; box-shadow: 0 0 0 9px rgba(243, 201, 139, .28); }
1741
1844
  html[data-theme="light"] .craft-plate .craft-art__ground { background: #c3c9dc; }
@@ -1745,28 +1848,8 @@ html[data-theme="light"] .craft-plate .craft-art__dot--gold { background: #c9a23
1745
1848
  html[data-theme="light"] .craft-plate .craft-art__dot--glow { background: #b8891c; box-shadow: 0 0 10px rgba(184, 137, 28, .45); }
1746
1849
  html[data-theme="light"] .craft-plate .craft-art__dot--proto { box-shadow: inset 0 0 0 1px rgba(122, 90, 12, .6); }
1747
1850
  html[data-theme="light"] .craft-plate .craft-art__ring { box-shadow: inset 0 0 0 1px rgba(122, 90, 12, .35); }
1748
- html[data-theme="light"] .craft-plate .craft-art--governing { background: #e9ecf6; }
1851
+ html[data-theme="light"] .craft-plate .craft-art--patron { background: #e9ecf6; }
1749
1852
  html[data-theme="light"] .craft-plate .craft-art__city { filter: invert(1) hue-rotate(180deg); }
1750
- /* Ideating's star dust: a few faint fixed specks across the rail itself. */
1751
- html[data-craft="ideating"] .app-sidebar {
1752
- background-image:
1753
- radial-gradient(1px 1px at 14px 40px, rgba(242, 210, 122, .5), transparent),
1754
- radial-gradient(1px 1px at 46px 130px, rgba(242, 210, 122, .35), transparent),
1755
- radial-gradient(1.5px 1.5px at 120px 90px, rgba(242, 210, 122, .4), transparent),
1756
- radial-gradient(1px 1px at 200px 190px, rgba(242, 210, 122, .35), transparent),
1757
- radial-gradient(1px 1px at 30px 230px, rgba(242, 210, 122, .3), transparent),
1758
- radial-gradient(1.5px 1.5px at 170px 260px, rgba(242, 210, 122, .3), transparent);
1759
- background-size: 246px 280px;
1760
- }
1761
- html[data-theme="light"][data-craft="ideating"] .app-sidebar {
1762
- background-image:
1763
- radial-gradient(1px 1px at 14px 40px, rgba(184, 137, 28, .45), transparent),
1764
- radial-gradient(1px 1px at 46px 130px, rgba(184, 137, 28, .3), transparent),
1765
- radial-gradient(1.5px 1.5px at 120px 90px, rgba(184, 137, 28, .35), transparent),
1766
- radial-gradient(1px 1px at 200px 190px, rgba(184, 137, 28, .3), transparent),
1767
- radial-gradient(1px 1px at 30px 230px, rgba(184, 137, 28, .25), transparent),
1768
- radial-gradient(1.5px 1.5px at 170px 260px, rgba(184, 137, 28, .25), transparent);
1769
- }
1770
1853
 
1771
1854
  /* THE MODE TOOLS (task 1004496, craft-mode.js TOOLS): a round button beside the
1772
1855
  switch, in the mode's colour, shown only in its own mode. Artistry's palette
@@ -1965,7 +2048,7 @@ html.pb-editing main { padding-bottom: 180px; }
1965
2048
  tighter and each icon button is 28px — still above the 24px floor — so the
1966
2049
  whole row fits with room to spare. Pinned in tests/hall_topbar_320.mjs. */
1967
2050
  .app-topbar { gap: var(--ds-space-hair); padding: 0 var(--ds-space-xs); }
1968
- .topbar-menu, .theme-toggle, .fullscreen-toggle { width: 28px; height: 28px; }
2051
+ .topbar-menu, .fullscreen-toggle { width: 28px; height: 28px; }
1969
2052
  .zoom-toggle { min-width: 28px; height: 28px; padding: 0 6px; }
1970
2053
  .topbar-side .topbar-jump { min-width: 28px; padding: 0 6px; }
1971
2054
  }
@@ -2047,11 +2130,13 @@ html.pb-editing main { padding-bottom: 180px; }
2047
2130
  /* Focus: the world's two-tone ring — a 2px accent-derived outline at 3px offset
2048
2131
  inside an 8px --bg halo, so the indicator keeps its own edge over whatever it
2049
2132
  lands on (a bare outline measured 1.1:1 over the light bar). The rail's items
2050
- ring inside themselves instead, or the halo would spill out of the 64px strip. */
2133
+ ring inside themselves instead, or the halo would spill out of the 64px strip.
2134
+ A CUT control (controls.css) hands in --focus-ring: its clip-path would clip
2135
+ the outline and the halo away, so its ring is the inset two-tone one. */
2051
2136
  :focus-visible {
2052
2137
  outline: 2px solid var(--focus);
2053
2138
  outline-offset: 3px;
2054
- box-shadow: 0 0 0 8px var(--bg);
2139
+ box-shadow: var(--focus-ring, 0 0 0 8px var(--bg));
2055
2140
  border-radius: var(--radius-sm);
2056
2141
  }
2057
2142
  .nav-item:focus-visible,
@@ -451,8 +451,8 @@
451
451
  // A create with no discipline the server cannot infer from the wording is
452
452
  // refused (task 1002988), so the builder names the craft here. Engineer is
453
453
  // the default, the same fallback bug routing uses (ideas/inbox.js).
454
- var craftOptions = [['engineer', 'Engineer'], ['artist', 'Artist'], ['ideator', 'Ideator'], ['ui', 'UI']].map(function (c) {
455
- return '<option value="' + c[0] + '"' + (c[0] === 'engineer' ? ' selected' : '') + '>' + c[1] + '</option>';
454
+ var craftOptions = [['artisan', 'Artisan'], ['artist', 'Artist'], ['ui', 'UI']].map(function (c) {
455
+ return '<option value="' + c[0] + '"' + (c[0] === 'artisan' ? ' selected' : '') + '>' + c[1] + '</option>';
456
456
  }).join('');
457
457
  box.innerHTML =
458
458
  '<form class="td-form" data-form="promote">'
@@ -509,7 +509,7 @@
509
509
  title: title,
510
510
  description: body + provenance,
511
511
  priority: Number(form.priority.value) || 3,
512
- discipline: (form.discipline && form.discipline.value) || 'engineer',
512
+ discipline: (form.discipline && form.discipline.value) || 'artisan',
513
513
  source: 'idea_inbox',
514
514
  source_ref: 'idea:' + idea.id,
515
515
  };
@@ -750,7 +750,8 @@
750
750
  }
751
751
 
752
752
  window.addEventListener('keydown', function (e) {
753
- if (e.key === 'Escape' && document.getElementById('deeplink-card')) clearLink();
753
+ // Spent once it closed the card (ADR 0399 §2.4 row 5, task 1005144).
754
+ if (e.key === 'Escape' && document.getElementById('deeplink-card')) { e.preventDefault(); clearLink(); }
754
755
  });
755
756
  window.addEventListener('hashchange', resolve);
756
757
 
@@ -8,7 +8,7 @@
8
8
  <link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link rel="stylesheet" href="/builders/style.css?v=2026-07-03-roadmap1">
11
+ <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-helm">
12
12
  <!-- The record archetype (shared with idea.html) and this page's own two
13
13
  shapes. Promoted out of an inline <style> by task 1003305 — the block was
14
14
  the hall's last substantive one and sat at its hall_audit ratchet. -->
@@ -57,17 +57,17 @@
57
57
  <!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
58
58
  time so the chrome exists before the deferred page scripts execute. -->
59
59
  <script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
60
- <script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
60
+ <script src="/builders/shell-game.js?v=2026-11-11-helm"></script>
61
61
  <script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
62
- <script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
63
- <script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
62
+ <script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
63
+ <script src="/builders/shell.js?v=2026-11-11-helm"></script>
64
64
  <script src="/builders/hall-dialog.js"></script>
65
65
  <!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
66
66
  <script src="/builders/palette.js" defer></script>
67
67
  <!-- task-detail.js still owns the #/idea/N and #/blocker/N deep-link overlay
68
68
  (and the #/task/N → /task/N redirect, task 751); load it here too so those
69
69
  links still resolve from this page. -->
70
- <script src="/builders/task-detail.js?v=2026-07-03-taskdetail2" defer></script>
70
+ <script src="/builders/task-detail.js?v=2026-11-10-options" defer></script>
71
71
  <script src="/builders/brand-apply.js?v=2026-06-19-r56" defer></script>
72
72
  <script src="/builders/md-reader.js" defer></script>
73
73
  <script src="/builders/hall-visual.js?v=2026-09-16-visual1" defer></script>
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "_": "The hall's TASK RECORD through modules/ui-design/kit/render.js (task 1003305). The record's own controls — the dependency links, the lifecycle buttons, the figure band, the way back — only exist once a task has LOADED, so the floors here are run against the hall-preview harness rather than the kit's own stub, which carries the public-landing feeds and not the hall's:\n\n node scripts/hall-preview/server.js --port 4612 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/task.states.json --base-in http://builders.localhost:4612 --base-out http://builders.localhost:4612\n\nRun against the kit's own stubs instead and every state renders `no such task`, which is a real state and is the `missing` one below — just not the one the re-skin changed.",
3
3
  "page": "/task/2166",
4
+ "modes": ["dark"],
4
5
  "_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
5
6
  "storage": { "session": { "hall-craft-asked": "1" } },
6
7
  "surface": "hall-ui",
@@ -304,3 +304,13 @@ html[data-fullscreen="on"] .sky-stage .top { padding-right: 184px; }
304
304
  .card { max-width: 240px; }
305
305
  }
306
306
  @media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
307
+
308
+ /* task 1005148: with the visor up (html.visor-on, game mode; visor.js), the sky's own layers keep
309
+ clear of the glass, as ADR 0399 §2.3 asks of a scene's pop-ups: the top row, the composer, the
310
+ jump field and the two side panels step below the compass and the place line, and the foot and
311
+ the tour rise above the visor's corner pills. Outside game mode nothing here applies. */
312
+ html.visor-on .top { padding-top: calc(60px + env(safe-area-inset-top, 0px)); }
313
+ html.visor-on .composer, html.visor-on .jump { top: calc(116px + env(safe-area-inset-top, 0px)); }
314
+ html.visor-on .panel, html.visor-on .room { top: calc(180px + env(safe-area-inset-top, 0px)); bottom: calc(200px + env(safe-area-inset-bottom, 0px)); }
315
+ html.visor-on .foot { padding-bottom: calc(132px + env(safe-area-inset-bottom, 0px)); }
316
+ html.visor-on .tour, html.visor-on .start { bottom: calc(210px + env(safe-area-inset-bottom, 0px)); }
@@ -12,8 +12,9 @@
12
12
  links, injected into this head by the server like every hall page's
13
13
  (tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet).
14
14
  The template carried its own Google Fonts link for the same two faces. -->
15
- <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
16
- <link rel="stylesheet" href="/builders/thinking.css?v=2026-09-27-split">
15
+ <link rel="stylesheet" href="/builders/style.css?v=2026-11-11-helm">
16
+ <link rel="stylesheet" href="/builders/visor.css?v=2026-11-10-visor">
17
+ <link rel="stylesheet" href="/builders/thinking.css?v=2026-11-10-visor">
17
18
  </head>
18
19
  <!-- THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331, ADR 0227
19
20
  §11). This page is docs/design/mocks/sky/sky.template.html — the prototype
@@ -139,11 +140,13 @@
139
140
  </div>
140
141
 
141
142
  <script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
142
- <script src="/builders/shell-game.js?v=2026-11-09-game-mode"></script>
143
+ <script src="/builders/shell-game.js?v=2026-11-11-helm"></script>
143
144
  <script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
144
- <script src="/builders/craft-mode.js?v=2026-11-05-goals"></script>
145
- <script src="/builders/shell.js?v=2026-11-09-game-mode"></script>
145
+ <script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
146
+ <script src="/builders/shell.js?v=2026-11-11-helm"></script>
146
147
  <script src="/builders/hall-dialog.js"></script>
148
+ <!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
149
+ <script src="/builders/visor.js?v=2026-11-10-visor"></script>
147
150
  <script src="/builders/palette.js" defer></script>
148
151
 
149
152
  <script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
@@ -152,7 +155,7 @@
152
155
  <script src="/builders/sky-data.js?v=2026-09-30-uat1"></script>
153
156
  <script src="/builders/sky-layout.js?v=2026-09-27-split"></script>
154
157
  <script src="/builders/sky-draw.js?v=2026-09-27-split"></script>
155
- <script src="/builders/sky-interaction.js?v=2026-09-30-uat1"></script>
158
+ <script src="/builders/sky-interaction.js?v=2026-11-10-visor"></script>
156
159
  <script src="/builders/sky-panel.js?v=2026-09-30-uat1"></script>
157
160
  <script src="/builders/sky-composer.js?v=2026-09-27-split"></script>
158
161
  <script src="/builders/sky-tour.js?v=2026-09-27-split"></script>
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "_": "THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331) through modules/ui-design/kit/render.js. The page draws GET /sky + GET /sky/mine; against the kit's own stub neither exists, so every state below renders the EMPTY sky — a real state the floors must hold in (the composer, the tour, the list drawer and the lenses all exist with no thought filed). To look at the populated sky, run it against the hall-preview harness, whose sky.json + sky__mine.json fixtures carry the wells and one of each of the five objects:\n\n node scripts/hall-preview/server.js --port 4615 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/thinking.states.json --base-in http://localhost:4615 --base-out http://localhost:4615\n\nThe tour opens by itself on a first visit (sky-tour-seen), so states that want the bare sky skip it first.\n\nIN THE HALL (task 1004327): the page sits in the hall chrome, so it renders in BOTH modes — the chrome follows the hall theme and the sky's stage stays the void in both. The full-* states press the shell's full-screen switch: the sidebar and the top bar leave, and the one button that brings them back floats top right.",
3
3
  "page": "/builders/thinking",
4
+ "modes": ["dark"],
4
5
  "_storage": "The hall asks a first-visit question (the session mode picker, craft-mode.js) over every page; seeding \"already asked\" renders the page a returning builder sees (task 1005080).",
5
6
  "storage": { "session": { "hall-craft-asked": "1" } },
6
7
  "surface": "hall-ui",