pmx-canvas 0.7.2 → 0.8.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.
- package/.github/extensions/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/.github/extensions/pmx-canvas/extension.mjs +25 -172
- package/.github/extensions/pmx-canvas/mcp-bootstrap.ts +198 -0
- package/.github/extensions/pmx-canvas/runtime.d.mts +41 -0
- package/.github/extensions/pmx-canvas/runtime.json +3 -0
- package/.github/extensions/pmx-canvas/runtime.mjs +194 -0
- package/.github/extensions/pmx-canvas/start-mcp.mjs +51 -0
- package/.github/extensions/pmx-canvas/tools.json +2560 -0
- package/CHANGELOG.md +60 -0
- package/Readme.md +44 -16
- package/dist/canvas/fonts/OFL.txt +93 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-600-normal.woff2 +0 -0
- package/dist/canvas/global.css +844 -710
- package/dist/canvas/index.js +92 -90
- package/dist/canvas/mcp-app.html +7878 -0
- package/dist/canvas/mermaid-entry.js +1 -1
- package/dist/canvas/surface-theme.css +151 -46
- package/dist/json-render/index.css +1 -1
- package/dist/json-render/index.js +55 -55
- package/dist/types/cli/commands/record.d.ts +1 -1
- package/dist/types/client/canvas/ChoiceMenu.d.ts +13 -0
- package/dist/types/client/canvas/NodeContextMark.d.ts +24 -0
- package/dist/types/client/canvas/SessionReceipt.d.ts +3 -1
- package/dist/types/client/icons.d.ts +1 -2
- package/dist/types/client/mcp-app/index.d.ts +1 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +2 -1
- package/dist/types/client/nodes/ax-node-actions.d.ts +2 -2
- package/dist/types/client/nodes/markdown-sanitize.d.ts +2 -0
- package/dist/types/client/nodes/use-workbench-asset.d.ts +2 -0
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -0
- package/dist/types/client/state/attention-store.d.ts +0 -5
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/state/context-status-store.d.ts +53 -0
- package/dist/types/client/state/intent-bridge.d.ts +4 -1
- package/dist/types/client/state/near-pin-store.d.ts +16 -0
- package/dist/types/client/state/presence-store.d.ts +5 -0
- package/dist/types/client/state/session-store.d.ts +33 -3
- package/dist/types/client/state/workbench-transport.d.ts +16 -0
- package/dist/types/client/theme/tokens.d.ts +1 -3
- package/dist/types/client/types.d.ts +9 -0
- package/dist/types/json-render/renderer/index.d.ts +2 -1
- package/dist/types/json-render/server.d.ts +3 -1
- package/dist/types/mcp/app-server.d.ts +3 -0
- package/dist/types/mcp/canvas-access.d.ts +1 -1
- package/dist/types/mcp/canvas-app.d.ts +4 -0
- package/dist/types/mcp/workbench-app.d.ts +4 -0
- package/dist/types/server/agent-presence.d.ts +1 -1
- package/dist/types/server/ax-state.d.ts +1 -1
- package/dist/types/server/canvas-db.d.ts +8 -0
- package/dist/types/server/canvas-geometry.d.ts +25 -0
- package/dist/types/server/canvas-operations.d.ts +1 -11
- package/dist/types/server/canvas-state.d.ts +25 -3
- package/dist/types/server/context-brief.d.ts +8 -1
- package/dist/types/server/context-reads.d.ts +30 -7
- package/dist/types/server/index.d.ts +6 -1
- package/dist/types/server/mcp-app-runtime.d.ts +1 -0
- package/dist/types/server/operations/http.d.ts +2 -0
- package/dist/types/server/operations/invoker.d.ts +4 -2
- package/dist/types/server/operations/ops/nodes.d.ts +0 -6
- package/dist/types/server/server.d.ts +1 -0
- package/dist/types/server/spatial-analysis.d.ts +2 -0
- package/dist/types/shared/agent-context.d.ts +22 -0
- package/dist/types/shared/agent-presence.d.ts +3 -10
- package/dist/types/shared/ax-surface-protocol.d.ts +2 -0
- package/dist/types/shared/canvas-app.d.ts +54 -0
- package/dist/types/shared/themes.d.ts +1 -1
- package/docs/RELEASE.md +7 -3
- package/docs/agent-plugin.md +123 -0
- package/docs/ax-host-adapter-contract.md +13 -2
- package/docs/ax-state-contract.md +40 -0
- package/docs/cli.md +7 -2
- package/docs/design/AgentContext.dc.html +186 -0
- package/docs/design/Before.dc.html +208 -0
- package/docs/design/BoardPins.dc.html +151 -0
- package/docs/design/Chrome.dc.html +208 -0
- package/docs/design/Context.dc.html +239 -0
- package/docs/design/Flows.dc.html +181 -0
- package/docs/design/Home.dc.html +209 -0
- package/docs/design/HomeGraph.dc.html +211 -0
- package/docs/design/HomeMap.dc.html +117 -0
- package/docs/design/HomeTeam.dc.html +176 -0
- package/docs/design/Light.dc.html +28 -0
- package/docs/design/Main.dc.html +280 -0
- package/docs/design/NearPin.dc.html +260 -0
- package/docs/design/Pane600.dc.html +120 -0
- package/docs/design/Relations.dc.html +297 -0
- package/docs/design/Themes.dc.html +121 -0
- package/docs/design/TokenSystem.dc.html +136 -0
- package/docs/design/Tokens.dc.html +163 -0
- package/docs/design/Types1.dc.html +177 -0
- package/docs/design/Types2.dc.html +226 -0
- package/docs/design/Types3.dc.html +195 -0
- package/docs/design/Uses.dc.html +152 -0
- package/docs/design/Vision.dc.html +116 -0
- package/docs/design/Zoom.dc.html +82 -0
- package/docs/design/canvas.json +274 -0
- package/docs/design.md +214 -0
- package/docs/environment.md +1 -1
- package/docs/http-api.md +80 -15
- package/docs/mcp.md +198 -3
- package/docs/node-types.md +34 -10
- package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
- package/docs/plans/plan-015-design-foundation-wave-0.md +177 -0
- package/docs/plans/plan-016-context-made-visible-wave-1.md +148 -0
- package/docs/product-vision-2026-09.md +47 -7
- package/docs/screenshot.png +0 -0
- package/docs/sdk.md +1 -0
- package/package.json +10 -4
- package/plugins/pmx-canvas/LICENSE +21 -0
- package/plugins/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/plugins/pmx-canvas/assets/preview.png +0 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +930 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/steering-delivery.mjs +79 -0
- package/plugins/pmx-canvas/mcp.json +12 -0
- package/plugins/pmx-canvas/plugin.json +24 -0
- package/plugins/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/start-mcp.mjs +51 -0
- package/plugins/pmx-canvas/tools.json +2560 -0
- package/skills/pmx-canvas/SKILL.md +31 -16
- package/skills/pmx-canvas/evals/evals.json +69 -0
- package/skills/pmx-canvas/references/full-reference.md +14 -10
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +20 -8
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +76 -4
- package/skills/pmx-canvas-testing/SKILL.md +54 -4
- package/src/cli/commands/copilot.ts +5 -0
- package/src/cli/commands/view.ts +1 -1
- package/src/cli/index.ts +8 -3
- package/src/client/App.tsx +6 -1
- package/src/client/canvas/AgentPresenceLayer.tsx +3 -3
- package/src/client/canvas/AnnotationLayer.tsx +1 -1
- package/src/client/canvas/CanvasNode.tsx +208 -220
- package/src/client/canvas/CanvasViewport.tsx +6 -2
- package/src/client/canvas/ChoiceMenu.tsx +122 -0
- package/src/client/canvas/CommandBar.tsx +25 -23
- package/src/client/canvas/CommandPalette.tsx +3 -2
- package/src/client/canvas/ContextMenu.tsx +11 -0
- package/src/client/canvas/EdgeLayer.tsx +1 -1
- package/src/client/canvas/ExportDialog.tsx +33 -6
- package/src/client/canvas/FeedbackDialog.tsx +10 -8
- package/src/client/canvas/IntentLayer.tsx +2 -2
- package/src/client/canvas/Minimap.tsx +12 -7
- package/src/client/canvas/NodeContextMark.tsx +156 -0
- package/src/client/canvas/SessionPanel.tsx +4 -7
- package/src/client/canvas/SessionReceipt.tsx +114 -17
- package/src/client/canvas/ShortcutOverlay.tsx +6 -1
- package/src/client/canvas/SnapshotPanel.tsx +11 -2
- package/src/client/canvas/ToolRail.tsx +58 -108
- package/src/client/canvas/TopBar.tsx +16 -11
- package/src/client/icons.tsx +2 -12
- package/src/client/mcp-app/index.tsx +137 -0
- package/src/client/mcp-app/style.css +10 -0
- package/src/client/nodes/AttachmentNode.tsx +8 -1
- package/src/client/nodes/AxStepControls.tsx +1 -1
- package/src/client/nodes/ContextNode.tsx +9 -9
- package/src/client/nodes/ExtAppFrame.tsx +13 -8
- package/src/client/nodes/FileNode.tsx +8 -5
- package/src/client/nodes/ImageNode.tsx +4 -2
- package/src/client/nodes/InlineMarkdownEditor.tsx +2 -1
- package/src/client/nodes/LedgerNode.tsx +2 -2
- package/src/client/nodes/MarkdownNode.tsx +44 -9
- package/src/client/nodes/McpAppNode.tsx +22 -4
- package/src/client/nodes/PromptNode.tsx +5 -17
- package/src/client/nodes/ResponseNode.tsx +3 -15
- package/src/client/nodes/StatusNode.tsx +2 -2
- package/src/client/nodes/StatusSummary.tsx +3 -1
- package/src/client/nodes/TraceNode.tsx +6 -4
- package/src/client/nodes/WebpageNode.tsx +1 -1
- package/src/client/nodes/ax-node-actions.ts +2 -2
- package/src/client/nodes/iframe-document-url.ts +3 -2
- package/src/client/nodes/markdown-sanitize.ts +10 -0
- package/src/client/nodes/surface-url.ts +10 -0
- package/src/client/nodes/use-ax-surface-bridge.ts +4 -2
- package/src/client/nodes/use-surface-frame.ts +3 -1
- package/src/client/nodes/use-workbench-asset.ts +26 -0
- package/src/client/nodes/viewer-runtime-state.ts +78 -0
- package/src/client/state/attention-bridge.ts +0 -8
- package/src/client/state/attention-store.ts +0 -17
- package/src/client/state/canvas-store.ts +7 -2
- package/src/client/state/context-status-store.ts +66 -0
- package/src/client/state/human-store.ts +2 -0
- package/src/client/state/iframe-mode.ts +5 -0
- package/src/client/state/intent-bridge.ts +24 -6
- package/src/client/state/near-pin-store.ts +53 -0
- package/src/client/state/presence-store.ts +5 -10
- package/src/client/state/session-store.ts +106 -9
- package/src/client/state/sse-bridge.ts +26 -7
- package/src/client/state/theme-override.ts +1 -1
- package/src/client/state/workbench-transport.ts +36 -0
- package/src/client/theme/global.css +844 -710
- package/src/client/theme/surface-theme.css +151 -46
- package/src/client/theme/tokens.ts +7 -11
- package/src/client/types.ts +10 -0
- package/src/json-render/renderer/index.tsx +58 -38
- package/src/json-render/server.ts +79 -15
- package/src/mcp/app-server.ts +64 -0
- package/src/mcp/canvas-access.ts +14 -11
- package/src/mcp/canvas-app.ts +318 -0
- package/src/mcp/server.ts +1 -1
- package/src/mcp/workbench-app.ts +211 -0
- package/src/server/agent-presence.ts +45 -6
- package/src/server/ax-context.ts +1 -1
- package/src/server/ax-state.ts +1 -1
- package/src/server/board-export.ts +5 -2
- package/src/server/canvas-db.ts +46 -12
- package/src/server/canvas-geometry.ts +64 -0
- package/src/server/canvas-operations.ts +6 -24
- package/src/server/canvas-state.ts +105 -15
- package/src/server/canvas-validation.ts +19 -4
- package/src/server/context-brief.ts +39 -2
- package/src/server/context-reads.ts +86 -15
- package/src/server/demo-state.json +31 -31
- package/src/server/html-surface.ts +4 -5
- package/src/server/index.ts +19 -3
- package/src/server/mcp-app-runtime.ts +11 -0
- package/src/server/operations/composites.ts +4 -3
- package/src/server/operations/http.ts +4 -4
- package/src/server/operations/invoker.ts +13 -4
- package/src/server/operations/ops/ax-read.ts +1 -1
- package/src/server/operations/ops/ax-timeline.ts +37 -0
- package/src/server/operations/ops/boards.ts +1 -1
- package/src/server/operations/ops/canvas-wire.ts +3 -6
- package/src/server/operations/ops/intent.ts +31 -2
- package/src/server/operations/ops/json-render.ts +1 -1
- package/src/server/operations/ops/nodes.ts +8 -76
- package/src/server/operations/ops/query.ts +8 -2
- package/src/server/operations/ops/snapshots.ts +4 -1
- package/src/server/operations/ops/viewport.ts +29 -5
- package/src/server/operations/registry.ts +38 -4
- package/src/server/scope-fence.ts +55 -10
- package/src/server/server.ts +86 -6
- package/src/server/spatial-analysis.ts +2 -2
- package/src/server/workboard.ts +6 -1
- package/src/{server → shared}/agent-context.ts +2 -2
- package/src/shared/agent-presence.ts +3 -15
- package/src/shared/ax-surface-protocol.ts +3 -0
- package/src/shared/canvas-app.ts +62 -0
- package/src/shared/themes.ts +5 -5
- package/src/client/canvas/FocusFieldLayer.tsx +0 -116
- package/src/client/canvas/kind-colors.ts +0 -23
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Nodes in context</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&family=IBM+Plex+Sans:wght@400;500;600&display=swap">
|
|
12
|
+
<style>
|
|
13
|
+
body{margin:0}
|
|
14
|
+
</style>
|
|
15
|
+
</helmet>
|
|
16
|
+
<div style="width: 1440px; height: 1400px; box-sizing: border-box; padding: 48px 56px; 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: 36px">
|
|
17
|
+
|
|
18
|
+
<div>
|
|
19
|
+
<h1 style="margin: 0; font-size: 28px; font-weight: 600; letter-spacing: -0.015em">Nodes in context</h1>
|
|
20
|
+
<p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">Pinned, being edited by the agent, and selected are three different facts. Today a pin spreads an amber halo to its neighbours and an agent edit is a faint blue sheen; proposed, each fact has its own signal and they combine.</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<section style="display: flex; flex-direction: column; gap: 12px">
|
|
24
|
+
<h2 style="margin: 0; font-size: 15px; font-weight: 600">Which two nodes are in context?</h2>
|
|
25
|
+
<div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px">
|
|
26
|
+
<sc-for list="{{scenes}}" as="sc" hint-placeholder-count="2">
|
|
27
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
28
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">{{sc.label}}</span>
|
|
29
|
+
<div style="position: relative; height: 290px; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background-color: {{sc.bg}}; background-image: radial-gradient({{sc.dot}} 1px, transparent 1.2px); background-size: 24px 24px">
|
|
30
|
+
<sc-for list="{{sc.nodes}}" as="cell" hint-placeholder-count="6">
|
|
31
|
+
<div style="position: absolute; left: {{cell.x}}px; top: {{cell.y}}px; width: 204px; height: 124px">
|
|
32
|
+
<sc-if value="{{cell.field}}" hint-placeholder-val="{{ false }}"><div style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 20px; background: rgba(244,197,66,0.05); box-shadow: 0 0 30px rgba(244,197,66,0.12)"></div></sc-if>
|
|
33
|
+
<div style="{{cell.node}}">
|
|
34
|
+
<div style="{{cell.head}}">
|
|
35
|
+
<svg width="14" height="14" viewBox="0 0 24 24" style="{{cell.icon}}"><path d="M6 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM8 10h8M8 14h5"></path></svg>
|
|
36
|
+
<span style="{{cell.title}}">{{cell.name}}</span>
|
|
37
|
+
<sc-if value="{{cell.oldPin}}" hint-placeholder-val="{{ false }}"><span style="color: #f4c542; font-size: 10px">●</span></sc-if>
|
|
38
|
+
<sc-if value="{{cell.expand}}" hint-placeholder-val="{{ false }}"><span style="{{cell.expandStyle}}"><svg width="12" height="12" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round"><path d="M14 4h6v6M20 4l-7 7M10 20H4v-6M4 20l7-7"></path></svg></span></sc-if><sc-if value="{{cell.pinOff}}" hint-placeholder-val="{{ false }}"><span style="{{cell.pinOffStyle}}"><svg width="10" height="10" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></span></sc-if><sc-if value="{{cell.pin}}" hint-placeholder-val="{{ false }}"><span style="{{cell.pinBadge}}"><svg width="11" height="11" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></span></sc-if>
|
|
39
|
+
<span style="{{cell.ctl}}">{{cell.ctlText}}</span>
|
|
40
|
+
</div>
|
|
41
|
+
<div style="{{cell.body}}">{{cell.text}}</div>
|
|
42
|
+
<sc-if value="{{cell.bar}}" hint-placeholder-val="{{ false }}"><div style="{{cell.barStyle}}"></div></sc-if>
|
|
43
|
+
</div>
|
|
44
|
+
<sc-if value="{{cell.handles}}" hint-placeholder-val="{{ false }}"><div style="{{cell.hTL}}"></div><div style="{{cell.hTR}}"></div><div style="{{cell.hBL}}"></div><div style="{{cell.hBR}}"></div></sc-if>
|
|
45
|
+
</div>
|
|
46
|
+
</sc-for>
|
|
47
|
+
</div>
|
|
48
|
+
<span style="font-size: 12px; color: {{sc.captionColor}}">{{sc.caption}}</span>
|
|
49
|
+
</div>
|
|
50
|
+
</sc-for>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
|
|
54
|
+
<section style="display: flex; flex-direction: column; gap: 12px">
|
|
55
|
+
<h2 style="margin: 0; font-size: 15px; font-weight: 600">Every state, side by side</h2>
|
|
56
|
+
<div style="display: grid; grid-template-columns: 120px repeat(6, minmax(0, 1fr)); column-gap: 12px; align-items: end">
|
|
57
|
+
<span></span>
|
|
58
|
+
<sc-for list="{{stateNames}}" as="sn" hint-placeholder-count="6"><span style="font-size: 12px; font-weight: 600; padding-bottom: 4px">{{sn}}</span></sc-for>
|
|
59
|
+
</div>
|
|
60
|
+
<sc-for list="{{rows}}" as="row" hint-placeholder-count="3">
|
|
61
|
+
<div style="display: grid; grid-template-columns: 120px repeat(6, minmax(0, 1fr)); column-gap: 12px; align-items: start; padding: 10px 0; border-top: 1px solid #1b2c44">
|
|
62
|
+
<div style="padding-top: 12px"><div style="font-size: 12px; font-weight: 600">{{row.label}}</div><div style="font-size: 11px; color: #8ea3bd">{{row.sub}}</div></div>
|
|
63
|
+
<sc-for list="{{row.cells}}" as="cell" hint-placeholder-count="6">
|
|
64
|
+
<div style="display: flex; flex-direction: column; gap: 6px">
|
|
65
|
+
<div style="position: relative; height: 128px; border-radius: 8px; background: {{row.bg}}">
|
|
66
|
+
<sc-if value="{{cell.field}}" hint-placeholder-val="{{ false }}"><div style="position: absolute; left: 2px; top: 2px; right: 2px; bottom: 2px; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 18px; background: rgba(244,197,66,0.05); box-shadow: 0 0 24px rgba(244,197,66,0.12)"></div></sc-if>
|
|
67
|
+
<div style="{{cell.node}}">
|
|
68
|
+
<div style="{{cell.head}}">
|
|
69
|
+
<svg width="14" height="14" viewBox="0 0 24 24" style="{{cell.icon}}"><path d="M6 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM8 10h8M8 14h5"></path></svg>
|
|
70
|
+
<span style="{{cell.title}}">{{cell.name}}</span>
|
|
71
|
+
<sc-if value="{{cell.oldPin}}" hint-placeholder-val="{{ false }}"><span style="color: #f4c542; font-size: 10px">●</span></sc-if>
|
|
72
|
+
<sc-if value="{{cell.expand}}" hint-placeholder-val="{{ false }}"><span style="{{cell.expandStyle}}"><svg width="12" height="12" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round"><path d="M14 4h6v6M20 4l-7 7M10 20H4v-6M4 20l7-7"></path></svg></span></sc-if><sc-if value="{{cell.pinOff}}" hint-placeholder-val="{{ false }}"><span style="{{cell.pinOffStyle}}"><svg width="10" height="10" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></span></sc-if><sc-if value="{{cell.pin}}" hint-placeholder-val="{{ false }}"><span style="{{cell.pinBadge}}"><svg width="11" height="11" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></span></sc-if>
|
|
73
|
+
<span style="{{cell.ctl}}">{{cell.ctlText}}</span>
|
|
74
|
+
</div>
|
|
75
|
+
<div style="{{cell.body}}">{{cell.text}}</div>
|
|
76
|
+
<sc-if value="{{cell.bar}}" hint-placeholder-val="{{ false }}"><div style="{{cell.barStyle}}"></div></sc-if>
|
|
77
|
+
</div>
|
|
78
|
+
<sc-if value="{{cell.handles}}" hint-placeholder-val="{{ false }}"><div style="{{cell.hTL}}"></div><div style="{{cell.hTR}}"></div><div style="{{cell.hBL}}"></div><div style="{{cell.hBR}}"></div></sc-if>
|
|
79
|
+
</div>
|
|
80
|
+
<span style="font-size: 11px; line-height: 1.4; color: {{cell.noteColor}}">{{cell.note}}</span>
|
|
81
|
+
</div>
|
|
82
|
+
</sc-for>
|
|
83
|
+
</div>
|
|
84
|
+
</sc-for>
|
|
85
|
+
</section>
|
|
86
|
+
|
|
87
|
+
<section style="display: flex; flex-direction: column; gap: 12px">
|
|
88
|
+
<h2 style="margin: 0; font-size: 15px; font-weight: 600">The context count</h2>
|
|
89
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 24px; align-items: start">
|
|
90
|
+
<div style="display: flex; flex-direction: column; gap: 10px">
|
|
91
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Today</span>
|
|
92
|
+
<div style="display: flex; align-items: center; gap: 12px; align-self: flex-start; height: 36px; padding: 0 12px; border-radius: 10px; border: 1px solid #f4c542; background: rgba(15,29,49,0.88); font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif">
|
|
93
|
+
<span style="font-size: 12px; font-weight: 600; color: #f4c542">✦ 4 nodes in context</span>
|
|
94
|
+
<span style="font-family: Arial, sans-serif; color: #8ea3bd">×</span>
|
|
95
|
+
</div>
|
|
96
|
+
<span style="font-size: 11px; color: #8ea3bd">Amber, the same color as warnings and the agent's halos.</span>
|
|
97
|
+
</div>
|
|
98
|
+
<div style="display: flex; flex-direction: column; gap: 10px">
|
|
99
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed — no session</span>
|
|
100
|
+
<div style="display: flex; align-items: center; gap: 8px; align-self: flex-start; height: 32px; padding: 0 6px 0 12px; border-radius: 999px; border: 1px solid rgba(75,188,255,0.3); background: #0f1d31; box-shadow: 0 10px 30px rgba(0,0,0,0.45); color: #4BBCFF; font-size: 12px; font-weight: 500">
|
|
101
|
+
<svg width="14" height="14" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg>
|
|
102
|
+
4 in context
|
|
103
|
+
<button aria-label="Clear all context pins" style="width: 22px; height: 22px; border: 0; border-radius: 999px; padding: 0; background: rgba(75,188,255,0.14); color: #4BBCFF; display: flex; align-items: center; justify-content: center"><svg width="12" height="12" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round"><path d="M7 7l10 10M17 7L7 17"></path></svg></button>
|
|
104
|
+
</div>
|
|
105
|
+
<span style="font-size: 11px; color: #8ea3bd">Same blue as the pin badge, so the count and the nodes read as one thing. Hover lights the four nodes.</span>
|
|
106
|
+
</div>
|
|
107
|
+
<div style="display: flex; flex-direction: column; gap: 10px">
|
|
108
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed — agent session (command bar)</span>
|
|
109
|
+
<div style="display: flex; flex-direction: column; gap: 10px; padding: 10px 14px; border-radius: 10px; border: 1px solid #1b2c44; background: rgba(10,23,41,0.92)">
|
|
110
|
+
<div style="display: flex; align-items: center; gap: 6px; flex-wrap: wrap">
|
|
111
|
+
<sc-for list="{{chips}}" as="ch" hint-placeholder-count="4">
|
|
112
|
+
<span style="display: flex; align-items: center; gap: 6px; height: 24px; padding: 0 4px 0 10px; border-radius: 999px; border: 1px solid rgba(75,188,255,0.25); background: rgba(75,188,255,0.1); color: #4BBCFF; font-size: 11px; font-weight: 600">{{ch}}<button aria-label="Remove from context" style="width: 18px; height: 18px; border: 0; border-radius: 999px; padding: 0; background: transparent; color: #4BBCFF; display: flex; align-items: center; justify-content: center"><svg width="10" height="10" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round"><path d="M7 7l10 10M17 7L7 17"></path></svg></button></span>
|
|
113
|
+
</sc-for>
|
|
114
|
+
<span style="flex: 1"></span>
|
|
115
|
+
<span style="display: flex; align-items: center; gap: 8px; font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd"><span style="width: 60px; height: 4px; border-radius: 2px; background: #1b2c44; overflow: hidden"><span style="display: block; width: 24%; height: 4px; background: #2fd07f"></span></span>48.2k / 200k</span>
|
|
116
|
+
</div>
|
|
117
|
+
<div style="display: flex; gap: 8px">
|
|
118
|
+
<label style="flex: 1; display: flex; align-items: center; height: 34px; padding: 0 12px; border-radius: 9px; border: 1px solid #1b2c44; background: #0f1d31"><span style="position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0)">Message the agent</span><input placeholder="Steer the agent…" style="flex: 1; border: 0; outline: none; background: transparent; color: #e6eef7; font-family: inherit; font-size: 12px"></label>
|
|
119
|
+
<button style="height: 34px; padding: 0 14px; border: 0; border-radius: 9px; background: #4BBCFF; color: #081524; font-family: inherit; font-size: 12px; font-weight: 600">Send</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
<span style="font-size: 11px; color: #8ea3bd">Each pinned node becomes a named chip; × unpins it and the budget drops (your v2 mockup).</span>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
</div>
|
|
128
|
+
</x-dc>
|
|
129
|
+
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1400}}'>
|
|
130
|
+
class Component extends DCLogic {
|
|
131
|
+
renderVals() {
|
|
132
|
+
var P = {
|
|
133
|
+
dark: { bg: '#081524', dot: 'rgba(142,163,189,0.14)', panel: '#0f1d31', line: '#1b2c44', text: '#e6eef7', soft: '#b9c6d6', muted: '#8ea3bd', accent: '#4BBCFF', accentA: 'rgba(75,188,255,0.12)', onAccent: '#081524', attn: '#B388FF', e1: '0 1px 2px rgba(0,0,0,0.4), 0 6px 20px rgba(0,0,0,0.24)' },
|
|
134
|
+
light: { bg: '#F6F7F9', dot: 'rgba(11,23,38,0.12)', panel: '#FFFFFF', line: '#DDE2E9', text: '#0B1726', soft: '#3d4d63', muted: '#55657a', accent: '#1A7ABF', accentA: 'rgba(26,122,191,0.09)', onAccent: '#FFFFFF', attn: '#7C4DDB', e1: '0 1px 2px rgba(11,23,38,0.06), 0 4px 14px rgba(11,23,38,0.06)' }
|
|
135
|
+
};
|
|
136
|
+
var inset = 'position:absolute;left:12px;top:12px;right:12px;bottom:12px;box-sizing:border-box;overflow:hidden;';
|
|
137
|
+
function handle(pos, fill, line) {
|
|
138
|
+
return 'position:absolute;' + pos + 'width:8px;height:8px;box-sizing:border-box;border-radius:2px;background:' + fill + ';border:1.5px solid ' + line + ';';
|
|
139
|
+
}
|
|
140
|
+
function today(state, name, text) {
|
|
141
|
+
var pinned = state === 'pin' || state === 'pinagent' || state === 'pinsel';
|
|
142
|
+
var agent = state === 'agent' || state === 'pinagent';
|
|
143
|
+
// semantic-attention.ts: the pinned nodes are the primary focus, so a pin always brings the halo and field
|
|
144
|
+
var primary = pinned;
|
|
145
|
+
var border = '#1b2c44', shadow = '0 4px 24px rgba(0,0,0,0.3)';
|
|
146
|
+
if (state === 'sec') shadow = '0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1)';
|
|
147
|
+
if (state === 'sel') { border = '#4BBCFF'; shadow = '0 0 0 1px #4BBCFF, 0 0 0 4px rgba(75,188,255,0.1)'; }
|
|
148
|
+
if (pinned) { border = 'rgba(244,197,66,0.6)'; shadow = '0 0 0 2px #f4c542, 0 0 8px rgba(244,197,66,0.3)'; }
|
|
149
|
+
if (primary) shadow = '0 0 0 1px rgba(244,197,66,0.72), 0 12px 34px rgba(244,197,66,0.18), inset 0 0 0 1px rgba(244,197,66,0.28)';
|
|
150
|
+
var headBg = primary ? 'linear-gradient(90deg, rgba(244,197,66,0.12), transparent 68%), #0b1828' : '#0b1828';
|
|
151
|
+
// agent-mutating before wave 0: accent border at 45% and a moving accent sheen
|
|
152
|
+
var bg = agent ? 'linear-gradient(100deg, transparent 20%, rgba(75,188,255,0.13) 50%, transparent 80%), #0f1d31' : '#0f1d31';
|
|
153
|
+
if (agent) border = 'rgba(75,188,255,0.45)';
|
|
154
|
+
var sel = state === 'sel' || state === 'pinsel';
|
|
155
|
+
return {
|
|
156
|
+
field: primary, oldPin: pinned, pin: false, pinOff: false, expand: false, bar: false, handles: sel, name: name, text: text,
|
|
157
|
+
node: inset + 'background:' + bg + ';border:1px solid ' + border + ';box-shadow:' + shadow + ';border-radius:12px 12px 8px 8px;font-family:-apple-system,"SF Pro Text",system-ui,sans-serif;',
|
|
158
|
+
head: 'display:flex;align-items:center;gap:6px;height:28px;padding:0 8px;border-bottom:1px solid #1b2c44;background:' + headBg + ';',
|
|
159
|
+
icon: 'flex-shrink:0;color:#4BBCFF;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;',
|
|
160
|
+
title: 'flex:1;min-width:0;font-size:11px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#e6eef7;',
|
|
161
|
+
ctl: 'font-family:Arial,sans-serif;font-size:10px;letter-spacing:3px;color:#8ea3bd;', ctlText: '⤢⌄×',
|
|
162
|
+
body: 'padding:6px 8px;font-size:9.5px;line-height:1.45;color:#b9c6d6;',
|
|
163
|
+
hTL: handle('left:8px;top:8px;', '#e6eef7', '#4BBCFF'), hTR: handle('right:8px;top:8px;', '#e6eef7', '#4BBCFF'),
|
|
164
|
+
hBL: handle('left:8px;bottom:8px;', '#e6eef7', '#4BBCFF'), hBR: handle('right:8px;bottom:8px;', '#e6eef7', '#4BBCFF')
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function proposed(theme, state, name, text) {
|
|
168
|
+
var c = P[theme];
|
|
169
|
+
var pinned = state === 'pin' || state === 'pinagent' || state === 'pinsel';
|
|
170
|
+
var touched = state === 'agent' || state === 'pinagent';
|
|
171
|
+
var sel = state === 'sel' || state === 'pinsel';
|
|
172
|
+
var border = pinned ? '1.5px solid ' + c.accent : '1px solid ' + c.line;
|
|
173
|
+
var shadow = sel ? '0 0 0 3px ' + c.bg + ', 0 0 0 5px ' + c.accent + ', ' + c.e1 : c.e1;
|
|
174
|
+
return {
|
|
175
|
+
field: false, oldPin: false, pin: pinned, pinOff: !pinned, expand: true,
|
|
176
|
+
expandStyle: 'flex-shrink:0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:' + c.soft + ';',
|
|
177
|
+
pinOffStyle: 'flex-shrink:0;width:18px;height:18px;box-sizing:border-box;border-radius:999px;border:1.5px solid ' + c.muted + ';color:' + c.soft + ';display:flex;align-items:center;justify-content:center;', bar: touched, handles: sel, name: name, text: text,
|
|
178
|
+
node: inset + 'background:' + c.panel + ';border:' + border + ';box-shadow:' + shadow + ';border-radius:10px;font-family:"IBM Plex Sans",system-ui,sans-serif;',
|
|
179
|
+
head: 'display:flex;align-items:center;gap:6px;height:30px;padding:0 6px 0 10px;border-bottom:1px solid ' + c.line + ';background:' + (pinned ? c.accentA : 'transparent') + ';',
|
|
180
|
+
icon: 'flex-shrink:0;color:' + (pinned ? c.accent : c.muted) + ';fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;',
|
|
181
|
+
title: 'flex:1;min-width:0;font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:' + c.text + ';',
|
|
182
|
+
pinBadge: 'flex-shrink:0;width:18px;height:18px;border-radius:999px;display:flex;align-items:center;justify-content:center;background:' + c.accent + ';color:' + c.onAccent + ';',
|
|
183
|
+
ctl: 'display:none;', ctlText: '',
|
|
184
|
+
body: 'padding:7px 10px;font-size:11px;line-height:1.5;color:' + c.soft + ';',
|
|
185
|
+
barStyle: 'position:absolute;left:0;right:0;top:0;height:2.5px;background:' + c.attn + ';',
|
|
186
|
+
hTL: handle('left:3px;top:3px;', c.panel, c.accent), hTR: handle('right:3px;top:3px;', c.panel, c.accent),
|
|
187
|
+
hBL: handle('left:3px;bottom:3px;', c.panel, c.accent), hBR: handle('right:3px;bottom:3px;', c.panel, c.accent)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
var states = ['rest', 'pin', 'agent', 'pinagent', 'sel', 'pinsel'];
|
|
191
|
+
var stateNames = ['Resting', 'In context', 'Agent editing', 'In context + agent editing', 'Selected', 'In context + selected'];
|
|
192
|
+
var todayNotes = ['Plain — unless it sits next to a pin: then it gets an amber halo too', 'Amber ring, halo and glowing field — all from the pin', 'A faint blue sheen in the accent, the colour of a selection', 'The pin’s amber halo with the blue sheen', 'Blue ring', 'Blue ring is lost; only the handles show'];
|
|
193
|
+
var badNotes = { 0: true, 2: true, 5: true };
|
|
194
|
+
var newNotes = ['', 'Blue border, tinted header, pin badge — no halos, no field', 'Violet bar while the agent edits; read, created and edited marks follow in wave 1', 'Both signals, independently', 'Ring with a gap, plus handles', 'Pin styling stays inside the ring'];
|
|
195
|
+
var nm = 'Release runbook', tx = 'Pre-flight gates, tag → publish, smoke checklist.';
|
|
196
|
+
function rowOf(kind) {
|
|
197
|
+
return states.map(function (st, i) {
|
|
198
|
+
var cell = kind === 'today' ? today(st, nm, tx) : proposed(kind, st, nm, tx);
|
|
199
|
+
cell.note = kind === 'today' ? todayNotes[i] : (kind === 'dark' ? newNotes[i] : '');
|
|
200
|
+
cell.noteColor = kind === 'today' && badNotes[i] ? '#ff8a9b' : '#8ea3bd';
|
|
201
|
+
return cell;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
var rows = [
|
|
205
|
+
{ label: 'Today', sub: 'Harbor', bg: '#081524', cells: rowOf('today') },
|
|
206
|
+
{ label: 'Proposed', sub: 'Harbor', bg: '#081524', cells: rowOf('dark') },
|
|
207
|
+
{ label: 'Proposed', sub: 'Daylight', bg: '#F6F7F9', cells: rowOf('light') }
|
|
208
|
+
];
|
|
209
|
+
var pos = [[16, 24], [222, 24], [428, 24], [16, 150], [222, 150], [428, 150]];
|
|
210
|
+
var names = [
|
|
211
|
+
['Release runbook', 'Pre-flight gates, tag → publish.'],
|
|
212
|
+
['Decision ledger', '09:12 Ship 0.4.7 behind the smoke gate.'],
|
|
213
|
+
['Readability floor', '2 files · +2 −2'],
|
|
214
|
+
['Agent', 'Tooling · rebuilding the checklist.'],
|
|
215
|
+
['node-sizes.ts', 'export const NODE_MIN = …'],
|
|
216
|
+
['Sprint state', 'Review · 6 of 7 items merged']
|
|
217
|
+
];
|
|
218
|
+
var todayStates = ['pin', 'sec', 'pin', 'sec', 'rest', 'agent'];
|
|
219
|
+
var newStates = ['pin', 'rest', 'pin', 'rest', 'rest', 'agent'];
|
|
220
|
+
function scene(fn) {
|
|
221
|
+
return pos.map(function (p, i) {
|
|
222
|
+
var cell = fn(i);
|
|
223
|
+
cell.x = p[0]; cell.y = p[1];
|
|
224
|
+
return cell;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
var scenes = [
|
|
228
|
+
{ label: 'Today', bg: '#081524', dot: 'rgba(142,163,189,0.10)', caption: 'Runbook and Readability floor are pinned — but their unpinned neighbours glow amber too, and Sprint state, which the agent is editing, only gets a faint blue sheen.', captionColor: '#ff8a9b',
|
|
229
|
+
nodes: scene(function (i) { return today(todayStates[i], names[i][0], names[i][1]); }) },
|
|
230
|
+
{ label: 'Proposed', bg: '#081524', dot: 'rgba(142,163,189,0.14)', caption: 'Only the two pinned nodes carry the blue border and pin badge. Sprint state, which the agent is editing, has the violet bar.', captionColor: '#8ea3bd',
|
|
231
|
+
nodes: scene(function (i) { return proposed('dark', newStates[i], names[i][0], names[i][1]); }) }
|
|
232
|
+
];
|
|
233
|
+
var chips = ['Release runbook', 'PMX Canvas — guided tour', 'Readability floor', 'Working context'];
|
|
234
|
+
return { scenes: scenes, rows: rows, stateNames: stateNames, chips: chips };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
</script>
|
|
238
|
+
</body>
|
|
239
|
+
</html>
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Lineage, evidence and drill-in</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&family=IBM+Plex+Sans:wght@400;500;600&display=swap">
|
|
12
|
+
<style>
|
|
13
|
+
body{margin:0}
|
|
14
|
+
</style>
|
|
15
|
+
</helmet>
|
|
16
|
+
<div style="width: 1440px; height: 1280px; box-sizing: border-box; padding: 48px 56px; 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: 32px">
|
|
17
|
+
|
|
18
|
+
<div>
|
|
19
|
+
<h1 style="margin: 0; font-size: 28px; font-weight: 600; letter-spacing: -0.015em">Lineage, evidence and drill-in</h1>
|
|
20
|
+
<p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">The same relation layer for data work: where a number came from and whether it's still current, what a finding rests on, and a group of sources opened with its outside links kept.</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<section style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px">
|
|
24
|
+
|
|
25
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
26
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Today — lineage drawn by hand</span>
|
|
27
|
+
<div style="position: relative; width: 644px; height: 330px; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.10) 1px, transparent 1.2px); background-size: 24px 24px; font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif">
|
|
28
|
+
<svg width="644" height="330" viewBox="0 0 644 330" style="position: absolute; left: 0; top: 0; fill: none; stroke-linecap: round">
|
|
29
|
+
<path d="M 152 148 C 164 148, 164 148, 176 148" style="stroke: #4BBCFF; stroke-width: 1.5; opacity: 0.85"></path><path d="M 176 148 L 168 144.8 L 168 151.2 Z" style="fill: #4BBCFF; opacity: 0.75"></path>
|
|
30
|
+
<path d="M 308 148 C 320 148, 320 148, 332 148" style="stroke: #4BBCFF; stroke-width: 1.5; opacity: 0.85"></path><path d="M 332 148 L 324 144.8 L 324 151.2 Z" style="fill: #4BBCFF; opacity: 0.75"></path>
|
|
31
|
+
<path d="M 464 148 C 476 148, 476 148, 488 148" style="stroke: #4BBCFF; stroke-width: 1.5; opacity: 0.85"></path><path d="M 488 148 L 480 144.8 L 480 151.2 Z" style="fill: #4BBCFF; opacity: 0.75"></path>
|
|
32
|
+
</svg>
|
|
33
|
+
<sc-for list="{{oldSteps}}" as="st" hint-placeholder-count="4">
|
|
34
|
+
<div style="position: absolute; left: {{st.x}}px; top: 84px; width: 132px; height: 128px; box-sizing: border-box; border-radius: 12px 12px 8px 8px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 4px 24px rgba(0,0,0,0.3); overflow: hidden; display: flex; flex-direction: column">
|
|
35
|
+
<div style="height: 26px; padding: 0 8px; display: flex; align-items: center; gap: 4px; background: #0b1828; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; color: {{st.ic}}">{{st.glyph}}</span><span style="flex: 1; font-size: 10.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis">{{st.title}}</span></div>
|
|
36
|
+
<div style="padding: 6px 8px; font-size: 9px; color: #b9c6d6; flex: 1">{{st.body}}</div>
|
|
37
|
+
</div>
|
|
38
|
+
</sc-for>
|
|
39
|
+
<span style="position: absolute; left: 20px; top: 230px; font-size: 10px; color: #5c6b80">churn-raw.csv was replaced this morning.</span>
|
|
40
|
+
</div>
|
|
41
|
+
<span style="font-size: 12px; color: #ff8a9b">Blue “flow” links, the same as every other flow. When the raw export is replaced, the cleaned table, the chart and the finding all look current.</span>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
45
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed — lineage that knows it's stale</span>
|
|
46
|
+
<div style="position: relative; width: 644px; height: 330px; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 24px 24px">
|
|
47
|
+
<svg width="644" height="330" viewBox="0 0 644 330" style="position: absolute; left: 0; top: 0; fill: none; stroke-linecap: round; stroke-linejoin: round">
|
|
48
|
+
<path d="M 152 135 L 174 135" style="stroke: #f4c542; stroke-width: 2; stroke-dasharray: 5 4"></path><path d="M 178 135 L 169 130.5 L 169 139.5 Z" style="fill: #f4c542"></path>
|
|
49
|
+
<path d="M 308 135 L 330 135" style="stroke: #f4c542; stroke-width: 2; stroke-dasharray: 5 4"></path><path d="M 334 135 L 325 130.5 L 325 139.5 Z" style="fill: #f4c542"></path>
|
|
50
|
+
<path d="M 464 135 L 486 135" style="stroke: #f4c542; stroke-width: 2; stroke-dasharray: 5 4"></path><path d="M 490 135 L 481 130.5 L 481 139.5 Z" style="fill: #f4c542"></path>
|
|
51
|
+
<path d="M 400 190 L 400 246" style="stroke: #7C9CFF; stroke-width: 2"></path><path d="M 400 250 L 395.5 241 L 404.5 241 Z" style="fill: #7C9CFF"></path>
|
|
52
|
+
</svg>
|
|
53
|
+
<span style="position: absolute; left: 410px; top: 210px; font-size: 11px; color: #7C9CFF">cited by</span>
|
|
54
|
+
<div style="{{c.step}} left: 24px">
|
|
55
|
+
<div style="{{c.head}}"><svg width="14" height="14" viewBox="0 0 24 24" style="{{c.ic}}"><path d="M7 3.5h7l4 4V20.5H6V3.5zM14 3.5V8h4"></path></svg><span style="{{c.title}}">churn-raw.csv</span></div>
|
|
56
|
+
<div style="{{c.body}}">14,212 rows</div>
|
|
57
|
+
<div style="padding: 0 10px 8px"><span style="{{c.chip}} background: rgba(47,208,127,0.12); color: #2fd07f">updated 2h ago</span></div>
|
|
58
|
+
</div>
|
|
59
|
+
<div style="{{c.step}} left: 180px">
|
|
60
|
+
<div style="{{c.head}}"><svg width="14" height="14" viewBox="0 0 24 24" style="{{c.ic}}"><path d="M7 3.5h7l4 4V20.5H6V3.5zM14 3.5V8h4"></path></svg><span style="{{c.title}}">churn-clean.csv</span></div>
|
|
61
|
+
<div style="{{c.body}}">Trials and test accounts removed</div>
|
|
62
|
+
<div style="padding: 0 10px 8px"><span style="{{c.chip}} background: rgba(244,197,66,0.12); color: #f4c542">stale</span></div>
|
|
63
|
+
</div>
|
|
64
|
+
<div style="{{c.step}} left: 336px">
|
|
65
|
+
<div style="{{c.head}}"><svg width="14" height="14" viewBox="0 0 24 24" style="{{c.ic}}"><path d="M4 4v16h16M8 16v-4M12 16V8M16 16v-6"></path></svg><span style="{{c.title}}">Churn by plan</span></div>
|
|
66
|
+
<div style="{{c.body}}">bar · monthly, by plan</div>
|
|
67
|
+
<div style="padding: 0 10px 8px"><span style="{{c.chip}} background: rgba(244,197,66,0.12); color: #f4c542">stale</span></div>
|
|
68
|
+
</div>
|
|
69
|
+
<div style="{{c.step}} left: 492px">
|
|
70
|
+
<div style="{{c.head}}"><svg width="14" height="14" viewBox="0 0 24 24" style="{{c.ic}}"><path d="M6 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM8 10h8M8 14h5"></path></svg><span style="{{c.title}}">Churn flat after raise</span></div>
|
|
71
|
+
<div style="{{c.body}}">Finding · rests on a stale chart</div>
|
|
72
|
+
<div style="padding: 0 10px 8px"><span style="{{c.chip}} background: rgba(244,197,66,0.12); color: #f4c542">check</span></div>
|
|
73
|
+
</div>
|
|
74
|
+
<div style="position: absolute; left: 300px; top: 252px; width: 200px; height: 56px; box-sizing: border-box; padding: 8px 12px; border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; display: flex; flex-direction: column; justify-content: center"><span style="font-size: 12px; font-weight: 600">SMB is price-sensitive</span><span style="font-size: 11px; color: #8ea3bd">finding · also cites the chart</span></div>
|
|
75
|
+
<div style="position: absolute; left: 24px; top: 262px; display: flex; flex-direction: column; gap: 6px">
|
|
76
|
+
<span style="font-size: 11px; color: #f4c542">3 nodes downstream of a changed source</span>
|
|
77
|
+
<div style="display: flex; gap: 6px"><button style="{{c.btn}}">Show lineage</button><button style="{{c.btn}}">Ask agent to refresh</button></div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<span style="font-size: 12px; color: #8ea3bd">“Derived from” links know their direction. When a source changes, everything downstream turns amber (a real warning) until it's refreshed or confirmed.</span>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
</section>
|
|
84
|
+
|
|
85
|
+
<section style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px">
|
|
86
|
+
|
|
87
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
88
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed — what a finding rests on (new)</span>
|
|
89
|
+
<div style="position: relative; height: 560px; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background: rgba(4,10,18,0.9); display: flex">
|
|
90
|
+
<div style="flex: 1; padding: 20px; display: flex; flex-direction: column">
|
|
91
|
+
<div style="flex: 1; border-radius: 14px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 24px 64px rgba(0,0,0,0.5); display: flex; flex-direction: column; overflow: hidden">
|
|
92
|
+
<div style="height: 40px; padding: 0 14px; display: flex; align-items: center; gap: 8px; border-bottom: 1px solid #1b2c44"><span style="font-size: 15px; font-weight: 600; flex: 1">Churn flat after last raise</span><span style="font-size: 11px; color: #6b7d94">finding</span></div>
|
|
93
|
+
<div style="padding: 14px; color: #b9c6d6; font-size: 12px; line-height: 1.6">Pro churn was 2.1% in the three months before the 2024 raise and 2.2% after it. The effect is within normal month-to-month noise.</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<aside style="width: 300px; box-sizing: border-box; padding: 18px 16px; border-left: 1px solid #1b2c44; background: #0b1828; display: flex; flex-direction: column; gap: 12px; overflow: hidden">
|
|
97
|
+
<div style="display: flex; align-items: center; justify-content: space-between"><span style="font-size: 12px; font-weight: 600">Relations</span><button style="height: 24px; padding: 0 9px; border-radius: 6px; border: 1px solid #2a4566; background: #13243b; color: #e6eef7; font-family: inherit; font-size: 11px">Show on canvas</button></div>
|
|
98
|
+
<div style="display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; background: rgba(244,197,66,0.12); color: #f4c542; font-size: 11px; font-weight: 500"><svg width="13" height="13" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round"><path d="M12 4l9 16H3zM12 10v4M12 17v.5"></path></svg>Rests on a stale chart</div>
|
|
99
|
+
<sc-for list="{{groups}}" as="g" hint-placeholder-count="3">
|
|
100
|
+
<div>
|
|
101
|
+
<div style="{{c.sec}}">{{g.name}}</div>
|
|
102
|
+
<sc-for list="{{g.items}}" as="rel" hint-placeholder-count="2">
|
|
103
|
+
<div style="{{c.rel}}"><div style="display: flex; align-items: center; gap: 6px"><svg width="16" height="6" viewBox="0 0 16 6" style="flex-shrink: 0; fill: none; stroke: {{rel.c}}; stroke-width: 2; stroke-linecap: round"><path d="M1 3 H15"></path></svg><span style="font-size: 11px; color: {{rel.c}}">{{rel.type}}</span><span style="font-size: 12px; font-weight: 600; color: #e6eef7">{{rel.target}}</span></div><div style="font-size: 11px; color: #8ea3bd; padding-left: 22px">{{rel.why}}</div></div>
|
|
104
|
+
</sc-for>
|
|
105
|
+
</div>
|
|
106
|
+
</sc-for>
|
|
107
|
+
</aside>
|
|
108
|
+
</div>
|
|
109
|
+
<span style="font-size: 12px; color: #8ea3bd">In the expanded node: evidence for, evidence against, and what uses this finding, each with its reason. Pinning the finding can bring its evidence into the agent's context too.</span>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
113
|
+
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed — open a group of sources (new)</span>
|
|
114
|
+
<div style="position: relative; height: 560px; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 24px 24px">
|
|
115
|
+
<div style="position: absolute; left: 16px; top: 14px; display: flex; align-items: center; gap: 6px; font-size: 12px"><span style="color: #8ea3bd">Q4 pricing</span><span style="color: #3d5170">/</span><span style="font-weight: 600">Pricing research</span><span style="margin-left: 8px; font-family: 'IBM Plex Mono', monospace; font-size: 11px; padding: 0 6px; border-radius: 4px; border: 1px solid #1b2c44; color: #6b7d94">Esc</span><span style="font-size: 11px; color: #6b7d94">goes up</span></div>
|
|
116
|
+
<div style="position: absolute; left: 24px; top: 52px; width: 596px; height: 300px; box-sizing: border-box; border-radius: 14px; border: 1.5px dashed rgba(75,188,255,0.35); background: rgba(75,188,255,0.03)"></div>
|
|
117
|
+
<span style="position: absolute; left: 40px; top: 42px; height: 20px; padding: 0 9px; border-radius: 999px; background: #0f1d31; border: 1px solid rgba(75,188,255,0.35); font-size: 11px; font-weight: 600; line-height: 18px">Inside Pricing research</span>
|
|
118
|
+
<svg width="644" height="560" viewBox="0 0 644 560" style="position: absolute; left: 0; top: 0; fill: none; stroke-linecap: round; stroke-linejoin: round">
|
|
119
|
+
<path d="M 236 150 L 308 150" style="stroke: #7C9CFF; stroke-width: 2"></path><path d="M 312 150 L 303 145.5 L 303 154.5 Z" style="fill: #7C9CFF"></path>
|
|
120
|
+
<path d="M 400 186 L 400 228" style="stroke: #D5DEEA; stroke-width: 2"></path><path d="M 400 232 L 395.5 223 L 404.5 223 Z" style="fill: #D5DEEA"></path>
|
|
121
|
+
<path d="M 140 186 C 140 300, 120 340, 120 420" style="stroke: #5FCFC0; stroke-width: 2"></path><path d="M 120 424 L 115.5 415 L 124.5 415 Z" style="fill: #5FCFC0"></path>
|
|
122
|
+
<path d="M 450 306 C 450 372, 330 360, 330 420" style="stroke: #7C9CFF; stroke-width: 2"></path><path d="M 330 424 L 325.5 415 L 334.5 415 Z" style="fill: #7C9CFF"></path>
|
|
123
|
+
<path d="M 540 424 C 540 360, 560 330, 560 186" style="stroke: #E59B6B; stroke-width: 2"></path><path d="M 560 182 L 555.5 191 L 564.5 191 Z" style="fill: #E59B6B"></path>
|
|
124
|
+
</svg>
|
|
125
|
+
<div style="{{c.card}} left: 48px; top: 114px; width: 188px">Competitor pricing<span style="{{c.meta}}">webpage · 4 rivals</span></div>
|
|
126
|
+
<div style="{{c.card}} left: 312px; top: 114px; width: 176px">Price tiers<span style="{{c.meta}}">table · from the pages</span></div>
|
|
127
|
+
<div style="{{c.card}} left: 312px; top: 234px; width: 176px">Tier comparison<span style="{{c.meta}}">chart</span></div>
|
|
128
|
+
<div style="{{c.card}} left: 512px; top: 114px; width: 92px">Notes<span style="{{c.meta}}">markdown</span></div>
|
|
129
|
+
<span style="position: absolute; left: 24px; top: 392px; font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Outside</span>
|
|
130
|
+
<div style="{{c.ghost}} left: 40px; top: 426px">Raise Pro to $24?<span style="{{c.meta}}">question · ① Question</span></div>
|
|
131
|
+
<div style="{{c.ghost}} left: 250px; top: 426px">Decision memo<span style="{{c.meta}}">markdown · ④ Decision</span></div>
|
|
132
|
+
<div style="{{c.ghost}} left: 460px; top: 426px">SMB interviews<span style="{{c.meta}}">notes · ② Evidence</span></div>
|
|
133
|
+
</div>
|
|
134
|
+
<span style="font-size: 12px; color: #8ea3bd">Opening a group keeps its outside links: the question it supports, the memo that cites it, the interview notes that push back.</span>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
</section>
|
|
138
|
+
|
|
139
|
+
</div>
|
|
140
|
+
</x-dc>
|
|
141
|
+
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1280}}'>
|
|
142
|
+
class Component extends DCLogic {
|
|
143
|
+
renderVals() {
|
|
144
|
+
var c = {
|
|
145
|
+
step: 'position:absolute;top:80px;width:128px;height:110px;box-sizing:border-box;overflow:hidden;border-radius:10px;border:1px solid #1b2c44;background:#0f1d31;box-shadow:0 1px 2px rgba(0,0,0,0.4),0 6px 20px rgba(0,0,0,0.24);display:flex;flex-direction:column;',
|
|
146
|
+
head: 'display:flex;align-items:center;gap:6px;height:32px;padding:0 10px;border-bottom:1px solid #1b2c44;',
|
|
147
|
+
ic: 'flex-shrink:0;color:#8ea3bd;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;',
|
|
148
|
+
title: 'font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;',
|
|
149
|
+
body: 'padding:6px 10px;font-size:11px;line-height:1.45;color:#b9c6d6;flex:1;',
|
|
150
|
+
chip: 'font-size:11px;line-height:18px;padding:0 7px;border-radius:999px;font-weight:500;',
|
|
151
|
+
btn: 'height:24px;padding:0 9px;border-radius:6px;border:1px solid #2a4566;background:#13243b;color:#e6eef7;font-family:inherit;font-size:11px;font-weight:500;',
|
|
152
|
+
sec: 'font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:#6b7d94;margin-bottom:4px;',
|
|
153
|
+
rel: 'padding:7px 0;border-bottom:1px solid #1b2c44;display:flex;flex-direction:column;gap:2px;',
|
|
154
|
+
card: 'position:absolute;height:72px;box-sizing:border-box;padding:10px 12px;border-radius:10px;border:1px solid #1b2c44;background:#0f1d31;box-shadow:0 1px 2px rgba(0,0,0,0.4),0 6px 20px rgba(0,0,0,0.24);font-size:12px;font-weight:600;display:flex;flex-direction:column;gap:2px;',
|
|
155
|
+
ghost: 'position:absolute;width:170px;height:60px;box-sizing:border-box;padding:9px 12px;border-radius:10px;border:1.5px dashed #2a4566;background:rgba(15,29,49,0.5);font-size:12px;font-weight:600;color:#b9c6d6;display:flex;flex-direction:column;gap:2px;',
|
|
156
|
+
meta: 'font-size:11px;font-weight:400;color:#6b7d94;'
|
|
157
|
+
};
|
|
158
|
+
var oldSteps = [
|
|
159
|
+
{ x: 20, title: 'churn-raw.csv', body: '14,212 rows', glyph: '▯', ic: '#4BBCFF' },
|
|
160
|
+
{ x: 176, title: 'churn-clean.csv', body: 'Trials and test accounts removed', glyph: '▯', ic: '#4BBCFF' },
|
|
161
|
+
{ x: 332, title: 'Churn by plan', body: 'bar · monthly, by plan', glyph: '▥', ic: '#b07aff' },
|
|
162
|
+
{ x: 488, title: 'Churn flat after raise', body: 'Pro churn 2.1% → 2.2% after the 2024 raise.', glyph: '▤', ic: '#4BBCFF' }
|
|
163
|
+
];
|
|
164
|
+
var groups = [
|
|
165
|
+
{ name: 'Evidence for · 2', items: [
|
|
166
|
+
{ type: 'cites', c: '#7C9CFF', target: 'Churn by plan', why: 'Pro churn 2.1% before vs 2.2% after.' },
|
|
167
|
+
{ type: 'supports', c: '#5FCFC0', target: 'Competitor pricing', why: 'Rivals charge $25–29 for the same tier.' }
|
|
168
|
+
] },
|
|
169
|
+
{ name: 'Evidence against · 1', items: [
|
|
170
|
+
{ type: 'contradicts', c: '#E59B6B', target: 'SMB is price-sensitive', why: 'SMB churn rose 0.6 pts after the raise.' }
|
|
171
|
+
] },
|
|
172
|
+
{ name: 'Used by · 1', items: [
|
|
173
|
+
{ type: 'supports', c: '#5FCFC0', target: 'Raise Pro to $24?', why: 'The last raise did not move churn.' }
|
|
174
|
+
] }
|
|
175
|
+
];
|
|
176
|
+
return { c: c, oldSteps: oldSteps, groups: groups };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
</script>
|
|
180
|
+
</body>
|
|
181
|
+
</html>
|