pmx-canvas 0.8.2 → 0.9.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 (335) hide show
  1. package/.github/extensions/pmx-canvas/runtime.json +1 -1
  2. package/.github/extensions/pmx-canvas/tools.json +601 -22
  3. package/CHANGELOG.md +49 -0
  4. package/Readme.md +131 -532
  5. package/dist/canvas/global.css +2724 -476
  6. package/dist/canvas/index.js +168 -107
  7. package/dist/canvas/mcp-app.html +2899 -596
  8. package/dist/json-render/index.js +20 -20
  9. package/dist/types/client/canvas/BarHint.d.ts +12 -2
  10. package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -1
  11. package/dist/types/client/canvas/BoardPinButton.d.ts +10 -0
  12. package/dist/types/client/canvas/BoardSwitcher.d.ts +1 -1
  13. package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
  14. package/dist/types/client/canvas/CommandBar.d.ts +3 -4
  15. package/dist/types/client/canvas/ConnectionBanner.d.ts +2 -1
  16. package/dist/types/client/canvas/ContextChip.d.ts +3 -0
  17. package/dist/types/client/canvas/CrossBoardReferences.d.ts +5 -0
  18. package/dist/types/client/canvas/EdgeLayer.d.ts +14 -3
  19. package/dist/types/client/canvas/EmptyState.d.ts +4 -4
  20. package/dist/types/client/canvas/HomeGraphView.d.ts +2 -0
  21. package/dist/types/client/canvas/HomeMapView.d.ts +1 -0
  22. package/dist/types/client/canvas/HomeReviewView.d.ts +6 -0
  23. package/dist/types/client/canvas/HomeView.d.ts +9 -7
  24. package/dist/types/client/canvas/KnowledgeDialog.d.ts +4 -0
  25. package/dist/types/client/canvas/LifecycleChrome.d.ts +5 -0
  26. package/dist/types/client/canvas/LifecycleFields.d.ts +7 -0
  27. package/dist/types/client/canvas/LifecyclePanel.d.ts +1 -0
  28. package/dist/types/client/canvas/MemoryInspector.d.ts +7 -0
  29. package/dist/types/client/canvas/NearPinLayer.d.ts +14 -0
  30. package/dist/types/client/canvas/NodeContextMark.d.ts +40 -7
  31. package/dist/types/client/canvas/RelationPresetsDialog.d.ts +4 -0
  32. package/dist/types/client/canvas/RelationsPanel.d.ts +4 -0
  33. package/dist/types/client/canvas/SessionPanel.d.ts +2 -0
  34. package/dist/types/client/canvas/canvas-area.d.ts +1 -1
  35. package/dist/types/client/canvas/graph-geometry.d.ts +27 -0
  36. package/dist/types/client/canvas/graph-model.d.ts +37 -0
  37. package/dist/types/client/canvas/memory-layout.d.ts +23 -0
  38. package/dist/types/client/canvas/use-chrome-height.d.ts +2 -0
  39. package/dist/types/client/canvas/use-focus-trap.d.ts +1 -0
  40. package/dist/types/client/canvas/use-memory-graph.d.ts +8 -0
  41. package/dist/types/client/canvas/use-pan-zoom.d.ts +4 -1
  42. package/dist/types/client/icons.d.ts +0 -10
  43. package/dist/types/client/nodes/AxStepControls.d.ts +1 -1
  44. package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +4 -4
  45. package/dist/types/client/nodes/MarkdownNode.d.ts +5 -1
  46. package/dist/types/client/nodes/McpAppNode.d.ts +4 -4
  47. package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -1
  48. package/dist/types/client/state/boards-store.d.ts +81 -9
  49. package/dist/types/client/state/canvas-store.d.ts +14 -1
  50. package/dist/types/client/state/context-chip-store.d.ts +22 -0
  51. package/dist/types/client/state/context-status-store.d.ts +35 -0
  52. package/dist/types/client/state/intent-bridge.d.ts +11 -8
  53. package/dist/types/client/state/knowledge-store.d.ts +22 -0
  54. package/dist/types/client/state/near-pin-store.d.ts +44 -1
  55. package/dist/types/client/state/presence-store.d.ts +4 -4
  56. package/dist/types/client/state/presentation.d.ts +28 -0
  57. package/dist/types/client/state/relation-store.d.ts +10 -0
  58. package/dist/types/client/state/session-store.d.ts +41 -2
  59. package/dist/types/client/state/workspace-settings.d.ts +7 -0
  60. package/dist/types/client/types.d.ts +13 -1
  61. package/dist/types/client/utils/keyboard.d.ts +2 -0
  62. package/dist/types/client/utils/time-ago.d.ts +4 -0
  63. package/dist/types/mcp/context-uri-template.d.ts +3 -1
  64. package/dist/types/server/agent-presence.d.ts +10 -3
  65. package/dist/types/server/ax-context.d.ts +1 -1
  66. package/dist/types/server/canvas-db.d.ts +30 -7
  67. package/dist/types/server/canvas-operations.d.ts +24 -2
  68. package/dist/types/server/canvas-provenance.d.ts +22 -2
  69. package/dist/types/server/canvas-serialization.d.ts +2 -0
  70. package/dist/types/server/canvas-state.d.ts +93 -15
  71. package/dist/types/server/canvas-validation.d.ts +1 -1
  72. package/dist/types/server/context-brief.d.ts +94 -6
  73. package/dist/types/server/context-reads.d.ts +33 -7
  74. package/dist/types/server/edit-summary.d.ts +20 -0
  75. package/dist/types/server/index.d.ts +71 -10
  76. package/dist/types/server/knowledge-lifecycle.d.ts +221 -0
  77. package/dist/types/server/lifecycle-status.d.ts +10 -0
  78. package/dist/types/server/memory-graph.d.ts +9 -0
  79. package/dist/types/server/mutation-history.d.ts +2 -0
  80. package/dist/types/server/operations/ops/ax-shared.d.ts +1 -1
  81. package/dist/types/server/operations/ops/boards.d.ts +2 -1
  82. package/dist/types/server/operations/ops/lifecycle.d.ts +2 -0
  83. package/dist/types/server/operations/ops/memory-graph.d.ts +2 -0
  84. package/dist/types/server/operations/ops/nodes.d.ts +5 -0
  85. package/dist/types/server/operations/ops/query.d.ts +23 -0
  86. package/dist/types/server/operations/registry.d.ts +1 -0
  87. package/dist/types/server/placement.d.ts +7 -0
  88. package/dist/types/server/scope-fence.d.ts +2 -1
  89. package/dist/types/server/spatial-analysis.d.ts +6 -3
  90. package/dist/types/server/tour-control.d.ts +32 -0
  91. package/dist/types/server/wiki-links.d.ts +14 -0
  92. package/dist/types/server/workbench-auth.d.ts +2 -0
  93. package/dist/types/shared/agent-context.d.ts +2 -0
  94. package/dist/types/shared/agent-presence.d.ts +15 -12
  95. package/dist/types/shared/auto-arrange.d.ts +1 -0
  96. package/dist/types/shared/boards.d.ts +4 -4
  97. package/dist/types/shared/knowledge-lifecycle.d.ts +41 -0
  98. package/dist/types/shared/knowledge-presets.d.ts +6 -0
  99. package/dist/types/shared/lifecycle-status.d.ts +24 -0
  100. package/dist/types/shared/memory-graph.d.ts +53 -0
  101. package/dist/types/shared/relations.d.ts +68 -0
  102. package/dist/types/shared/semantic-attention.d.ts +2 -0
  103. package/dist/types/shared/tour.d.ts +38 -0
  104. package/dist/types/shared/workspace-settings.d.ts +11 -0
  105. package/docs/RELEASE.md +21 -3
  106. package/docs/adr-001-bun-only-runtime.md +7 -1
  107. package/docs/adr-002-shared-product-separate-runtimes.md +93 -0
  108. package/docs/api-reference.md +109 -0
  109. package/docs/ax-host-adapter-contract.md +1 -1
  110. package/docs/ax-state-contract.md +5 -4
  111. package/docs/cli.md +153 -15
  112. package/docs/demos/pmx-canvas-demo.mp4 +0 -0
  113. package/docs/design/AgentContext.dc.html +3 -3
  114. package/docs/design/BoardPins.dc.html +37 -22
  115. package/docs/design/Categories.dc.html +208 -0
  116. package/docs/design/CategoryEditor.dc.html +33 -0
  117. package/docs/design/Chrome.dc.html +52 -9
  118. package/docs/design/ContextChip.dc.html +224 -0
  119. package/docs/design/ContextChip600.dc.html +136 -0
  120. package/docs/design/EmptyState.dc.html +45 -0
  121. package/docs/design/Flows.dc.html +23 -1
  122. package/docs/design/HeaderMarks.dc.html +183 -0
  123. package/docs/design/Home.dc.html +19 -1
  124. package/docs/design/HomeGraph.dc.html +86 -202
  125. package/docs/design/HomeMap.dc.html +23 -1
  126. package/docs/design/HomeTeam.dc.html +32 -14
  127. package/docs/design/Lifecycle.dc.html +22 -0
  128. package/docs/design/Lifecycle600.dc.html +18 -0
  129. package/docs/design/LifecycleVariants.dc.html +157 -0
  130. package/docs/design/LinkAuthorship.dc.html +139 -0
  131. package/docs/design/LinksChanged.dc.html +203 -0
  132. package/docs/design/LinksOptions.dc.html +137 -0
  133. package/docs/design/LinksOptions600.dc.html +134 -0
  134. package/docs/design/NearPin.dc.html +9 -10
  135. package/docs/design/Pane600.dc.html +4 -3
  136. package/docs/design/Relations.dc.html +3 -2
  137. package/docs/design/Restore.dc.html +152 -0
  138. package/docs/design/SeeChange.dc.html +267 -0
  139. package/docs/design/Uses.dc.html +12 -6
  140. package/docs/design/canvas.json +146 -19
  141. package/docs/design.md +449 -16
  142. package/docs/environment.md +0 -1
  143. package/docs/evals/curation-effect.md +128 -0
  144. package/docs/http-api.md +459 -37
  145. package/docs/mcp.md +146 -18
  146. package/docs/node-types.md +58 -3
  147. package/docs/plans/design-gaps-2026-10-08.md +53 -0
  148. package/docs/plans/plan-009-tech-debt-backlog.md +379 -0
  149. package/docs/plans/plan-016-context-made-visible-wave-1.md +150 -5
  150. package/docs/plans/plan-017-knowledge-categories-and-lifecycle.md +175 -0
  151. package/docs/plans/plan-018-connected-memory-wave-2.md +594 -0
  152. package/docs/plans/plan-019-post-0.9-roadmap.md +198 -0
  153. package/docs/product-context-vision-2026-09.md +17 -1
  154. package/docs/product-vision-2026-09.md +1082 -43
  155. package/docs/product-vision-review-2026-09.md +13 -1
  156. package/docs/screenshots/workbench-live-dark.png +0 -0
  157. package/docs/screenshots/workbench-live-light.png +0 -0
  158. package/docs/sdk.md +62 -2
  159. package/package.json +1 -1
  160. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
  161. package/plugins/pmx-canvas/plugin.json +1 -1
  162. package/plugins/pmx-canvas/runtime.json +1 -1
  163. package/plugins/pmx-canvas/tools.json +601 -22
  164. package/skills/pmx-canvas/SKILL.md +216 -42
  165. package/skills/pmx-canvas/references/full-reference.md +120 -21
  166. package/skills/pmx-canvas/references/github-copilot-app-adapter.md +2 -2
  167. package/skills/pmx-canvas/references/importing-context.md +132 -0
  168. package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
  169. package/skills/pmx-canvas/references/tours-and-recording.md +16 -1
  170. package/skills/pmx-canvas-testing/SKILL.md +20 -0
  171. package/src/cli/agent.ts +2 -0
  172. package/src/cli/commands/ax.ts +12 -0
  173. package/src/cli/commands/boards.ts +87 -11
  174. package/src/cli/commands/edges.ts +28 -0
  175. package/src/cli/commands/groups.ts +7 -0
  176. package/src/cli/commands/nodes.ts +1 -0
  177. package/src/cli/commands/query.ts +34 -2
  178. package/src/cli/commands/record.ts +199 -48
  179. package/src/cli/index.ts +6 -1
  180. package/src/client/App.tsx +177 -70
  181. package/src/client/canvas/AttentionHistory.tsx +0 -2
  182. package/src/client/canvas/BarHint.tsx +40 -2
  183. package/src/client/canvas/BoardCopyDialog.tsx +1 -1
  184. package/src/client/canvas/BoardFolderDialog.tsx +7 -7
  185. package/src/client/canvas/BoardLinkDialog.tsx +138 -33
  186. package/src/client/canvas/BoardPinButton.tsx +33 -0
  187. package/src/client/canvas/BoardSwitcher.tsx +26 -40
  188. package/src/client/canvas/CanvasNode.tsx +360 -237
  189. package/src/client/canvas/CanvasViewport.tsx +45 -7
  190. package/src/client/canvas/CommandBar.tsx +29 -23
  191. package/src/client/canvas/CommandPalette.tsx +5 -12
  192. package/src/client/canvas/ConnectionBanner.tsx +3 -3
  193. package/src/client/canvas/ContextChip.tsx +296 -0
  194. package/src/client/canvas/ContextMenu.tsx +63 -5
  195. package/src/client/canvas/CrossBoardReferences.tsx +60 -0
  196. package/src/client/canvas/EdgeLayer.tsx +339 -76
  197. package/src/client/canvas/EmptyState.tsx +33 -18
  198. package/src/client/canvas/ExpandedNodeOverlay.tsx +72 -40
  199. package/src/client/canvas/ExternalWriters.tsx +57 -42
  200. package/src/client/canvas/HomeGraphView.tsx +942 -0
  201. package/src/client/canvas/HomeMapView.tsx +641 -0
  202. package/src/client/canvas/HomeReviewView.tsx +167 -0
  203. package/src/client/canvas/HomeView.tsx +687 -160
  204. package/src/client/canvas/IntentLayer.tsx +19 -12
  205. package/src/client/canvas/KnowledgeDialog.tsx +488 -0
  206. package/src/client/canvas/LifecycleChrome.tsx +133 -0
  207. package/src/client/canvas/LifecycleFields.tsx +91 -0
  208. package/src/client/canvas/LifecyclePanel.tsx +533 -0
  209. package/src/client/canvas/MemoryInspector.tsx +104 -0
  210. package/src/client/canvas/Minimap.tsx +3 -3
  211. package/src/client/canvas/NearPinLayer.tsx +187 -0
  212. package/src/client/canvas/NodeContextMark.tsx +175 -97
  213. package/src/client/canvas/Presentation.tsx +23 -57
  214. package/src/client/canvas/RelationPresetsDialog.tsx +413 -0
  215. package/src/client/canvas/RelationsPanel.tsx +82 -0
  216. package/src/client/canvas/SelectionBar.tsx +3 -6
  217. package/src/client/canvas/SessionPanel.tsx +90 -50
  218. package/src/client/canvas/SessionReceipt.tsx +311 -39
  219. package/src/client/canvas/ShortcutOverlay.tsx +1 -1
  220. package/src/client/canvas/SnapshotPanel.tsx +27 -36
  221. package/src/client/canvas/ToolRail.tsx +367 -192
  222. package/src/client/canvas/TopBar.tsx +354 -124
  223. package/src/client/canvas/canvas-area.ts +10 -3
  224. package/src/client/canvas/graph-geometry.ts +195 -0
  225. package/src/client/canvas/graph-model.ts +254 -0
  226. package/src/client/canvas/memory-layout.ts +106 -0
  227. package/src/client/canvas/use-chrome-height.ts +20 -0
  228. package/src/client/canvas/use-focus-trap.ts +31 -5
  229. package/src/client/canvas/use-memory-graph.ts +58 -0
  230. package/src/client/canvas/use-node-drag.ts +2 -1
  231. package/src/client/canvas/use-pan-zoom.ts +64 -7
  232. package/src/client/icons.tsx +0 -63
  233. package/src/client/mcp-app/style.css +0 -6
  234. package/src/client/nodes/AxStepControls.tsx +74 -50
  235. package/src/client/nodes/BoardNode.tsx +5 -1
  236. package/src/client/nodes/ContextNode.tsx +18 -11
  237. package/src/client/nodes/ExtAppFrame.tsx +0 -1
  238. package/src/client/nodes/FileNode.tsx +46 -42
  239. package/src/client/nodes/HtmlNode.tsx +32 -0
  240. package/src/client/nodes/ImageNode.tsx +1 -1
  241. package/src/client/nodes/InlineFormatBar.tsx +6 -9
  242. package/src/client/nodes/InlineMarkdownEditor.tsx +56 -17
  243. package/src/client/nodes/MarkdownNode.tsx +377 -109
  244. package/src/client/nodes/McpAppNode.tsx +50 -20
  245. package/src/client/nodes/MdFormatBar.tsx +21 -18
  246. package/src/client/nodes/PromptNode.tsx +1 -1
  247. package/src/client/nodes/ResponseNode.tsx +1 -1
  248. package/src/client/nodes/viewer-runtime-state.ts +54 -22
  249. package/src/client/state/attention-bridge.ts +64 -15
  250. package/src/client/state/boards-store.ts +193 -39
  251. package/src/client/state/canvas-store.ts +99 -12
  252. package/src/client/state/context-chip-store.ts +70 -0
  253. package/src/client/state/context-status-store.ts +53 -0
  254. package/src/client/state/intent-bridge.ts +51 -30
  255. package/src/client/state/knowledge-store.ts +43 -0
  256. package/src/client/state/near-pin-store.ts +115 -6
  257. package/src/client/state/presence-store.ts +7 -10
  258. package/src/client/state/presentation.ts +91 -0
  259. package/src/client/state/relation-store.ts +81 -0
  260. package/src/client/state/session-store.ts +144 -18
  261. package/src/client/state/sse-bridge.ts +206 -29
  262. package/src/client/state/workspace-settings.ts +11 -0
  263. package/src/client/theme/global.css +2724 -476
  264. package/src/client/types.ts +12 -0
  265. package/src/client/utils/keyboard.ts +10 -0
  266. package/src/client/utils/time-ago.ts +14 -0
  267. package/src/json-render/renderer/index.tsx +31 -0
  268. package/src/mcp/canvas-app.ts +12 -2
  269. package/src/mcp/context-uri-template.ts +7 -4
  270. package/src/mcp/server.ts +63 -41
  271. package/src/mcp/workbench-app.ts +39 -6
  272. package/src/server/agent-presence.ts +128 -28
  273. package/src/server/ax-context.ts +27 -13
  274. package/src/server/board-export.ts +12 -1
  275. package/src/server/canvas-db.ts +331 -42
  276. package/src/server/canvas-operations.ts +195 -83
  277. package/src/server/canvas-provenance.ts +53 -22
  278. package/src/server/canvas-serialization.ts +2 -0
  279. package/src/server/canvas-state.ts +950 -122
  280. package/src/server/canvas-validation.ts +9 -2
  281. package/src/server/context-brief.ts +345 -38
  282. package/src/server/context-reads.ts +178 -30
  283. package/src/server/demo-state.json +355 -24
  284. package/src/server/edit-summary.ts +74 -0
  285. package/src/server/html-surface.ts +8 -1
  286. package/src/server/index.ts +181 -11
  287. package/src/server/knowledge-lifecycle.ts +304 -0
  288. package/src/server/lifecycle-status.ts +232 -0
  289. package/src/server/memory-graph.ts +166 -0
  290. package/src/server/mutation-history.ts +18 -6
  291. package/src/server/operations/composites.ts +32 -11
  292. package/src/server/operations/http.ts +7 -2
  293. package/src/server/operations/index.ts +4 -0
  294. package/src/server/operations/mcp.ts +26 -1
  295. package/src/server/operations/ops/ax-presence.ts +1 -1
  296. package/src/server/operations/ops/ax-read.ts +57 -6
  297. package/src/server/operations/ops/ax-timeline.ts +28 -2
  298. package/src/server/operations/ops/backup.ts +5 -3
  299. package/src/server/operations/ops/batch.ts +35 -4
  300. package/src/server/operations/ops/boards.ts +188 -47
  301. package/src/server/operations/ops/canvas-wire.ts +31 -1
  302. package/src/server/operations/ops/edges.ts +36 -2
  303. package/src/server/operations/ops/groups.ts +6 -1
  304. package/src/server/operations/ops/lifecycle.ts +262 -0
  305. package/src/server/operations/ops/memory-graph.ts +45 -0
  306. package/src/server/operations/ops/nodes.ts +107 -24
  307. package/src/server/operations/ops/query.ts +281 -68
  308. package/src/server/operations/ops/snapshots.ts +73 -1
  309. package/src/server/operations/ops/validate.ts +5 -1
  310. package/src/server/operations/ops/viewport.ts +97 -3
  311. package/src/server/operations/registry.ts +74 -25
  312. package/src/server/placement.ts +29 -0
  313. package/src/server/scope-fence.ts +78 -6
  314. package/src/server/server.ts +115 -16
  315. package/src/server/spatial-analysis.ts +48 -23
  316. package/src/server/tour-control.ts +82 -0
  317. package/src/server/wiki-links.ts +137 -0
  318. package/src/server/workbench-auth.ts +11 -0
  319. package/src/shared/agent-context.ts +3 -0
  320. package/src/shared/agent-presence.ts +15 -15
  321. package/src/shared/auto-arrange.ts +2 -0
  322. package/src/shared/boards.ts +4 -4
  323. package/src/shared/knowledge-lifecycle.ts +22 -0
  324. package/src/shared/knowledge-presets.ts +80 -0
  325. package/src/shared/lifecycle-status.ts +26 -0
  326. package/src/shared/memory-graph.ts +74 -0
  327. package/src/shared/relations.ts +98 -0
  328. package/src/shared/semantic-attention.ts +15 -1
  329. package/src/shared/tour.ts +23 -5
  330. package/src/shared/workspace-settings.ts +13 -0
  331. package/dist/types/client/canvas/ContextPinBar.d.ts +0 -1
  332. package/dist/types/client/canvas/FocusFieldLayer.d.ts +0 -1
  333. package/dist/types/client/canvas/kind-colors.d.ts +0 -3
  334. package/dist/types/server/agent-context.d.ts +0 -22
  335. package/src/client/canvas/ContextPinBar.tsx +0 -25
@@ -17,7 +17,7 @@ body{margin:0}
17
17
 
18
18
  <div>
19
19
  <h1 style="margin: 0; font-size: 28px; font-weight: 600; letter-spacing: -0.015em">Board pins — a working set across boards</h1>
20
- <p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">One gesture at two levels. Pin a card and its content goes to the agent. Pin a board and the whole board joins the agent's working set, wherever it sits in the library.</p>
20
+ <p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">One gesture at two levels. Pin a card and it goes first in the agent's map — title, summary and relations; the agent pulls its full text when it needs it. Pin a board and the board joins the agent's working set as a map, wherever it sits in the library — with its review state: what is due, and what has no lifecycle.</p>
21
21
  </div>
22
22
 
23
23
  <div style="display: grid; grid-template-columns: 600px minmax(0, 1fr); gap: 40px">
@@ -28,8 +28,8 @@ body{margin:0}
28
28
  <div style="{{s.card}}">
29
29
  <span style="{{s.cap}}">Home — board cards</span>
30
30
  <div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px">
31
- <div style="border-radius: 10px; border: 1.5px solid #4BBCFF; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOn}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">C4 2026 OKR planning</div><div style="font-size: 11px; color: #8ea3bd">in context · 34 cards</div></div></div>
32
- <div style="border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOff}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">Platform roadmap 2027</div><div style="font-size: 11px; color: #8ea3bd">click the pin to add · 26 cards</div></div></div>
31
+ <div style="border-radius: 10px; border: 1.5px solid #4BBCFF; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOn}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">C4 2026 OKR planning</div><div style="display: flex; align-items: center; gap: 6px; font-size: 11px; color: #8ea3bd"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.icCat}}"><path d="{{i.strategy}}"></path></svg><span style="flex: 1">Strategy · in context · 34 cards</span><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.icChip}}"><path d="{{i.glass}}"></path></svg>3 due</span></div></div></div>
32
+ <div style="border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOff}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">Platform roadmap 2027</div><div style="display: flex; align-items: center; gap: 6px; font-size: 11px; color: #8ea3bd"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.icCat}}"><path d="{{i.strategy}}"></path></svg>Strategy · click the pin to add · 26 cards</div></div></div>
33
33
  </div>
34
34
  </div>
35
35
 
@@ -37,7 +37,7 @@ body{margin:0}
37
37
  <div style="{{s.card}}">
38
38
  <span style="{{s.cap}}">Board switcher</span>
39
39
  <sc-for list="{{switcher}}" as="b" hint-placeholder-count="4">
40
- <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; border-radius: 6px; background: {{b.bg}}"><span style="width: 8px; height: 8px; border-radius: 3px; background: {{b.hue}}"></span><span style="flex: 1; font-size: 12px; font-weight: 500">{{b.name}}</span><span style="{{b.pinStyle}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div>
40
+ <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; border-radius: 6px; background: {{b.bg}}"><svg width="12" height="12" viewBox="0 0 24 24" style="{{s.icCat}}"><path d="{{b.icon}}"></path></svg><span style="flex: 1; min-width: 0; font-size: 12px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">{{b.name}}</span><sc-if value="{{b.hasDue}}" hint-placeholder-val="{{ false }}"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.icChip}}"><path d="{{i.glass}}"></path></svg>{{b.due}}</span></sc-if><span style="{{b.pinStyle}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div>
41
41
  </sc-for>
42
42
  </div>
43
43
  <div style="{{s.card}}">
@@ -70,11 +70,12 @@ body{margin:0}
70
70
  <div style="display: flex; align-items: baseline; gap: 10px"><span style="width: 22px; height: 22px; border-radius: 999px; background: {{t.numBg}}; color: {{t.numC}}; font-size: 12px; font-weight: 600; text-align: center; line-height: 22px; flex-shrink: 0">{{t.n}}</span><span style="font-size: 15px; font-weight: 600; flex: 1">{{t.title}}</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd">{{t.tokens}}</span></div>
71
71
  <span style="font-size: 12px; color: #8ea3bd">{{t.what}}</span>
72
72
  <sc-for list="{{t.rows}}" as="r" hint-placeholder-count="2">
73
- <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border-radius: 6px; background: #13243b; font-size: 12px"><span style="{{r.mark}}">{{r.markText}}</span><span style="flex: 1; font-weight: 500">{{r.name}}</span><span style="font-size: 11px; color: #8ea3bd">{{r.detail}}</span></div>
73
+ <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border-radius: 6px; background: #13243b; font-size: 12px"><span style="{{r.mark}}">{{r.markText}}</span><span style="flex: 1; font-weight: 500">{{r.name}}</span><span style="font-size: 11px; color: #8ea3bd">{{r.detail}}</span><sc-if value="{{r.hasDue}}" hint-placeholder-val="{{ false }}"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.icChip}}"><path d="{{i.glass}}"></path></svg>{{r.due}}</span></sc-if></div>
74
74
  </sc-for>
75
75
  </div>
76
76
  </sc-for>
77
- <div style="display: flex; align-items: center; gap: 12px; font-size: 12px; color: #8ea3bd"><span style="width: 200px; height: 6px; border-radius: 999px; background: #1b2c44; overflow: hidden; display: block"><span style="display: block; width: 77%; height: 6px; background: #f4c542"></span></span><span style="font-family: 'IBM Plex Mono', monospace; color: #e6eef7; white-space: nowrap">24.5k / 32k</span><span>Over budget, a pinned board falls back to discovery — said on the chip, never silent.</span></div>
77
+ <div style="display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 8px; border: 1px solid rgba(244,197,66,0.3); font-size: 12px; color: #b9c6d6"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.icChip}}"><path d="{{i.glass}}"></path></svg>review due</span><span>Review state travels with a pinned board. Its due cards arrive marked “review due” with when they were last validated, cards with no category as “lifecycle unknown” — the same lines the brief uses on the open board (Lifecycle).</span></div>
78
+ <div style="display: flex; align-items: center; gap: 12px; font-size: 12px; color: #8ea3bd"><span style="font-family: 'IBM Plex Mono', monospace; color: #e6eef7; white-space: nowrap">≈ 2.1k tokens</span><span>What the canvas sends the agent costs ≈ 2.1k tokens — a cost, not a budget. Maps keep pinned boards cheap.</span></div>
78
79
  </section>
79
80
 
80
81
  </div>
@@ -83,10 +84,10 @@ body{margin:0}
83
84
  <span style="{{s.label}}">On any board — the context chip, opened</span>
84
85
  <div style="display: flex; gap: 24px; align-items: flex-start">
85
86
  <div style="width: 420px; box-sizing: border-box; padding: 12px; border-radius: 12px; border: 1px solid #2a4566; background: #13243b; box-shadow: 0 10px 30px rgba(0,0,0,0.55); display: flex; flex-direction: column; gap: 8px">
86
- <div style="display: flex; align-items: center; justify-content: space-between"><span style="font-size: 12px; font-weight: 600">In the agent's context</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd">24.5k tokens</span></div>
87
+ <div style="display: flex; align-items: center; justify-content: space-between"><span style="font-size: 12px; font-weight: 600">In the agent's context</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd">≈ 2.1k tokens</span></div>
87
88
  <span style="{{s.cap}}">Boards · 3</span>
88
89
  <sc-for list="{{chipBoards}}" as="r" hint-placeholder-count="3">
89
- <div style="display: flex; align-items: center; gap: 8px; height: 28px; font-size: 12px"><span style="width: 8px; height: 8px; border-radius: 3px; background: {{r.hue}}"></span><span style="flex: 1">{{r.name}}</span><span style="{{r.readStyle}}">{{r.read}}</span><span style="color: #6b7d94">×</span></div>
90
+ <div style="display: flex; align-items: center; gap: 8px; height: 28px; font-size: 12px"><svg width="12" height="12" viewBox="0 0 24 24" style="{{s.icCat}}"><path d="{{r.icon}}"></path></svg><span style="flex: 1">{{r.name}}</span><sc-if value="{{r.hasDue}}" hint-placeholder-val="{{ false }}"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.icChip}}"><path d="{{i.glass}}"></path></svg>{{r.due}}</span></sc-if><span style="{{r.readStyle}}">{{r.read}}</span><span style="color: #6b7d94">×</span></div>
90
91
  </sc-for>
91
92
  <span style="{{s.cap}}">Cards on this board · 4</span>
92
93
  <div style="font-size: 12px; color: #b9c6d6">Raise Pro to $24? · Churn flat after last raise · SMB is price-sensitive · Competitor pricing</div>
@@ -104,7 +105,15 @@ body{margin:0}
104
105
  <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1100}}'>
105
106
  class Component extends DCLogic {
106
107
  renderVals() {
107
- var i = { pin: 'M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20' };
108
+ var i = {
109
+ pin: 'M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20',
110
+ strategy: 'M12 3a9 9 0 1 0 0 18a9 9 0 1 0 0-18M15.5 8.5l-2 5-5 2 2-5z',
111
+ decision: 'M6 3v18M6 7h10l3 3-3 3H6',
112
+ research: 'M10.5 4a6.5 6.5 0 1 0 0 13a6.5 6.5 0 1 0 0-13M15.5 15.5L20 20',
113
+ notes: 'M4 20l4.2-1L19 8.2 15.8 5 5 15.8z',
114
+ unknown: 'M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5v.7M12 16.8v.4',
115
+ glass: 'M7 3h10M7 21h10M8 3v3l4 6-4 6v3M16 3v3l-4 6 4 6v3',
116
+ };
108
117
  var pinOn = 'width:18px;height:18px;border-radius:999px;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:#4BBCFF;color:#081524;';
109
118
  var pinOff = 'width:18px;height:18px;box-sizing:border-box;border-radius:999px;display:flex;align-items:center;justify-content:center;flex-shrink:0;border:1.5px solid #6b7d94;color:#b9c6d6;';
110
119
  var s = {
@@ -112,31 +121,37 @@ class Component extends DCLogic {
112
121
  cap: 'font-size:11px;font-weight:500;color:#8ea3bd;',
113
122
  card: 'display:flex;flex-direction:column;gap:10px;padding:14px 16px;border-radius:10px;border:1px solid #1b2c44;background:#0b1828;',
114
123
  ic: 'fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;',
124
+ icCat: 'fill:none;stroke:#8ea3bd;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;',
125
+ icChip: 'fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;',
126
+ due: 'display:inline-flex;align-items:center;gap:3px;height:18px;box-sizing:border-box;padding:0 6px;border-radius:999px;border:1px solid rgba(244,197,66,0.6);color:#f4c542;font-size:11px;font-weight:500;flex-shrink:0;',
127
+ set: 'display:inline-flex;align-items:center;gap:4px;height:20px;box-sizing:border-box;padding:0 6px;border-radius:6px;border:1px solid #2a4566;color:#e6eef7;font-size:11px;flex-shrink:0;',
128
+ inh: 'display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 2px;color:#8ea3bd;font-size:11px;flex-shrink:0;',
129
+ unk: 'display:inline-flex;align-items:center;gap:4px;height:20px;box-sizing:border-box;padding:0 6px;border-radius:6px;border:1px dashed #3d5170;color:#8ea3bd;font-size:11px;flex-shrink:0;',
115
130
  pinOn: pinOn, pinOff: pinOff
116
131
  };
117
132
  var switcher = [
118
- { name: 'Pricing research', hue: '#7C9CFF', pinStyle: pinOn, bg: '#13243b' },
119
- { name: 'C4 2026 OKR planning', hue: '#5FCFC0', pinStyle: pinOn, bg: 'transparent' },
120
- { name: 'Tech Enabling — overview', hue: '#5FCFC0', pinStyle: pinOn, bg: 'transparent' },
121
- { name: 'Platform roadmap 2027', hue: '#5FCFC0', pinStyle: pinOff, bg: 'transparent' }
133
+ { name: 'Pricing research', icon: i.research, pinStyle: pinOn, bg: '#13243b' },
134
+ { name: 'C4 2026 OKR planning', icon: i.strategy, hasDue: true, due: '3 due', pinStyle: pinOn, bg: 'transparent' },
135
+ { name: 'Tech Enabling — overview', icon: i.notes, pinStyle: pinOn, bg: 'transparent' },
136
+ { name: 'Platform roadmap 2027', icon: i.strategy, pinStyle: pinOff, bg: 'transparent' }
122
137
  ];
123
138
  var mOn = 'font-size:11px;font-weight:600;padding:0 6px;border-radius:999px;background:rgba(75,188,255,0.14);color:#4BBCFF;';
124
139
  var mDisc = 'font-size:11px;font-weight:600;padding:0 6px;border-radius:999px;background:#1b2c44;color:#8ea3bd;';
125
140
  var tiers = [
126
- { n: '1', title: 'This board’s pinned cards', tokens: '9k', what: 'Full content, as today.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
127
- rows: [{ name: '4 cards on Pricing research', detail: 'full text', mark: mOn, markText: 'cards' }] },
128
- { n: '2', title: 'Pinned boards', tokens: '14k', what: 'Each board’s README and its pinned cards, in full. New.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
129
- rows: [{ name: 'Tech Enabling — overview', detail: 'README + 2 pinned · 6k', mark: mOn, markText: 'board' },
130
- { name: 'C4 2026 OKR planning', detail: 'README + 3 pinned · 8k', mark: mOn, markText: 'board' }] },
131
- { n: '3', title: 'Discovery', tokens: '1.5k', what: 'Linked and same-folder boards: README summary and pinned titles only — today’s behaviour.', border: '#1b2c44', numBg: '#1b2c44', numC: '#b9c6d6',
141
+ { n: '1', title: 'This board’s pinned cards', tokens: '1.2k', what: 'First in the map: title, summary and relations. The agent pulls full text itself.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
142
+ rows: [{ name: '4 cards on Pricing research', detail: 'title + summary', mark: mOn, markText: 'cards' }] },
143
+ { n: '2', title: 'Pinned boards', tokens: '0.6k', what: 'Each board as a map: folder, README summary, pinned cards’ titles and summaries, links and backlinks, each with its review state. New.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
144
+ rows: [{ name: 'Tech Enabling — overview', detail: 'map · 0.3k', mark: mOn, markText: 'board' },
145
+ { name: 'C4 2026 OKR planning', detail: 'map · 0.3k', mark: mOn, markText: 'board', hasDue: true, due: '1 due' }] },
146
+ { n: '3', title: 'Discovery', tokens: '0.3k', what: 'Linked and same-folder boards: README summary and pinned titles only — today’s behaviour.', border: '#1b2c44', numBg: '#1b2c44', numC: '#b9c6d6',
132
147
  rows: [{ name: 'Churn analysis · SMB interviews · Competitor teardown', detail: 'summaries', mark: mDisc, markText: 'linked' }] }
133
148
  ];
134
149
  var read = 'font-size:11px;font-weight:500;padding:0 6px;border-radius:999px;background:rgba(179,136,255,0.16);color:#B388FF;';
135
150
  var notRead = 'font-size:11px;font-weight:500;padding:0 6px;border-radius:999px;background:#1b2c44;color:#8ea3bd;';
136
151
  var chipBoards = [
137
- { name: 'Pricing research (this board)', hue: '#7C9CFF', read: 'read 2m ago', readStyle: read },
138
- { name: 'Tech Enabling — overview', hue: '#5FCFC0', read: 'read 2m ago', readStyle: read },
139
- { name: 'C4 2026 OKR planning', hue: '#5FCFC0', read: 'not read yet', readStyle: notRead }
152
+ { name: 'Pricing research (this board)', icon: i.research, read: 'read 2m ago', readStyle: read },
153
+ { name: 'Tech Enabling — overview', icon: i.notes, read: 'read 2m ago', readStyle: read },
154
+ { name: 'C4 2026 OKR planning', icon: i.strategy, hasDue: true, due: '3 due', read: 'not read yet', readStyle: notRead }
140
155
  ];
141
156
  var rules = [
142
157
  { t: 'Lasts until you unpin', d: 'Board pins belong to the workspace: they survive board switches and restarts. You or the agent can pin; the agent’s pins carry its violet dot.' },
@@ -0,0 +1,208 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Knowledge categories on folders</title>
6
+ <script src="./support.js"></script>
7
+ </head>
8
+ <body>
9
+ <x-dc>
10
+ <helmet>
11
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&amp;family=IBM+Plex+Sans:wght@400;500;600&amp;display=swap">
12
+ <style>
13
+ body{margin:0}
14
+ </style>
15
+ </helmet>
16
+ <div style="width: 1440px; height: 940px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: flex; flex-direction: column; gap: 20px">
17
+
18
+ <div>
19
+ <h1 style="margin: 0; font-size: 28px; font-weight: 600; letter-spacing: -0.015em">Knowledge categories live on folders</h1>
20
+ <p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">One hierarchy: folders. A category says what kind of knowledge a folder holds and brings its lifecycle defaults with it. It inherits down the tree, so a board filed under Decisions is a decision without anyone tagging it.</p>
21
+ </div>
22
+
23
+ <div style="flex: 1; display: grid; grid-template-columns: 380px 560px minmax(0, 1fr); gap: 24px; min-height: 0">
24
+
25
+ <section style="display: flex; flex-direction: column; gap: 10px; min-width: 0">
26
+ <span style="{{s.label}}">1 · Home library tree</span>
27
+ <div style="{{s.panel}} padding: 14px 10px; gap: 2px">
28
+ <div style="display: flex; align-items: center; gap: 8px; padding: 0 8px 10px">
29
+ <span style="font-size: 13px; font-weight: 600; flex: 1">Acme workspace</span>
30
+ <button style="{{s.ghostBtn}}"><svg width="12" height="12" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.list}}"></path></svg>Categories</button>
31
+ </div>
32
+ <sc-for list="{{tree}}" as="r" hint-placeholder-count="16">
33
+ <div style="{{r.row}}"><span style="{{r.ind}}"></span><svg width="13" height="13" viewBox="0 0 24 24" style="{{s.icDim}}"><path d="{{r.fold}}"></path></svg><span style="{{s.name}}">{{r.name}}</span><span style="{{r.tagSt}}"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{r.icon}}"></path></svg>{{r.tag}}</span><sc-if value="{{r.hasDue}}" hint-placeholder-val="{{ true }}"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.glass}}"></path></svg>{{r.due}}</span></sc-if></div>
34
+ </sc-for>
35
+ <div style="margin: 10px 8px 0; padding-top: 10px; border-top: 1px solid #1b2c44; font-size: 11px; color: #6b7d94">Started from the Org · team · personal template, then renamed. Any folder can be renamed, moved or deleted.</div>
36
+ </div>
37
+
38
+ <div style="{{s.panel}} padding: 12px 14px; gap: 8px">
39
+ <span style="font-size: 12px; font-weight: 600">How to read a row</span>
40
+ <sc-for list="{{legend}}" as="l" hint-placeholder-count="4">
41
+ <div style="display: grid; grid-template-columns: 112px 1fr; gap: 10px; align-items: center"><span style="{{l.st}}"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{l.icon}}"></path></svg>{{l.tag}}</span><span style="font-size: 11px; color: #b9c6d6">{{l.d}}</span></div>
42
+ </sc-for>
43
+ </div>
44
+ </section>
45
+
46
+ <section style="display: flex; flex-direction: column; gap: 10px; min-width: 0">
47
+ <span style="{{s.label}}">2 · Folder settings — Platform team / Metrics</span>
48
+ <div style="{{s.panel}} padding: 0; box-shadow: 0 10px 30px rgba(0,0,0,0.6)">
49
+ <div style="display: flex; align-items: center; gap: 10px; height: 48px; padding: 0 12px 0 16px; border-bottom: 1px solid #1b2c44">
50
+ <svg width="16" height="16" viewBox="0 0 24 24" style="{{s.icDim}}"><path d="{{i.folder}}"></path></svg>
51
+ <div style="flex: 1; min-width: 0"><div style="font-size: 15px; font-weight: 600; line-height: 20px">Metrics</div><div style="font-size: 11px; color: #6b7d94; line-height: 14px">Acme / Platform team / Metrics · 12 boards</div></div>
52
+ <button aria-label="Close" style="{{s.iconBtn}}"><svg width="14" height="14" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.x}}"></path></svg></button>
53
+ </div>
54
+
55
+ <div style="padding: 16px; display: flex; flex-direction: column; gap: 16px">
56
+ <div style="display: flex; flex-direction: column; gap: 8px">
57
+ <span style="font-size: 12px; font-weight: 600">Category</span>
58
+ <label style="{{s.radio}}"><span style="{{s.radioOff}}"></span><span style="flex: 1">Use the parent’s</span><span style="{{s.inh}}"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.research}}"></path></svg>↳ Research</span><span style="font-size: 11px; color: #6b7d94">from Platform team</span></label>
59
+ <label style="{{s.radioOn}}"><span style="{{s.radioDot}}"></span><span style="flex: 1">Set here</span>
60
+ <span style="{{s.select}}"><svg width="13" height="13" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.metric}}"></path></svg><span style="flex: 1">Metric</span><span style="color: #6b7d94">▾</span></span></label>
61
+ <span style="font-size: 11px; color: #8ea3bd; padding-left: 26px">Picks from the workspace’s one list. Subfolders and boards below inherit Metric unless they set their own.</span>
62
+ </div>
63
+
64
+ <div style="display: flex; flex-direction: column; gap: 8px">
65
+ <div style="display: flex; align-items: baseline; gap: 8px"><span style="font-size: 12px; font-weight: 600; flex: 1">Lifecycle defaults · from Metric</span><span style="font-size: 11px; color: #4BBCFF">Edit Metric in Categories →</span></div>
66
+ <div style="display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px; padding: 12px; border-radius: 8px; background: #13243b; font-size: 12px">
67
+ <span style="color: #8ea3bd">Decays when</span><span>Reality changes — the numbers move</span>
68
+ <span style="color: #8ea3bd">Check</span><span>Fast — at use, every time a brief carries it</span>
69
+ <span style="color: #8ea3bd">Also review when</span><span>its source refreshes · a card contradicts it</span>
70
+ <span style="color: #8ea3bd">Revalidate by</span><span>re-reading the source dashboard and comparing</span>
71
+ </div>
72
+ <span style="font-size: 11px; color: #8ea3bd">Rates are planning judgements, not odds that a claim is true.</span>
73
+ </div>
74
+
75
+ <div style="display: flex; flex-direction: column; gap: 6px">
76
+ <span style="font-size: 12px; font-weight: 600">What inherits it</span>
77
+ <div style="{{s.kv}}"><span style="flex: 1">Boards in this folder</span><span style="color: #b9c6d6">11 inherit Metric · 1 sets its own</span></div>
78
+ <div style="{{s.kv}}"><span style="flex: 1">OKR mirror</span><span style="{{s.set}}"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.strategy}}"></path></svg>Strategy</span><span style="font-size: 11px; color: #6b7d94">set on the board</span></div>
79
+ <div style="{{s.kv}}"><span style="flex: 1">Cards on these boards</span><span style="color: #b9c6d6">may change their lifecycle, never their category</span></div>
80
+ </div>
81
+
82
+ <div style="display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 8px; border: 1px dashed #1b2c44; color: #6b7d94; font-size: 12px"><svg width="13" height="13" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.lock}}"></path></svg><span style="flex: 1">Who can read and write</span><span style="font-size: 11px">later, with the team server · not part of the category</span></div>
83
+ </div>
84
+
85
+ <div style="display: flex; justify-content: flex-end; gap: 8px; padding: 12px 16px; border-top: 1px solid #1b2c44">
86
+ <button style="{{s.btn}}">Cancel</button><button style="{{s.btnPrimary}}">Save</button>
87
+ </div>
88
+ </div>
89
+ </section>
90
+
91
+ <section style="display: flex; flex-direction: column; gap: 10px; min-width: 0">
92
+ <span style="{{s.label}}">3 · Another workspace — solo research</span>
93
+ <div style="{{s.panel}} padding: 14px 10px; gap: 2px">
94
+ <div style="display: flex; align-items: center; gap: 8px; padding: 0 8px 10px">
95
+ <span style="font-size: 13px; font-weight: 600; flex: 1">Thesis notes</span>
96
+ <button style="{{s.ghostBtn}}"><svg width="12" height="12" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.list}}"></path></svg>Categories</button>
97
+ </div>
98
+ <sc-for list="{{solo}}" as="r" hint-placeholder-count="9">
99
+ <div style="{{r.row}}"><span style="{{r.ind}}"></span><svg width="13" height="13" viewBox="0 0 24 24" style="{{s.icDim}}"><path d="{{r.fold}}"></path></svg><span style="{{s.name}}">{{r.name}}</span><span style="{{r.tagSt}}"><svg width="11" height="11" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{r.icon}}"></path></svg>{{r.tag}}</span><sc-if value="{{r.hasDue}}" hint-placeholder-val="{{ true }}"><span style="{{s.due}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.glass}}"></path></svg>{{r.due}}</span></sc-if></div>
100
+ </sc-for>
101
+ <div style="margin: 10px 8px 0; padding-top: 10px; border-top: 1px solid #1b2c44; font-size: 11px; color: #6b7d94">No template. One person started empty and defined four categories of their own: Question, Source, Finding, Note. Nothing here says org, team or personal.</div>
102
+ </div>
103
+
104
+ <sc-for list="{{rules}}" as="r" hint-placeholder-count="4">
105
+ <div style="{{s.panel}} padding: 12px 14px; gap: 2px"><span style="font-size: 12px; font-weight: 600">{{r.t}}</span><span style="font-size: 11px; color: #b9c6d6">{{r.d}}</span></div>
106
+ </sc-for>
107
+ </section>
108
+
109
+ </div>
110
+ </div>
111
+ </x-dc>
112
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":940}}'>
113
+ class Component extends DCLogic {
114
+ renderVals() {
115
+ var i = {
116
+ folder: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z',
117
+ open: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v1H7l-4 9zM7 10h15l-3 9H3',
118
+ strategy: 'M12 3a9 9 0 1 0 0 18a9 9 0 1 0 0-18M15.5 8.5l-2 5-5 2 2-5z',
119
+ decision: 'M6 3v18M6 7h10l3 3-3 3H6',
120
+ research: 'M10.5 4a6.5 6.5 0 1 0 0 13a6.5 6.5 0 1 0 0-13M15.5 15.5L20 20',
121
+ metric: 'M4 20V11M10 20V5M16 20v-6M3 20h18',
122
+ policy: 'M12 3l7 3v5c0 5-3.5 8-7 10-3.5-2-7-5-7-10V6z',
123
+ notes: 'M4 20l4.2-1L19 8.2 15.8 5 5 15.8z',
124
+ question: 'M12 3a9 9 0 1 0 0 18a9 9 0 1 0 0-18M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5v.7M12 16.8v.4',
125
+ source: 'M5 5a2 2 0 0 1 2-2h12v15H7a2 2 0 0 0-2 2zM5 20a2 2 0 0 0 2 1h12v-3',
126
+ finding: 'M9 18h6M10 21h4M12 3a6 6 0 0 0-3.5 10.9c.4.3.5.7.5 1.1v1h6v-1c0-.4.1-.8.5-1.1A6 6 0 0 0 12 3',
127
+ unknown: 'M9.5 9.5a2.5 2.5 0 1 1 3.5 2.3c-.6.3-1 .8-1 1.5v.7M12 16.8v.4',
128
+ glass: 'M7 3h10M7 21h10M8 3v3l4 6-4 6v3M16 3v3l-4 6 4 6v3',
129
+ list: 'M8 6h12M8 12h12M8 18h12M4 6h.5M4 12h.5M4 18h.5',
130
+ lock: 'M6 11h12v9H6zM8.5 11V8a3.5 3.5 0 0 1 7 0v3',
131
+ x: 'M6 6l12 12M18 6L6 18'
132
+ };
133
+ var s = {
134
+ label: 'font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:#6b7d94;',
135
+ panel: 'display:flex;flex-direction:column;border-radius:10px;border:1px solid #1b2c44;background:#0f1d31;',
136
+ ic: 'fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;',
137
+ icDim: 'fill:none;stroke:#6b7d94;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;',
138
+ name: 'flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:13px;',
139
+ due: 'display:inline-flex;align-items:center;gap:3px;height:18px;padding:0 6px;border-radius:999px;border:1px solid rgba(244,197,66,0.6);color:#f4c542;font-size:11px;flex-shrink:0;',
140
+ set: 'display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 6px;border-radius:6px;border:1px solid #2a4566;color:#e6eef7;font-size:11px;flex-shrink:0;',
141
+ inh: 'display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 2px;color:#8ea3bd;font-size:11px;flex-shrink:0;',
142
+ ghostBtn: 'display:flex;align-items:center;gap:6px;height:26px;padding:0 9px;border-radius:6px;border:1px solid #1b2c44;background:transparent;color:#b9c6d6;font-family:inherit;font-size:12px;',
143
+ iconBtn: 'width:28px;height:28px;border:0;border-radius:6px;background:transparent;color:#8ea3bd;display:flex;align-items:center;justify-content:center;',
144
+ radio: 'display:flex;align-items:center;gap:10px;height:40px;padding:0 12px;border-radius:8px;border:1px solid #1b2c44;font-size:13px;',
145
+ radioOn: 'display:flex;align-items:center;gap:10px;height:44px;padding:0 6px 0 12px;border-radius:8px;border:1px solid #2a4566;background:#13243b;font-size:13px;',
146
+ radioOff: 'width:14px;height:14px;box-sizing:border-box;border-radius:999px;border:1.5px solid #6b7d94;flex-shrink:0;',
147
+ radioDot: 'width:14px;height:14px;box-sizing:border-box;border-radius:999px;border:4px solid #e6eef7;flex-shrink:0;',
148
+ select: 'display:flex;align-items:center;gap:8px;width:190px;height:32px;box-sizing:border-box;padding:0 10px;border-radius:6px;border:1px solid #2a4566;background:#0f1d31;font-size:13px;',
149
+ kv: 'display:flex;align-items:center;gap:8px;min-height:30px;padding:0 10px;border-radius:6px;background:#13243b;font-size:12px;',
150
+ btn: 'height:30px;padding:0 14px;border-radius:6px;border:1px solid #1b2c44;background:transparent;color:#e6eef7;font-family:inherit;font-size:12px;',
151
+ btnPrimary: 'height:30px;padding:0 14px;border-radius:6px;border:0;background:#4BBCFF;color:#081524;font-family:inherit;font-size:12px;font-weight:600;'
152
+ };
153
+ var unk = 'display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 6px;border-radius:6px;border:1px dashed #3d5170;color:#8ea3bd;font-size:11px;flex-shrink:0;';
154
+ var cats = { strategy: 'Strategy', decision: 'Decision', research: 'Research', metric: 'Metric', policy: 'Policy', notes: 'Notes', question: 'Question', source: 'Source', finding: 'Finding' };
155
+ function row(name, depth, cat, mode, due, opts) {
156
+ opts = opts || {};
157
+ var tag = mode === 'unk' ? 'unknown' : (mode === 'inh' ? '↳ ' : '') + cats[cat];
158
+ return {
159
+ name: name, due: due ? due + ' due' : '', hasDue: !!due,
160
+ row: 'display:flex;align-items:center;gap:6px;height:28px;padding:0 8px;border-radius:6px;' + (opts.sel ? 'background:#13243b;box-shadow:inset 2px 0 0 #e6eef7;' : ''),
161
+ ind: 'width:' + (depth * 16) + 'px;flex-shrink:0;',
162
+ fold: opts.leaf ? i.folder : i.open,
163
+ icon: mode === 'unk' ? i.unknown : i[cat], tag: tag,
164
+ tagSt: mode === 'set' ? s.set : mode === 'inh' ? s.inh : unk
165
+ };
166
+ }
167
+ var tree = [
168
+ row('Org', 0, 'strategy', 'set', 0),
169
+ row('Strategy 2027', 1, 'strategy', 'inh', 0, { leaf: true }),
170
+ row('Principles', 1, 'policy', 'set', 0, { leaf: true }),
171
+ row('Decisions', 1, 'decision', 'set', 1, { leaf: true }),
172
+ row('Platform team', 0, 'research', 'set', 0),
173
+ row('Objectives', 1, 'strategy', 'set', 0, { leaf: true }),
174
+ row('Decisions', 1, 'decision', 'set', 2, { leaf: true }),
175
+ row('Metrics', 1, 'metric', 'set', 5, { leaf: true, sel: true }),
176
+ row('Spikes', 1, 'research', 'inh', 1, { leaf: true }),
177
+ row('Pepe', 0, 'notes', 'set', 0),
178
+ row('Reading', 1, 'notes', 'inh', 0, { leaf: true }),
179
+ row('Pricing drafts', 1, 'notes', 'inh', 0, { leaf: true }),
180
+ row('Inbox', 0, '', 'unk', 0, { leaf: true })
181
+ ];
182
+ var solo = [
183
+ row('Projects', 0, 'question', 'set', 0),
184
+ row('Urban heat', 1, 'question', 'inh', 0, { leaf: true }),
185
+ row('Bike lanes', 1, 'question', 'inh', 0, { leaf: true }),
186
+ row('Sources', 0, 'source', 'set', 0),
187
+ row('Papers', 1, 'source', 'inh', 2, { leaf: true }),
188
+ row('Datasets', 1, 'source', 'inh', 1, { leaf: true }),
189
+ row('Findings', 0, 'finding', 'set', 0, { leaf: true }),
190
+ row('Notes', 0, 'notes', 'set', 0, { leaf: true })
191
+ ];
192
+ var legend = [
193
+ { st: s.set, icon: i.decision, tag: 'Decision', d: 'Set here. Glyph and word, no colour: categories are not meanings.' },
194
+ { st: s.inh, icon: i.research, tag: '↳ Research', d: 'Inherited from the nearest folder above that sets one.' },
195
+ { st: unk, icon: i.unknown, tag: 'unknown', d: 'Nothing above sets a category. No lifecycle, and never an invented expiry date.' },
196
+ { st: s.due, icon: i.glass, tag: '5 due', d: 'Boards in the folder waiting for a review. Amber: needs a look.' }
197
+ ];
198
+ var rules = [
199
+ { t: 'One hierarchy', d: 'Category is a property of a folder (or a board), not tags or a second tree. A board still lives in one folder; links stay many-to-many.' },
200
+ { t: 'The workspace owns the list', d: 'One category list per workspace, edited in Categories. The product ships editable defaults; a template fills them in.' },
201
+ { t: 'Category never grants access', d: 'Folder names and categories say what knowledge is, not who sees it. Audience is a later, separate property.' }
202
+ ];
203
+ return { i: i, s: s, tree: tree, solo: solo, legend: legend, rules: rules };
204
+ }
205
+ }
206
+ </script>
207
+ </body>
208
+ </html>
@@ -0,0 +1,33 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head><meta charset="utf-8"><title>C1 · Compact category inspector</title><script src="./support.js"></script></head>
4
+ <body>
5
+ <x-dc>
6
+ <helmet>
7
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&amp;family=IBM+Plex+Sans:wght@400;500;600&amp;display=swap">
8
+ <style>
9
+ body{margin:0} .c1{width:1440px;height:1100px;box-sizing:border-box;padding:48px;background:#081524;color:#e6eef7;font:13px/1.5 'IBM Plex Sans',system-ui,sans-serif}
10
+ .c1 h1{font-size:28px;margin:0}.c1 p{color:#8ea3bd}.c1 .dialog{width:900px;margin:32px auto;border:1px solid #1b2c44;border-radius:14px;background:#0f1d31;padding:20px;box-sizing:border-box}.c1 header,.c1 footer,.c1 nav{display:flex;gap:8px;align-items:center}.c1 header{border-bottom:1px solid #1b2c44;padding-bottom:12px}.c1 header strong{flex:1;font-size:15px}.c1 button,.c1 input,.c1 select,.c1 textarea{font:inherit;color:inherit;background:#081524;border:1px solid #1b2c44;border-radius:6px;padding:7px 10px;box-sizing:border-box}.c1 .columns{display:grid;grid-template-columns:220px 1fr;gap:24px;margin:16px 0}.c1 aside button{width:100%;text-align:left;margin:4px 0;display:flex;flex-direction:column}.c1 small{color:#8ea3bd}.c1 .selected{border-color:#e6eef7;background:#13243b}.c1 label{display:flex;flex-direction:column;gap:6px;margin:12px 0}.c1 footer{border-top:1px solid #1b2c44;padding-top:12px;justify-content:flex-end}.c1 .save{background:#4BBCFF;color:#081524;border-color:transparent;font-weight:600}.c1 summary{color:#8ea3bd;cursor:pointer}.c1 .states{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.c1 .states section{border:1px solid #1b2c44;border-radius:10px;padding:16px;background:#0f1d31}
11
+ </style></helmet>
12
+ <main class="c1">
13
+ <h1>C1 · Compact category inspector</h1>
14
+ <p>Selected 2026-10-14 · local implementation, validation ongoing. One neutral workspace list; folders choose categories, cards override only lifecycle.</p>
15
+ <section class="dialog">
16
+ <header><strong>Workspace categories</strong><button>×</button></header>
17
+ <details style="margin-top:12px"><summary>Add from template</summary><p>Org · team · personal / Solo research / Product team / Empty. Add missing entries only; never overwrite edits.</p></details>
18
+ <div class="columns">
19
+ <aside><label style="margin-bottom:0">Search categories<input type="search" placeholder="Search categories"></label><button style="margin-top:8px">+ Add category</button><button class="selected"><strong>⌕ Research</strong><small>Medium · 90 days</small></button><button><strong>⚑ Decision</strong><small>Durable</small></button><button><strong>▤ Notes</strong><small>Slow · on resume</small></button><button><strong>▥ Metric</strong><small>Fast · at use</small></button></aside>
20
+ <section><h2 style="font-size:15px;margin:0 0 12px">⌕ Research</h2><nav><button>Basics</button><button class="selected">Review policy</button><button>Usage</button></nav><label>Why review?<select><option>Reality · facts change</option></select></label><label>Review frequency<select><option>Medium · on a cadence</option></select></label><label>Cadence in days<input value="90"></label><label>How to check<textarea rows="2">Check sources and conflicting evidence.</textarea></label><details><summary>Additional review triggers</summary><p>Source changes · contradiction · dependency changes</p></details><p>Changes affect inheriting folders. Explicit folder and card overrides keep their policy.</p></section>
21
+ </div><footer><button>Cancel</button><button class="save">Save category</button></footer>
22
+ </section>
23
+ <div class="states">
24
+ <section><strong>Basics / Usage</strong><label>Glyph<input value="⌕"></label><div role="group" aria-label="Glyph choices" style="display:flex;flex-wrap:wrap;gap:6px"><button>◎</button><button>◇</button><button>⚑</button><button class="selected">⌕</button><button>▥</button><button>✎</button><button>?</button><button>▤</button><button>◉</button></div><p>Choose a starter glyph or type your own. Only the glyph changes, not the category's name or review policy. Usage names explicitly assigned folders.</p></section>
25
+ <section><strong>Dirty-leave guard</strong><p>Discard unsaved category changes?</p><button>Keep editing</button> <button>Discard changes</button><p>Switching category, Cancel, close or Escape uses the guard.</p></section>
26
+ <section><strong>Deletion protection</strong><p>Assigned to Projects / Research. Reassign or clear the folder first.</p><p>Unused deletion asks inline confirmation. Never clears folder assignments or inherited policy.</p></section>
27
+ </div>
28
+ </main>
29
+ </x-dc>
30
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1100}}'>
31
+ class Component extends DCLogic { renderVals() { return {}; } }
32
+ </script>
33
+ </body></html>
@@ -13,7 +13,7 @@
13
13
  body{margin:0}
14
14
  </style>
15
15
  </helmet>
16
- <div style="width: 1440px; height: 820px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px">
16
+ <div style="width: 1440px; height: 1000px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: grid; grid-template-columns: 500px repeat(2, minmax(0, 1fr)); gap: 40px">
17
17
 
18
18
  <section style="display: flex; flex-direction: column; gap: 14px">
19
19
  <div><h2 style="margin: 0; font-size: 15px; font-weight: 600">7 · Tool rail in a 690px-tall window</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">20 buttons need 850px. Settings-type tools move into one menu.</p></div>
@@ -37,20 +37,25 @@ body{margin:0}
37
37
  <span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed</span>
38
38
  <div style="position: relative; height: 600px; border: 1px solid #1b2c44; border-radius: 10px; overflow: hidden; background: #081524">
39
39
  <div style="width: 52px; height: 600px; box-sizing: border-box; padding: 8px 0; background: #0f1d31; border-right: 1px solid #1b2c44; display: flex; flex-direction: column; align-items: center; gap: 4px">
40
- <sc-for list="{{railNew}}" as="i" hint-placeholder-count="12">
40
+ <sc-for list="{{railNew}}" as="i" hint-placeholder-count="13">
41
41
  <sc-if value="{{i.sep}}" hint-placeholder-val="{{ false }}"><div style="width: 24px; height: 1px; margin: 6px 0; background: #1b2c44; flex-shrink: 0"></div></sc-if>
42
42
  <sc-if value="{{i.grow}}" hint-placeholder-val="{{ false }}"><div style="flex: 1"></div></sc-if>
43
43
  <sc-if value="{{i.btn}}" hint-placeholder-val="{{ true }}"><button aria-label="{{i.label}}" style="{{i.style}}"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round"><path d="{{i.d}}"></path></svg></button></sc-if>
44
44
  </sc-for>
45
45
  </div>
46
- <div role="menu" aria-label="Settings" style="position: absolute; left: 60px; bottom: 8px; width: 180px; box-sizing: border-box; padding: 6px; border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 10px 30px rgba(0,0,0,0.6); display: flex; flex-direction: column; gap: 2px">
47
- <sc-for list="{{settings}}" as="m" hint-placeholder-count="6">
46
+ <!-- Tooltip preview is a sibling of the scrolling menu, never clipped by its overflow. -->
47
+ <div role="tooltip" id="settings-tooltip-preview" style="position: absolute; z-index: 2; left: 60px; bottom: 340px; width: 280px; box-sizing: border-box; padding: 10px 12px; border: 1px solid #2a4566; border-radius: 6px; background: #13243b; color: #b9c6d6; font-size: 12px; box-shadow: 0 6px 20px rgba(0,0,0,0.24)"><strong style="color: #e6eef7">Hover / keyboard focus</strong><br>Show session tools for this workspace. Off hides the tools, not attached agents or their protections.</div>
48
+ <div role="menu" aria-label="Settings" style="position: absolute; left: 60px; bottom: 8px; width: 280px; max-height: 316px; overflow-y: auto; box-sizing: border-box; padding: 6px; border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 10px 30px rgba(0,0,0,0.6); display: flex; flex-direction: column; gap: 2px">
49
+ <div style="padding: 4px 10px; color: #8ea3bd; font-size: 11px">Workspace · all boards</div>
50
+ <sc-for list="{{settings}}" as="m" hint-placeholder-count="8">
48
51
  <sc-if value="{{m.sep}}" hint-placeholder-val="{{ false }}"><div style="height: 1px; margin: 4px 6px; background: #1b2c44"></div></sc-if>
49
- <sc-if value="{{m.btn}}" hint-placeholder-val="{{ true }}"><button role="menuitem" style="display: flex; align-items: center; justify-content: space-between; height: 30px; padding: 0 10px; border: 0; border-radius: 6px; background: {{m.bg}}; color: #e6eef7; font-family: inherit; font-size: 12px; text-align: left">{{m.label}}<span style="font-size: 11px; color: #6b7d94">{{m.hint}}</span></button></sc-if>
52
+ <sc-if value="{{m.btn}}" hint-placeholder-val="{{ true }}"><button role="menuitem" aria-description="{{m.tip}}" style="display: flex; flex-shrink: 0; align-items: center; justify-content: space-between; height: 30px; padding: 0 10px; border: 0; border-radius: 6px; background: {{m.bg}}; color: #e6eef7; font-family: inherit; font-size: 12px; text-align: left">{{m.label}}<span style="font-size: 11px; color: #6b7d94">{{m.hint}}</span></button></sc-if>
53
+ <sc-if value="{{m.toggle}}" hint-placeholder-val="{{ false }}"><button role="menuitemcheckbox" aria-checked="false" aria-description="{{m.tip}}" style="display: flex; flex-shrink: 0; align-items: center; justify-content: space-between; gap: 8px; height: 34px; padding: 0 10px; border: 0; border-radius: 6px; background: {{m.bg}}; color: #e6eef7; font-family: inherit; font-size: 12px; text-align: left"><span>{{m.label}} <sc-if value="{{m.beta}}" hint-placeholder-val="{{ true }}"><span style="font-size: 10px; color: #8ea3bd">Beta</span></sc-if></span><span style="display: flex; align-items: center; gap: 6px; font-size: 11px; color: #8ea3bd">Off <span aria-hidden="true" style="display: inline-flex; align-items: center; width: 24px; height: 14px; padding: 2px; box-sizing: border-box; border: 1px solid #6b7d94; border-radius: 999px; background: #081524"><span style="width: 8px; height: 8px; border-radius: 50%; background: #8ea3bd"></span></span></span></button></sc-if>
50
54
  </sc-for>
51
55
  </div>
52
56
  </div>
53
- <span style="font-size: 11px; color: #8ea3bd">12 tools, then Settings: theme, snapshots, minimap, shortcuts, trace, feedback.</span>
57
+ <span style="font-size: 11px; color: #8ea3bd">13 tools, then Settings. Both Beta switches default Off and persist library-wide, never in board snapshots. Every main item explains itself on hover and keyboard focus through a nonnative, viewport-contained overlay outside the scrolling menu (preview above). Saving disables the action with aria-disabled while retaining focus on the switch; Tab and board shortcuts never act on the canvas behind the menu. Trace toggles inline with the same switch, without a Beta label; Clear trace appears separately while capture is on or trace cards remain. Theme opens in place with “‹ Settings”, not a side flyout. Eraser stays beside Text note.</span>
58
+ <span style="font-size: 11px; color: #8ea3bd">Sessions Off: no chips, start, timeline, work items, composer or receipts; attached agents, writer visibility, approvals, scope, edit locks and veto remain. Lifecycle Off: no Review, policy/category management, filters or due/retired marks; saved records and suspended drafts remain. Folders, boards, pins and relations stay. UI opt-ins only, not API/security disables; retired context stays excluded.</span>
54
59
  </div>
55
60
 
56
61
  </div>
@@ -101,6 +106,33 @@ body{margin:0}
101
106
  </sc-for>
102
107
  </div>
103
108
  </div>
109
+
110
+ <span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Reference footer · many connections</span>
111
+ <div style="height: 236px; display: flex; flex-direction: column; border: 1px solid #1b2c44; border-radius: 10px; overflow: hidden; background: #0f1d31">
112
+ <div style="flex-shrink: 0; height: 36px; display: flex; align-items: center; padding: 0 12px; border-bottom: 1px solid #1b2c44; font-size: 12px; font-weight: 600">Research index</div>
113
+ <div style="flex: 1; min-height: 0; display: flex; flex-direction: column">
114
+ <div style="flex: 1; min-height: 0; padding: 10px 12px; overflow: auto; font-size: 13px; color: #b9c6d6">Read the source, then follow <a href="#reference-footer" style="color: #e6eef7">the evidence</a>.<div style="margin-top: 20px; font-size: 12px; color: #8ea3bd">Set as README <span style="float: right">Edit</span></div></div>
115
+ <div id="reference-footer" role="region" aria-label="Cross-board references" tabindex="0" style="flex-shrink: 0; max-height: min(40%, 132px); overflow: auto; overscroll-behavior: contain">
116
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Interview notes</div>
117
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Findings</div>
118
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Follow-ups</div>
119
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Next steps</div>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ <span style="font-size: 11px; color: #8ea3bd">Keep every connection. Only the references scroll, capped at 40% of the body and 132 world px; short lists keep their natural height. The document and its actions retain their own space. Wheel and keyboard scrolling stay inside the footer.</span>
124
+ <span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Reference footer · focus mode</span>
125
+ <div style="height: 350px; display: flex; flex-direction: column; border: 1px solid #1b2c44; border-radius: 14px; overflow: hidden; background: #0f1d31">
126
+ <div style="flex-shrink: 0; height: 46px; display: flex; align-items: center; gap: 10px; padding: 0 16px; border-bottom: 1px solid #1b2c44; font-size: 13px; font-weight: 600">Research index <span style="margin-left: auto; font-size: 12px; font-weight: 400">Relations</span><span style="margin-left: 12px">×</span></div>
127
+ <div style="flex: 1; min-height: 0; overflow: auto; padding: 16px; font-size: 13px; color: #b9c6d6">Read and edit the source here. Actual edits finish saving before a reference opens; a refused save keeps this reader and its draft.</div>
128
+ <div role="region" aria-label="Cross-board references" tabindex="0" style="flex-shrink: 0; max-height: min(40%, 132px); overflow: auto; overscroll-behavior: contain">
129
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Interview notes</div>
130
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Findings</div>
131
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Follow-ups</div>
132
+ <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Next steps</div>
133
+ </div>
134
+ <div style="flex-shrink: 0; height: 28px; display: flex; align-items: center; padding: 0 16px; border-top: 1px solid #1b2c44; font-size: 11px; color: #8ea3bd">markdown<span style="margin-left: auto">esc or click outside to close</span></div>
135
+ </div>
104
136
  </section>
105
137
 
106
138
  <section style="display: flex; flex-direction: column; gap: 14px">
@@ -145,7 +177,7 @@ body{margin:0}
145
177
 
146
178
  </div>
147
179
  </x-dc>
148
- <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":820}}'>
180
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1000}}'>
149
181
  class Component extends DCLogic {
150
182
  renderVals() {
151
183
  var P = {
@@ -192,7 +224,7 @@ class Component extends DCLogic {
192
224
  var railNew = [
193
225
  b('Home', P.home), sep,
194
226
  b('Select', P.select), b('Pan', P.pan), b('Connect', P.connect), sep,
195
- b('Markdown note', P.note), b('Attach files', P.attach), b('Webpage', P.web), b('Group', P.group), b('Draw', P.draw), b('Text note', P.text), sep,
227
+ b('Markdown note', P.note), b('Attach files', P.attach), b('Webpage', P.web), b('Group', P.group), b('Draw', P.draw), b('Text note', P.text), b('Eraser', P.eraser), sep,
196
228
  b('Search and commands', P.search), b('Arrange', P.arrange), grow, b('Settings', P.settings)
197
229
  ].map(function (i) {
198
230
  if (!i.btn) return i;
@@ -200,7 +232,18 @@ class Component extends DCLogic {
200
232
  });
201
233
  function m(label, hint, active) { return { btn: true, sep: false, label: label, hint: hint, bg: active ? '#1b2c44' : 'transparent' }; }
202
234
  var msep = { btn: false, sep: true };
203
- var settings = [m('Theme', 'Dark ›', true), m('Snapshots', ''), m('Minimap', 'On'), m('Keyboard shortcuts', '?'), msep, m('Trace', 'Off ›'), m('Send feedback', '')];
235
+ function setting(label, hint, tip) { return Object.assign(m(label, hint), { tip: tip, toggle: false }); }
236
+ function optIn(label, tip, active, beta = true) { return { btn: false, sep: false, toggle: true, beta: beta, label: label, tip: tip, bg: active ? '#1b2c44' : 'transparent' }; }
237
+ var settings = [
238
+ setting('Theme', 'Harbor ›', 'Choose the workspace appearance.'),
239
+ setting('Snapshots', '', 'Save or restore this board; workspace opt-ins are not included.'),
240
+ setting('Minimap', 'On', 'Show or hide the board overview.'),
241
+ setting('Keyboard shortcuts', '?', 'See the available keyboard commands.'), msep,
242
+ optIn('Agent sessions', 'Show session tools for this workspace. Off hides the tools, not attached agents or their protections.', true),
243
+ optIn('Knowledge lifecycle', 'This turns on context lifecycle, where boards and cards decay over time as their relevance fades. Includes Review, review policies, categories, and due or retired indicators. Turning off hides lifecycle tools without deleting their data or drafts. Saved for this workspace.'), msep,
244
+ optIn('Trace', 'Show execution traces. Turning off keeps existing traces and never starts an agent.', false, false),
245
+ setting('Send feedback', '', 'Share feedback about PMX Canvas.')
246
+ ];
204
247
  var nodeMenu = [m('Focus', ''), m('Rename…', ''), m('Collapse', ''), m('Open in new tab', '', true), msep, m('Delete', '⌫')];
205
248
  var oldIcons = [{ d: P.ctx }, { d: P.ask }, { d: P.open }, { d: P.expand }, { d: P.chevron }, { d: P.close }];
206
249
  return { railToday: railToday, railNew: railNew, settings: settings, nodeMenu: nodeMenu, oldIcons: oldIcons };