pmx-canvas 0.6.4 → 0.7.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/extension.mjs +67 -3
- package/CHANGELOG.md +73 -0
- package/Readme.md +35 -5
- package/dist/canvas/global.css +498 -28
- package/dist/canvas/index.js +110 -95
- package/dist/canvas/mermaid-entry.js +258 -258
- package/dist/types/cli/agent.d.ts +4 -0
- package/dist/types/cli/commands/backup.d.ts +1 -0
- package/dist/types/cli/commands/boards.d.ts +1 -0
- package/dist/types/cli/commands/export.d.ts +1 -0
- package/dist/types/cli/commands/record.d.ts +12 -0
- package/dist/types/client/canvas/BoardCopyDialog.d.ts +5 -0
- package/dist/types/client/canvas/BoardFolderDialog.d.ts +7 -0
- package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -0
- package/dist/types/client/canvas/BoardSwitcher.d.ts +8 -0
- package/dist/types/client/canvas/ExportDialog.d.ts +7 -0
- package/dist/types/client/canvas/HomeView.d.ts +9 -0
- package/dist/types/client/canvas/Presentation.d.ts +13 -0
- package/dist/types/client/canvas/use-node-drag.d.ts +2 -1
- package/dist/types/client/nodes/AttachmentNode.d.ts +6 -0
- package/dist/types/client/nodes/BoardNode.d.ts +5 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +24 -1
- package/dist/types/client/state/boards-store.d.ts +79 -0
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/state/intent-bridge.d.ts +1 -0
- package/dist/types/client/state/presentation.d.ts +3 -0
- package/dist/types/client/state/session-store.d.ts +7 -0
- package/dist/types/client/types.d.ts +2 -2
- package/dist/types/json-render/catalog.d.ts +3 -3
- package/dist/types/json-render/charts/definitions.d.ts +1 -1
- package/dist/types/json-render/server.d.ts +8 -0
- package/dist/types/mcp/canvas-access.d.ts +10 -3
- package/dist/types/mcp/context-uri-template.d.ts +6 -0
- package/dist/types/server/agent-presence.d.ts +1 -1
- package/dist/types/server/attribution.d.ts +11 -0
- package/dist/types/server/ax-context.d.ts +3 -1
- package/dist/types/server/ax-interaction.d.ts +2 -2
- package/dist/types/server/ax-state.d.ts +13 -3
- package/dist/types/server/backup.d.ts +36 -0
- package/dist/types/server/board-export.d.ts +45 -0
- package/dist/types/server/canvas-db.d.ts +65 -9
- package/dist/types/server/canvas-operations.d.ts +45 -0
- package/dist/types/server/canvas-provenance.d.ts +1 -1
- package/dist/types/server/canvas-schema.d.ts +1 -0
- package/dist/types/server/canvas-state.d.ts +146 -3
- package/dist/types/server/canvas-validation.d.ts +3 -0
- package/dist/types/server/context-brief.d.ts +111 -0
- package/dist/types/server/context-reads.d.ts +55 -0
- package/dist/types/server/document-import.d.ts +66 -0
- package/dist/types/server/html-surface.d.ts +1 -1
- package/dist/types/server/index.d.ts +107 -4
- package/dist/types/server/mutation-history.d.ts +1 -0
- package/dist/types/server/operations/invoker.d.ts +2 -0
- package/dist/types/server/operations/mcp.d.ts +7 -1
- package/dist/types/server/operations/ops/app.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-shared.d.ts +2 -2
- package/dist/types/server/operations/ops/backup.d.ts +2 -0
- package/dist/types/server/operations/ops/boards.d.ts +10 -0
- package/dist/types/server/operations/ops/export.d.ts +2 -0
- package/dist/types/server/operations/ops/imports.d.ts +2 -0
- package/dist/types/server/operations/ops/json-render.d.ts +2 -0
- package/dist/types/server/operations/ops/nodes.d.ts +4 -2
- package/dist/types/server/operations/ops/query.d.ts +2 -0
- package/dist/types/server/operations/registry.d.ts +9 -1
- package/dist/types/server/operations/types.d.ts +1 -1
- package/dist/types/server/server.d.ts +1 -0
- package/dist/types/server/trace-manager.d.ts +7 -0
- package/dist/types/server/web-artifacts.d.ts +3 -0
- package/dist/types/server/webpage-node.d.ts +22 -1
- package/dist/types/server/workbench-auth.d.ts +3 -0
- package/dist/types/shared/boards.d.ts +6 -0
- package/dist/types/shared/tour.d.ts +72 -0
- package/docs/RELEASE.md +5 -0
- package/docs/cli.md +157 -0
- package/docs/http-api.md +277 -6
- package/docs/mcp.md +96 -7
- package/docs/node-types.md +106 -0
- package/docs/plans/plan-010-attributed-ask-answers.md +39 -0
- package/docs/plans/plan-011-context-read-instrumentation.md +54 -0
- package/docs/plans/plan-012-many-boards-stage-1.md +98 -0
- package/docs/plans/plan-013-static-board-export.md +47 -0
- package/docs/plans/plan-014-connected-board-memory.md +140 -0
- package/docs/product-vision-2026-09.md +118 -18
- package/docs/sdk.md +50 -0
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +62 -5
- package/skills/pmx-canvas/references/full-reference.md +44 -8
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +3 -0
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +4 -4
- package/skills/pmx-canvas-orchestration/SKILL.md +5 -0
- package/skills/pmx-canvas-testing/SKILL.md +4 -0
- package/src/cli/agent.ts +9 -0
- package/src/cli/commands/ax.ts +13 -0
- package/src/cli/commands/backup.ts +66 -0
- package/src/cli/commands/boards.ts +71 -0
- package/src/cli/commands/export.ts +30 -0
- package/src/cli/commands/nodes.ts +14 -1
- package/src/cli/commands/pins.ts +6 -2
- package/src/cli/commands/pump.ts +3 -0
- package/src/cli/commands/query.ts +33 -7
- package/src/cli/commands/record.ts +218 -0
- package/src/cli/commands/view.ts +7 -5
- package/src/cli/index.ts +21 -9
- package/src/client/App.tsx +28 -4
- package/src/client/canvas/AgentPresenceLayer.tsx +1 -1
- package/src/client/canvas/BoardCopyDialog.tsx +153 -0
- package/src/client/canvas/BoardFolderDialog.tsx +120 -0
- package/src/client/canvas/BoardLinkDialog.tsx +93 -0
- package/src/client/canvas/BoardSwitcher.tsx +149 -0
- package/src/client/canvas/CanvasNode.tsx +8 -0
- package/src/client/canvas/CanvasViewport.tsx +3 -0
- package/src/client/canvas/CommandPalette.tsx +107 -4
- package/src/client/canvas/ContextMenu.tsx +4 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +3 -0
- package/src/client/canvas/ExportDialog.tsx +197 -0
- package/src/client/canvas/HomeView.tsx +277 -0
- package/src/client/canvas/IntentLayer.tsx +9 -2
- package/src/client/canvas/Presentation.tsx +108 -0
- package/src/client/canvas/SessionPanel.tsx +28 -1
- package/src/client/canvas/ToolRail.tsx +38 -3
- package/src/client/canvas/TopBar.tsx +49 -7
- package/src/client/canvas/import-files.ts +19 -1
- package/src/client/canvas/kind-colors.ts +1 -0
- package/src/client/canvas/use-node-drag.ts +8 -3
- package/src/client/icons.tsx +2 -0
- package/src/client/mermaid-entry.ts +39 -0
- package/src/client/nodes/AttachmentNode.tsx +148 -0
- package/src/client/nodes/BoardNode.tsx +35 -0
- package/src/client/nodes/FileNode.tsx +6 -0
- package/src/client/nodes/HtmlNode.tsx +12 -13
- package/src/client/nodes/MarkdownNode.tsx +47 -19
- package/src/client/nodes/McpAppNode.tsx +105 -13
- package/src/client/nodes/MermaidNode.tsx +3 -2
- package/src/client/nodes/ax-node-actions.ts +2 -5
- package/src/client/nodes/use-ax-surface-bridge.ts +1 -1
- package/src/client/state/boards-store.ts +167 -0
- package/src/client/state/canvas-store.ts +22 -0
- package/src/client/state/intent-bridge.ts +30 -2
- package/src/client/state/intent-store.ts +5 -1
- package/src/client/state/node-factory.ts +1 -0
- package/src/client/state/presentation.ts +7 -0
- package/src/client/state/session-store.ts +8 -0
- package/src/client/state/sse-bridge.ts +52 -5
- package/src/client/theme/global.css +498 -28
- package/src/client/types.ts +2 -0
- package/src/json-render/server.ts +45 -9
- package/src/mcp/canvas-access.ts +59 -22
- package/src/mcp/context-uri-template.ts +28 -0
- package/src/mcp/server.ts +122 -15
- package/src/server/agent-context.ts +116 -29
- package/src/server/agent-presence.ts +15 -9
- package/src/server/attribution.ts +29 -0
- package/src/server/ax-context.ts +4 -2
- package/src/server/ax-interaction.ts +1 -0
- package/src/server/ax-state-manager.ts +72 -3
- package/src/server/ax-state.ts +41 -0
- package/src/server/backup.ts +178 -0
- package/src/server/board-export.ts +686 -0
- package/src/server/canvas-db.ts +612 -105
- package/src/server/canvas-operations.ts +183 -31
- package/src/server/canvas-provenance.ts +1 -0
- package/src/server/canvas-schema.ts +22 -0
- package/src/server/canvas-state.ts +812 -48
- package/src/server/canvas-validation.ts +9 -1
- package/src/server/context-brief.ts +372 -0
- package/src/server/context-reads.ts +238 -0
- package/src/server/demo-state.json +670 -9
- package/src/server/document-import.ts +223 -0
- package/src/server/html-primitives.ts +199 -91
- package/src/server/html-surface.ts +8 -3
- package/src/server/index.ts +243 -5
- package/src/server/mutation-history.ts +10 -13
- package/src/server/operations/composites.ts +29 -5
- package/src/server/operations/http.ts +9 -3
- package/src/server/operations/index.ts +8 -0
- package/src/server/operations/invoker.ts +14 -3
- package/src/server/operations/mcp.ts +50 -11
- package/src/server/operations/ops/app.ts +15 -0
- package/src/server/operations/ops/ax-read.ts +10 -6
- package/src/server/operations/ops/ax-timeline.ts +75 -0
- package/src/server/operations/ops/backup.ts +134 -0
- package/src/server/operations/ops/batch.ts +20 -4
- package/src/server/operations/ops/boards.ts +351 -0
- package/src/server/operations/ops/export.ts +74 -0
- package/src/server/operations/ops/ext-app.ts +4 -0
- package/src/server/operations/ops/groups.ts +14 -7
- package/src/server/operations/ops/imports.ts +220 -0
- package/src/server/operations/ops/json-render.ts +37 -5
- package/src/server/operations/ops/nodes.ts +99 -21
- package/src/server/operations/ops/query.ts +206 -9
- package/src/server/operations/ops/viewport.ts +32 -0
- package/src/server/operations/registry.ts +129 -31
- package/src/server/operations/types.ts +1 -1
- package/src/server/scope-fence.ts +1 -1
- package/src/server/server.ts +155 -8
- package/src/server/spatial-analysis.ts +9 -17
- package/src/server/trace-manager.ts +19 -0
- package/src/server/web-artifacts.ts +11 -3
- package/src/server/webpage-node.ts +173 -13
- package/src/server/workbench-auth.ts +11 -0
- package/src/server/workboard.ts +3 -3
- package/src/shared/boards.ts +18 -0
- package/src/shared/node-sizes.ts +1 -0
- package/src/shared/tour.ts +87 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { findOpenCanvasPosition } from '../utils/placement.js';
|
|
2
|
+
import { ownsCamera } from './presentation';
|
|
2
3
|
import { normalizeExtAppToolResult } from '../utils/ext-app-tool-result.js';
|
|
3
4
|
import type { CanvasAnnotation, CanvasEdge, CanvasNodeState } from '../types';
|
|
4
5
|
import {
|
|
@@ -26,10 +27,13 @@ import {
|
|
|
26
27
|
workbenchConnectionEpoch,
|
|
27
28
|
reconnectAttempt,
|
|
28
29
|
reconnectDelay,
|
|
30
|
+
resetCanvasInteractionState,
|
|
29
31
|
} from './canvas-store';
|
|
32
|
+
import { applyBoards, loadBoards, setBoardSwitchHandler } from './boards-store';
|
|
30
33
|
import {
|
|
31
34
|
fetchAgentPresence,
|
|
32
35
|
fetchAxSurfaceState,
|
|
36
|
+
fetchCanvasState,
|
|
33
37
|
reportClientViewportSize,
|
|
34
38
|
requestJson,
|
|
35
39
|
tabAgentKey,
|
|
@@ -303,6 +307,7 @@ function isCanvasNodeType(value: unknown): value is CanvasNodeState['type'] {
|
|
|
303
307
|
value === 'webpage' ||
|
|
304
308
|
value === 'json-render' ||
|
|
305
309
|
value === 'graph' ||
|
|
310
|
+
value === 'board' ||
|
|
306
311
|
value === 'prompt' ||
|
|
307
312
|
value === 'response' ||
|
|
308
313
|
value === 'status' ||
|
|
@@ -455,14 +460,44 @@ function handleAgentSessionEnded(data: Record<string, unknown>): void {
|
|
|
455
460
|
}
|
|
456
461
|
|
|
457
462
|
let stopHumanPresence: (() => void) | null = null;
|
|
463
|
+
let boardResyncGeneration = 0;
|
|
464
|
+
let layoutRevision = 0;
|
|
465
|
+
let pinsRevision = 0;
|
|
458
466
|
|
|
459
467
|
function handleHumanPresence(data: Record<string, unknown>): void {
|
|
460
468
|
applyHumanSnapshot(data as Partial<HumanPresenceSnapshot>);
|
|
461
469
|
}
|
|
462
470
|
|
|
471
|
+
/**
|
|
472
|
+
* The open board changed (this tab, another tab, or a restart): the canvas is
|
|
473
|
+
* a different board now, so take its layout like a fresh connection would —
|
|
474
|
+
* camera included — and drop what belonged to the old board.
|
|
475
|
+
*/
|
|
476
|
+
function resyncForBoardSwitch(): void {
|
|
477
|
+
const generation = ++boardResyncGeneration;
|
|
478
|
+
savedLayout = null;
|
|
479
|
+
hasInitialServerLayout.value = false;
|
|
480
|
+
resetIntents();
|
|
481
|
+
resetCanvasInteractionState();
|
|
482
|
+
axSurfaceState.value = null;
|
|
483
|
+
void refreshAxSurface();
|
|
484
|
+
const layoutAtRequest = layoutRevision;
|
|
485
|
+
const pinsAtRequest = pinsRevision;
|
|
486
|
+
void fetchCanvasState().then((layout) => {
|
|
487
|
+
if (generation === boardResyncGeneration && layoutAtRequest === layoutRevision)
|
|
488
|
+
handleCanvasLayoutUpdate({ layout });
|
|
489
|
+
});
|
|
490
|
+
void requestJson<{ nodeIds?: unknown }>('fetchPinnedContext', '/api/canvas/pinned-context', {}).then((data) => {
|
|
491
|
+
if (generation === boardResyncGeneration && pinsAtRequest === pinsRevision)
|
|
492
|
+
handleContextPinsChanged({ nodeIds: data.nodeIds });
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
setBoardSwitchHandler(resyncForBoardSwitch);
|
|
496
|
+
|
|
463
497
|
function handleConnected(data: Record<string, unknown>): void {
|
|
464
498
|
sessionId.value = (data.sessionId as string) || '';
|
|
465
499
|
connectionStatus.value = 'connected';
|
|
500
|
+
void loadBoards();
|
|
466
501
|
// Reconnect marker for holders of server-minted URLs (Finding S).
|
|
467
502
|
workbenchConnectionEpoch.value += 1;
|
|
468
503
|
reloadIfServerUpgraded(data.version, data.bundleStamp);
|
|
@@ -485,8 +520,7 @@ function handleConnected(data: Record<string, unknown>): void {
|
|
|
485
520
|
// The AX surface snapshot (work items, gates) likewise — it used to arrive
|
|
486
521
|
// only on the first ax-state-changed, so a fresh load showed an empty
|
|
487
522
|
// session panel while persisted work items existed.
|
|
488
|
-
void
|
|
489
|
-
axSurfaceState.value = state;
|
|
523
|
+
void refreshAxSurface().then(() => {
|
|
490
524
|
if (sessionActive.value) void refreshTimeline();
|
|
491
525
|
});
|
|
492
526
|
// A ?theme= session override (host-default theming) wins over the
|
|
@@ -902,6 +936,7 @@ function handleCanvasLayoutUpdate(data: Record<string, unknown>): void {
|
|
|
902
936
|
}
|
|
903
937
|
| undefined;
|
|
904
938
|
if (!layout?.nodes) return;
|
|
939
|
+
layoutRevision += 1;
|
|
905
940
|
const shouldApplyViewport = !hasInitialServerLayout.value;
|
|
906
941
|
hasInitialServerLayout.value = true;
|
|
907
942
|
|
|
@@ -945,6 +980,7 @@ function reconnectDelayMs(attempt: number): number {
|
|
|
945
980
|
}
|
|
946
981
|
|
|
947
982
|
function handleCanvasFocusNode(data: Record<string, unknown>): void {
|
|
983
|
+
if (ownsCamera()) return;
|
|
948
984
|
const nodeId = data.nodeId as string;
|
|
949
985
|
if (nodeId && nodes.value.has(nodeId)) {
|
|
950
986
|
if (data.noPan === true) {
|
|
@@ -956,6 +992,7 @@ function handleCanvasFocusNode(data: Record<string, unknown>): void {
|
|
|
956
992
|
}
|
|
957
993
|
|
|
958
994
|
function handleCanvasViewportUpdate(data: Record<string, unknown>): void {
|
|
995
|
+
if (ownsCamera()) return;
|
|
959
996
|
const viewport = data.viewport as Record<string, unknown> | undefined;
|
|
960
997
|
if (!viewport) return;
|
|
961
998
|
const x = typeof viewport.x === 'number' ? viewport.x : 0;
|
|
@@ -990,6 +1027,7 @@ function handleThemeChanged(data: Record<string, unknown>): void {
|
|
|
990
1027
|
}
|
|
991
1028
|
|
|
992
1029
|
function handleContextPinsChanged(data: Record<string, unknown>): void {
|
|
1030
|
+
pinsRevision += 1;
|
|
993
1031
|
const nodeIds = Array.isArray(data.nodeIds) ? data.nodeIds.filter((id): id is string => typeof id === 'string') : [];
|
|
994
1032
|
replaceContextPinsFromServer(nodeIds);
|
|
995
1033
|
syncAttentionFromSse({ event: 'context-pins-changed', data });
|
|
@@ -1000,13 +1038,21 @@ function handleContextPinsChanged(data: Record<string, unknown>): void {
|
|
|
1000
1038
|
// (debounced). The snapshot feeds AX-enabled surfaces (HtmlNode/McpAppNode push it
|
|
1001
1039
|
// into their iframes), so authored boards reflect the live work queue / focus.
|
|
1002
1040
|
let axRefreshTimer: ReturnType<typeof setTimeout> | null = null;
|
|
1041
|
+
let axRefreshSequence = 0;
|
|
1042
|
+
async function refreshAxSurface(): Promise<void> {
|
|
1043
|
+
const sequence = ++axRefreshSequence;
|
|
1044
|
+
const generation = boardResyncGeneration;
|
|
1045
|
+
const state = await fetchAxSurfaceState();
|
|
1046
|
+
if (sequence === axRefreshSequence && generation === boardResyncGeneration) axSurfaceState.value = state;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1003
1049
|
function handleAxStateChanged(): void {
|
|
1004
1050
|
if (axRefreshTimer) clearTimeout(axRefreshTimer);
|
|
1051
|
+
// Invalidate any in-flight read before the debounced replacement starts.
|
|
1052
|
+
axRefreshSequence += 1;
|
|
1005
1053
|
axRefreshTimer = setTimeout(() => {
|
|
1006
1054
|
axRefreshTimer = null;
|
|
1007
|
-
void
|
|
1008
|
-
axSurfaceState.value = state;
|
|
1009
|
-
});
|
|
1055
|
+
void refreshAxSurface();
|
|
1010
1056
|
// The session panel's timeline — only worth fetching while it is mounted.
|
|
1011
1057
|
if (sessionActive.value) void refreshTimeline();
|
|
1012
1058
|
}, 150);
|
|
@@ -1061,6 +1107,7 @@ export const EVENT_HANDLERS: Record<string, (data: Record<string, unknown>) => v
|
|
|
1061
1107
|
'ext-app-update': handleExtAppUpdate,
|
|
1062
1108
|
'ext-app-result': handleExtAppResult,
|
|
1063
1109
|
'context-pins-changed': handleContextPinsChanged,
|
|
1110
|
+
'boards-changed': applyBoards,
|
|
1064
1111
|
'canvas-layout-update': handleCanvasLayoutUpdate,
|
|
1065
1112
|
'canvas-focus-node': handleCanvasFocusNode,
|
|
1066
1113
|
'canvas-viewport-update': handleCanvasViewportUpdate,
|
|
@@ -60,6 +60,26 @@
|
|
|
60
60
|
--hud-bar-height: 44px;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
.board-node, .md-card-preview { display: flex; flex-direction: column; height: 100%; min-height: 0; }
|
|
64
|
+
.board-node-content { flex: 1; min-height: 0; overflow: auto; padding: 16px; overflow-wrap: anywhere; }
|
|
65
|
+
.board-node-label { color: var(--c-dim); font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; margin-bottom: 8px; }
|
|
66
|
+
.board-node-title { display: block; font-size: 17px; line-height: 1.35; margin-bottom: 6px; }
|
|
67
|
+
.board-node-meta { color: var(--c-dim); font-size: 11px; line-height: 1.5; }
|
|
68
|
+
.board-node-summary { color: var(--c-text-soft); font-size: 13px; line-height: 1.6; margin: 14px 0; }
|
|
69
|
+
.board-node-open { display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; width: 100%; padding: 10px 16px; border: 0; border-top: 1px solid var(--c-line); background: var(--c-panel); color: var(--c-accent); font: 500 12px var(--font); text-align: left; cursor: pointer; }
|
|
70
|
+
.board-node-open:hover:not(:disabled) { background: var(--c-accent-8); }
|
|
71
|
+
.board-node-open:disabled { color: var(--c-dim); cursor: default; }
|
|
72
|
+
.md-card-content { flex: 1; min-height: 0; overflow: auto; }
|
|
73
|
+
.md-card-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; border-top: 1px solid var(--c-line); padding: 6px 36px 6px 8px; background: var(--c-panel); }
|
|
74
|
+
.md-card-actions button { border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--c-dim); padding: 4px 8px; font: 500 11px var(--font); cursor: pointer; }
|
|
75
|
+
.md-card-actions button:hover { color: var(--c-text); background: var(--c-accent-8); }
|
|
76
|
+
.md-card-actions .md-readme-btn[aria-pressed="true"] { color: var(--c-accent); background: var(--c-accent-8); border-color: var(--c-accent-25); }
|
|
77
|
+
.md-card-edit { margin-left: auto; }
|
|
78
|
+
.board-node-open:focus-visible, .md-card-actions button:focus-visible { outline: 2px solid var(--c-accent); outline-offset: -2px; }
|
|
79
|
+
.canvas-node[data-node-type="markdown"] .node-body,
|
|
80
|
+
.canvas-node[data-node-type="board"] .node-body { padding: 0; }
|
|
81
|
+
.md-card-content { padding: 10px 14px; }
|
|
82
|
+
|
|
63
83
|
:root[data-theme="light"] {
|
|
64
84
|
/* ── Core palette (light · paper + ink) ──────────────────── */
|
|
65
85
|
--c-bg: #F4EFE6;
|
|
@@ -1210,13 +1230,13 @@ body,
|
|
|
1210
1230
|
font-size: 9px;
|
|
1211
1231
|
padding: 1px 6px;
|
|
1212
1232
|
}
|
|
1213
|
-
/*
|
|
1233
|
+
/* Parked idle cursors leave the board (user feedback, 0.5.1 cycle): with many agents
|
|
1214
1234
|
attached, a wall of parked "Idle" pills covers real node content. The
|
|
1215
1235
|
element stays MOUNTED — counts, twin-merge, and cursor-follow logic are
|
|
1216
1236
|
untouched, and visibility (not display) keeps its layout box so position
|
|
1217
|
-
polls still resolve — but it paints nothing
|
|
1218
|
-
|
|
1219
|
-
.agent-cursor.phase-idle {
|
|
1237
|
+
polls still resolve — but it paints nothing. An explicitly reported cursor
|
|
1238
|
+
remains visible even while idle so cursor-only movement cannot disappear. */
|
|
1239
|
+
.agent-cursor.phase-idle:not(.has-explicit-cursor) {
|
|
1220
1240
|
opacity: 0;
|
|
1221
1241
|
visibility: hidden;
|
|
1222
1242
|
transition:
|
|
@@ -1251,7 +1271,7 @@ body,
|
|
|
1251
1271
|
}
|
|
1252
1272
|
|
|
1253
1273
|
.agent-chip-end:hover {
|
|
1254
|
-
color: var(--c-danger
|
|
1274
|
+
color: var(--c-danger);
|
|
1255
1275
|
background: color-mix(in srgb, currentColor 12%, transparent);
|
|
1256
1276
|
}
|
|
1257
1277
|
|
|
@@ -3317,29 +3337,6 @@ body,
|
|
|
3317
3337
|
}
|
|
3318
3338
|
|
|
3319
3339
|
/* Raw markdown source editor */
|
|
3320
|
-
.md-edit-btn {
|
|
3321
|
-
position: absolute;
|
|
3322
|
-
top: 4px;
|
|
3323
|
-
right: 4px;
|
|
3324
|
-
padding: 3px 8px;
|
|
3325
|
-
font-size: 10px;
|
|
3326
|
-
background: var(--c-panel);
|
|
3327
|
-
border: 1px solid var(--c-line);
|
|
3328
|
-
border-radius: 4px;
|
|
3329
|
-
color: var(--c-text-soft);
|
|
3330
|
-
cursor: pointer;
|
|
3331
|
-
opacity: 0;
|
|
3332
|
-
transition: opacity 0.12s ease;
|
|
3333
|
-
}
|
|
3334
|
-
.canvas-node:hover .md-edit-btn,
|
|
3335
|
-
.md-edit-btn:focus-visible {
|
|
3336
|
-
opacity: 1;
|
|
3337
|
-
}
|
|
3338
|
-
.md-edit-btn:hover {
|
|
3339
|
-
color: var(--c-text);
|
|
3340
|
-
border-color: var(--c-accent-25);
|
|
3341
|
-
}
|
|
3342
|
-
|
|
3343
3340
|
.md-editor-split {
|
|
3344
3341
|
display: flex;
|
|
3345
3342
|
height: 100%;
|
|
@@ -4211,6 +4208,33 @@ html.is-node-resizing .ext-app-preview-catcher {
|
|
|
4211
4208
|
}
|
|
4212
4209
|
|
|
4213
4210
|
/* MCP app iframe */
|
|
4211
|
+
.mcp-app-frame-stack {
|
|
4212
|
+
position: relative;
|
|
4213
|
+
flex: 1;
|
|
4214
|
+
min-width: 0;
|
|
4215
|
+
min-height: 0;
|
|
4216
|
+
background: var(--c-panel-soft);
|
|
4217
|
+
overflow: hidden;
|
|
4218
|
+
border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px);
|
|
4219
|
+
}
|
|
4220
|
+
|
|
4221
|
+
.mcp-app-frame-stack:has(.html-node-frame) {
|
|
4222
|
+
width: 100%;
|
|
4223
|
+
height: 100%;
|
|
4224
|
+
min-height: 300px;
|
|
4225
|
+
background: var(--c-bg);
|
|
4226
|
+
border-radius: 6px;
|
|
4227
|
+
}
|
|
4228
|
+
|
|
4229
|
+
.mcp-app-frame-stack:has(.html-node-frame-presentation) {
|
|
4230
|
+
min-height: 0;
|
|
4231
|
+
border-radius: 0;
|
|
4232
|
+
}
|
|
4233
|
+
|
|
4234
|
+
.mcp-app-frame-stack:has(.html-node-frame-expanded) {
|
|
4235
|
+
min-height: 70vh;
|
|
4236
|
+
}
|
|
4237
|
+
|
|
4214
4238
|
.mcp-app-frame {
|
|
4215
4239
|
width: 100%;
|
|
4216
4240
|
height: 100%;
|
|
@@ -6808,3 +6832,449 @@ html.is-node-dragging .intent-ghost,
|
|
|
6808
6832
|
html.is-node-dragging .intent-line-layer {
|
|
6809
6833
|
opacity: 0.5;
|
|
6810
6834
|
}
|
|
6835
|
+
|
|
6836
|
+
.present-button {
|
|
6837
|
+
color: var(--c-text);
|
|
6838
|
+
background: var(--c-bg);
|
|
6839
|
+
border: 1px solid var(--c-line);
|
|
6840
|
+
border-radius: 6px;
|
|
6841
|
+
padding: 4px 12px;
|
|
6842
|
+
cursor: pointer;
|
|
6843
|
+
}
|
|
6844
|
+
.is-presenting > :not(.app-main):not(.presentation-error),
|
|
6845
|
+
.is-presenting .app-main > :not(.canvas-region),
|
|
6846
|
+
.is-presenting .canvas-region > :not(.canvas-viewport) {
|
|
6847
|
+
display: none !important;
|
|
6848
|
+
}
|
|
6849
|
+
.is-presenting .canvas-viewport { pointer-events: none; }
|
|
6850
|
+
.presentation-error {
|
|
6851
|
+
position: fixed;
|
|
6852
|
+
bottom: 16px;
|
|
6853
|
+
left: 16px;
|
|
6854
|
+
z-index: 100;
|
|
6855
|
+
max-width: calc(100% - 32px);
|
|
6856
|
+
padding: 10px 16px;
|
|
6857
|
+
border: 1px solid var(--c-line);
|
|
6858
|
+
border-radius: 6px;
|
|
6859
|
+
background: var(--c-panel);
|
|
6860
|
+
color: var(--c-text);
|
|
6861
|
+
}
|
|
6862
|
+
|
|
6863
|
+
/* ── Many boards (plan 012): top-bar switcher + Home ── */
|
|
6864
|
+
.board-switcher {
|
|
6865
|
+
display: inline-flex;
|
|
6866
|
+
/* The board name is the bar's identity: it keeps room for a short name
|
|
6867
|
+
("Home") when chips crowd a 600px pane; long names still ellipsize. */
|
|
6868
|
+
min-width: 88px;
|
|
6869
|
+
flex-shrink: 1;
|
|
6870
|
+
}
|
|
6871
|
+
.board-switcher-button {
|
|
6872
|
+
display: inline-flex;
|
|
6873
|
+
align-items: center;
|
|
6874
|
+
gap: 6px;
|
|
6875
|
+
max-width: 280px;
|
|
6876
|
+
padding: 4px 8px;
|
|
6877
|
+
margin-left: -8px;
|
|
6878
|
+
background: none;
|
|
6879
|
+
border: 1px solid transparent;
|
|
6880
|
+
border-radius: 8px;
|
|
6881
|
+
cursor: pointer;
|
|
6882
|
+
}
|
|
6883
|
+
.board-switcher-button:hover,
|
|
6884
|
+
.board-switcher-button[aria-expanded='true'] {
|
|
6885
|
+
border-color: var(--c-line);
|
|
6886
|
+
background: var(--c-panel);
|
|
6887
|
+
}
|
|
6888
|
+
.board-switcher-name {
|
|
6889
|
+
overflow: hidden;
|
|
6890
|
+
text-overflow: ellipsis;
|
|
6891
|
+
white-space: nowrap;
|
|
6892
|
+
}
|
|
6893
|
+
.board-switcher-caret {
|
|
6894
|
+
font-size: 10px;
|
|
6895
|
+
color: var(--c-text-soft);
|
|
6896
|
+
}
|
|
6897
|
+
.board-switcher-menu {
|
|
6898
|
+
width: min(340px, calc(100vw - 24px));
|
|
6899
|
+
min-width: 0;
|
|
6900
|
+
padding: 8px;
|
|
6901
|
+
background: var(--c-panel);
|
|
6902
|
+
backdrop-filter: none;
|
|
6903
|
+
overflow: hidden;
|
|
6904
|
+
}
|
|
6905
|
+
.board-switcher-heading {
|
|
6906
|
+
padding: 8px 10px 10px;
|
|
6907
|
+
font-size: 11px;
|
|
6908
|
+
font-weight: 600;
|
|
6909
|
+
color: var(--c-dim);
|
|
6910
|
+
text-transform: uppercase;
|
|
6911
|
+
letter-spacing: 0.08em;
|
|
6912
|
+
flex-shrink: 0;
|
|
6913
|
+
}
|
|
6914
|
+
.board-switcher-recents { min-height: 0; overflow-y: auto; }
|
|
6915
|
+
.board-switcher-menu .toolbar-menu-item { padding: 10px; gap: 12px; }
|
|
6916
|
+
.board-switcher-menu .toolbar-menu-item:hover,
|
|
6917
|
+
.board-switcher-menu .toolbar-menu-item:focus-visible {
|
|
6918
|
+
background: var(--c-accent-8);
|
|
6919
|
+
border-color: var(--c-accent-25);
|
|
6920
|
+
outline: none;
|
|
6921
|
+
}
|
|
6922
|
+
.board-switcher-icon { display: flex; align-items: center; justify-content: center; width: 20px; flex-shrink: 0; color: var(--c-accent); font-size: 22px; }
|
|
6923
|
+
.board-switcher-item-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
|
|
6924
|
+
.board-switcher-item-name {
|
|
6925
|
+
color: var(--c-text);
|
|
6926
|
+
font-weight: 500;
|
|
6927
|
+
line-height: 1.35;
|
|
6928
|
+
overflow-wrap: anywhere;
|
|
6929
|
+
text-align: left;
|
|
6930
|
+
}
|
|
6931
|
+
.board-switcher-item-folder { font-size: 11px; line-height: 1.4; color: var(--c-dim); overflow-wrap: anywhere; }
|
|
6932
|
+
.board-switcher-item-meta {
|
|
6933
|
+
font-size: 10px;
|
|
6934
|
+
color: var(--c-dim);
|
|
6935
|
+
white-space: nowrap;
|
|
6936
|
+
align-self: flex-start;
|
|
6937
|
+
padding-top: 2px;
|
|
6938
|
+
}
|
|
6939
|
+
.board-switcher-actions { border-top: 1px solid var(--c-line); margin-top: 6px; padding-top: 6px; flex-shrink: 0; }
|
|
6940
|
+
|
|
6941
|
+
.home-view {
|
|
6942
|
+
position: absolute;
|
|
6943
|
+
inset: 0;
|
|
6944
|
+
/* Above the canvas's floating chrome (the updates tab sits at 60), below menus and prompts. */
|
|
6945
|
+
z-index: 70;
|
|
6946
|
+
overflow-y: auto;
|
|
6947
|
+
background: var(--c-bg);
|
|
6948
|
+
padding: 32px 16px;
|
|
6949
|
+
}
|
|
6950
|
+
.home-view-inner {
|
|
6951
|
+
max-width: 720px;
|
|
6952
|
+
margin: 0 auto;
|
|
6953
|
+
display: flex;
|
|
6954
|
+
flex-direction: column;
|
|
6955
|
+
gap: 18px;
|
|
6956
|
+
}
|
|
6957
|
+
.home-view-head {
|
|
6958
|
+
display: flex;
|
|
6959
|
+
align-items: center;
|
|
6960
|
+
justify-content: space-between;
|
|
6961
|
+
gap: 12px;
|
|
6962
|
+
}
|
|
6963
|
+
.home-view-title {
|
|
6964
|
+
margin: 0;
|
|
6965
|
+
font-size: 20px;
|
|
6966
|
+
font-weight: 650;
|
|
6967
|
+
color: var(--c-text);
|
|
6968
|
+
}
|
|
6969
|
+
.home-view-new {
|
|
6970
|
+
padding: 7px 14px;
|
|
6971
|
+
border-radius: 8px;
|
|
6972
|
+
border: 1px solid var(--c-accent);
|
|
6973
|
+
background: var(--c-accent);
|
|
6974
|
+
color: var(--c-bg);
|
|
6975
|
+
font-weight: 600;
|
|
6976
|
+
cursor: pointer;
|
|
6977
|
+
}
|
|
6978
|
+
.home-view-empty {
|
|
6979
|
+
color: var(--c-text-soft);
|
|
6980
|
+
font-size: 13px;
|
|
6981
|
+
}
|
|
6982
|
+
.home-view-list {
|
|
6983
|
+
list-style: none;
|
|
6984
|
+
margin: 0;
|
|
6985
|
+
padding: 0;
|
|
6986
|
+
display: flex;
|
|
6987
|
+
flex-direction: column;
|
|
6988
|
+
gap: 7px;
|
|
6989
|
+
}
|
|
6990
|
+
.home-board {
|
|
6991
|
+
display: flex;
|
|
6992
|
+
align-items: center;
|
|
6993
|
+
gap: 8px;
|
|
6994
|
+
padding: 7px 8px 7px 5px;
|
|
6995
|
+
border: 1px solid var(--c-line);
|
|
6996
|
+
border-radius: 10px;
|
|
6997
|
+
background: var(--c-panel);
|
|
6998
|
+
}
|
|
6999
|
+
.home-board.is-confirming {
|
|
7000
|
+
border-color: var(--c-danger);
|
|
7001
|
+
padding: 10px 12px;
|
|
7002
|
+
flex-wrap: wrap;
|
|
7003
|
+
}
|
|
7004
|
+
.home-board-open {
|
|
7005
|
+
flex: 1;
|
|
7006
|
+
min-width: 0;
|
|
7007
|
+
display: flex;
|
|
7008
|
+
flex-direction: column;
|
|
7009
|
+
align-items: flex-start;
|
|
7010
|
+
gap: 2px;
|
|
7011
|
+
padding: 6px 8px;
|
|
7012
|
+
background: none;
|
|
7013
|
+
border: none;
|
|
7014
|
+
border-radius: 8px;
|
|
7015
|
+
color: var(--c-text);
|
|
7016
|
+
cursor: pointer;
|
|
7017
|
+
text-align: left;
|
|
7018
|
+
}
|
|
7019
|
+
.home-board-open:hover {
|
|
7020
|
+
background: color-mix(in srgb, var(--c-accent) 10%, transparent);
|
|
7021
|
+
}
|
|
7022
|
+
.home-board-name {
|
|
7023
|
+
max-width: 100%;
|
|
7024
|
+
font-size: 14px;
|
|
7025
|
+
font-weight: 600;
|
|
7026
|
+
overflow: hidden;
|
|
7027
|
+
text-overflow: ellipsis;
|
|
7028
|
+
white-space: nowrap;
|
|
7029
|
+
}
|
|
7030
|
+
.home-board-meta {
|
|
7031
|
+
font: 11px var(--mono);
|
|
7032
|
+
color: var(--c-text-soft);
|
|
7033
|
+
}
|
|
7034
|
+
.home-board-confirm-text {
|
|
7035
|
+
flex: 1 1 240px;
|
|
7036
|
+
font-size: 13px;
|
|
7037
|
+
color: var(--c-text);
|
|
7038
|
+
}
|
|
7039
|
+
.home-board-actions {
|
|
7040
|
+
display: flex;
|
|
7041
|
+
gap: 2px;
|
|
7042
|
+
flex-shrink: 0;
|
|
7043
|
+
}
|
|
7044
|
+
.home-board-action {
|
|
7045
|
+
padding: 6px 7px;
|
|
7046
|
+
border-radius: 6px;
|
|
7047
|
+
border: 1px solid transparent;
|
|
7048
|
+
background: none;
|
|
7049
|
+
color: var(--c-dim);
|
|
7050
|
+
font-size: 11px;
|
|
7051
|
+
cursor: pointer;
|
|
7052
|
+
}
|
|
7053
|
+
.home-board-action:hover {
|
|
7054
|
+
border-color: var(--c-line);
|
|
7055
|
+
background: color-mix(in srgb, var(--c-text) 5%, transparent);
|
|
7056
|
+
color: var(--c-text-soft);
|
|
7057
|
+
}
|
|
7058
|
+
.home-board-action.is-danger {
|
|
7059
|
+
border-color: var(--c-danger);
|
|
7060
|
+
background: var(--c-danger);
|
|
7061
|
+
color: var(--c-bg);
|
|
7062
|
+
font-weight: 600;
|
|
7063
|
+
}
|
|
7064
|
+
.home-board-open:focus-visible,
|
|
7065
|
+
.home-board-action:focus-visible,
|
|
7066
|
+
.home-view-new:focus-visible,
|
|
7067
|
+
.board-switcher-button:focus-visible {
|
|
7068
|
+
outline: 2px solid var(--c-accent);
|
|
7069
|
+
outline-offset: 2px;
|
|
7070
|
+
}
|
|
7071
|
+
|
|
7072
|
+
/* ── Board export dialog (plan 013) ── */
|
|
7073
|
+
.export-dialog {
|
|
7074
|
+
width: min(520px, calc(100% - 32px));
|
|
7075
|
+
}
|
|
7076
|
+
.export-dialog-note {
|
|
7077
|
+
font-size: 12px;
|
|
7078
|
+
color: var(--c-text-soft);
|
|
7079
|
+
}
|
|
7080
|
+
.export-dialog-list {
|
|
7081
|
+
margin: 0;
|
|
7082
|
+
padding-left: 18px;
|
|
7083
|
+
font-size: 13px;
|
|
7084
|
+
color: var(--c-text);
|
|
7085
|
+
display: flex;
|
|
7086
|
+
flex-direction: column;
|
|
7087
|
+
gap: 4px;
|
|
7088
|
+
}
|
|
7089
|
+
.export-dialog-files {
|
|
7090
|
+
display: flex;
|
|
7091
|
+
gap: 8px;
|
|
7092
|
+
align-items: flex-start;
|
|
7093
|
+
font-size: 12px;
|
|
7094
|
+
color: var(--c-text);
|
|
7095
|
+
word-break: break-all;
|
|
7096
|
+
}
|
|
7097
|
+
.export-dialog-result {
|
|
7098
|
+
font-size: 12px;
|
|
7099
|
+
color: var(--c-text);
|
|
7100
|
+
display: flex;
|
|
7101
|
+
flex-direction: column;
|
|
7102
|
+
gap: 6px;
|
|
7103
|
+
word-break: break-all;
|
|
7104
|
+
}
|
|
7105
|
+
.export-dialog-links {
|
|
7106
|
+
display: flex;
|
|
7107
|
+
gap: 12px;
|
|
7108
|
+
}
|
|
7109
|
+
.export-dialog-links a {
|
|
7110
|
+
color: var(--c-accent);
|
|
7111
|
+
}
|
|
7112
|
+
|
|
7113
|
+
/* ── Home categories ── */
|
|
7114
|
+
.home-section {
|
|
7115
|
+
display: flex;
|
|
7116
|
+
flex-direction: column;
|
|
7117
|
+
gap: 8px;
|
|
7118
|
+
}
|
|
7119
|
+
.home-section-head {
|
|
7120
|
+
display: flex;
|
|
7121
|
+
align-items: center;
|
|
7122
|
+
gap: 9px;
|
|
7123
|
+
min-height: 42px;
|
|
7124
|
+
width: 100%;
|
|
7125
|
+
padding: 9px 10px;
|
|
7126
|
+
background: none;
|
|
7127
|
+
border: none;
|
|
7128
|
+
border-radius: 8px;
|
|
7129
|
+
color: var(--c-text-soft);
|
|
7130
|
+
font-size: 12px;
|
|
7131
|
+
font-weight: 600;
|
|
7132
|
+
text-transform: uppercase;
|
|
7133
|
+
letter-spacing: 0.06em;
|
|
7134
|
+
cursor: pointer;
|
|
7135
|
+
text-align: left;
|
|
7136
|
+
}
|
|
7137
|
+
.home-section-head:hover {
|
|
7138
|
+
color: var(--c-text);
|
|
7139
|
+
background: color-mix(in srgb, var(--c-text) 5%, transparent);
|
|
7140
|
+
}
|
|
7141
|
+
.home-section-chevron,
|
|
7142
|
+
.home-section-folder {
|
|
7143
|
+
flex: 0 0 18px;
|
|
7144
|
+
stroke: currentColor;
|
|
7145
|
+
stroke-width: 1.75;
|
|
7146
|
+
stroke-linecap: round;
|
|
7147
|
+
stroke-linejoin: round;
|
|
7148
|
+
}
|
|
7149
|
+
.home-section-chevron {
|
|
7150
|
+
transition: transform 120ms ease;
|
|
7151
|
+
}
|
|
7152
|
+
.home-section-head[aria-expanded='true'] .home-section-chevron {
|
|
7153
|
+
transform: rotate(90deg);
|
|
7154
|
+
}
|
|
7155
|
+
.home-section-folder { color: var(--c-dim); }
|
|
7156
|
+
.home-section-count {
|
|
7157
|
+
font: 11px var(--mono);
|
|
7158
|
+
text-transform: none;
|
|
7159
|
+
color: var(--c-dim);
|
|
7160
|
+
margin-left: auto;
|
|
7161
|
+
}
|
|
7162
|
+
.home-section-head:focus-visible {
|
|
7163
|
+
outline: 2px solid var(--c-accent);
|
|
7164
|
+
outline-offset: 2px;
|
|
7165
|
+
}
|
|
7166
|
+
.home-section-head {
|
|
7167
|
+
text-transform: none;
|
|
7168
|
+
letter-spacing: normal;
|
|
7169
|
+
max-width: 100%;
|
|
7170
|
+
}
|
|
7171
|
+
.home-section-name {
|
|
7172
|
+
font-size: 13px;
|
|
7173
|
+
font-weight: 650;
|
|
7174
|
+
overflow-wrap: anywhere;
|
|
7175
|
+
}
|
|
7176
|
+
.home-folder-children {
|
|
7177
|
+
display: flex;
|
|
7178
|
+
flex-direction: column;
|
|
7179
|
+
gap: 10px;
|
|
7180
|
+
padding-left: 12px;
|
|
7181
|
+
border-left: 1px solid var(--c-line);
|
|
7182
|
+
}
|
|
7183
|
+
.home-search { width: 100%; box-sizing: border-box; }
|
|
7184
|
+
.board-copy-dialog,
|
|
7185
|
+
.board-link-dialog {
|
|
7186
|
+
width: min(540px, calc(100vw - 32px));
|
|
7187
|
+
max-height: calc(100dvh - 40px);
|
|
7188
|
+
overflow-y: auto;
|
|
7189
|
+
box-sizing: border-box;
|
|
7190
|
+
}
|
|
7191
|
+
.board-copy-dialog form,
|
|
7192
|
+
.board-copy-field,
|
|
7193
|
+
.board-copy-options {
|
|
7194
|
+
display: flex;
|
|
7195
|
+
flex-direction: column;
|
|
7196
|
+
gap: 8px;
|
|
7197
|
+
}
|
|
7198
|
+
.board-copy-dialog h2,
|
|
7199
|
+
.board-link-dialog h2 { margin: 0 0 12px; font-size: 17px; }
|
|
7200
|
+
.board-copy-field { color: var(--c-text-soft); font-size: 12px; }
|
|
7201
|
+
.board-copy-cards {
|
|
7202
|
+
margin: 14px 0;
|
|
7203
|
+
padding: 8px;
|
|
7204
|
+
border: 1px solid var(--c-line);
|
|
7205
|
+
border-radius: 9px;
|
|
7206
|
+
max-height: 230px;
|
|
7207
|
+
overflow-y: auto;
|
|
7208
|
+
}
|
|
7209
|
+
.board-copy-cards legend { color: var(--c-text-soft); font-size: 12px; }
|
|
7210
|
+
.board-copy-card {
|
|
7211
|
+
display: flex;
|
|
7212
|
+
align-items: center;
|
|
7213
|
+
gap: 9px;
|
|
7214
|
+
padding: 8px;
|
|
7215
|
+
border-radius: 7px;
|
|
7216
|
+
cursor: pointer;
|
|
7217
|
+
}
|
|
7218
|
+
.board-copy-card:hover { background: color-mix(in srgb, var(--c-accent) 9%, transparent); }
|
|
7219
|
+
.board-copy-card span { display: flex; flex-direction: column; min-width: 0; }
|
|
7220
|
+
.board-copy-card strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
|
|
7221
|
+
.board-copy-card small,
|
|
7222
|
+
.board-link-results small { color: var(--c-text-soft); font: 11px var(--mono); }
|
|
7223
|
+
.board-copy-options { font-size: 13px; }
|
|
7224
|
+
.board-copy-options label { display: flex; gap: 8px; align-items: center; }
|
|
7225
|
+
.board-copy-note,
|
|
7226
|
+
.board-copy-status { color: var(--c-text-soft); font-size: 12px; line-height: 1.5; }
|
|
7227
|
+
.board-copy-error { color: var(--c-danger); font-size: 12px; margin-top: 8px; }
|
|
7228
|
+
.board-link-results { display: flex; flex-direction: column; gap: 5px; margin: 12px 0; padding: 0; max-height: 320px; overflow-y: auto; list-style: none; }
|
|
7229
|
+
.board-link-results button { width: 100%; display: flex; justify-content: space-between; gap: 12px; padding: 10px; border: 1px solid var(--c-line); border-radius: 8px; background: var(--c-panel); color: var(--c-text); text-align: left; cursor: pointer; }
|
|
7230
|
+
.board-link-results button:hover,
|
|
7231
|
+
.board-link-results button:focus-visible { border-color: var(--c-accent); outline: none; }
|
|
7232
|
+
.home-folder-dialog {
|
|
7233
|
+
width: min(460px, calc(100vw - 32px));
|
|
7234
|
+
max-height: calc(100dvh - 48px);
|
|
7235
|
+
overflow-y: auto;
|
|
7236
|
+
box-sizing: border-box;
|
|
7237
|
+
}
|
|
7238
|
+
.home-folder-hint {
|
|
7239
|
+
color: var(--c-text-soft);
|
|
7240
|
+
font-size: 12px;
|
|
7241
|
+
line-height: 1.5;
|
|
7242
|
+
overflow-wrap: anywhere;
|
|
7243
|
+
}
|
|
7244
|
+
.home-folder-options {
|
|
7245
|
+
margin: 12px 0;
|
|
7246
|
+
padding: 8px;
|
|
7247
|
+
border: 1px solid var(--c-line);
|
|
7248
|
+
border-radius: 8px;
|
|
7249
|
+
max-height: 240px;
|
|
7250
|
+
overflow-y: auto;
|
|
7251
|
+
}
|
|
7252
|
+
.home-folder-options legend { color: var(--c-text-soft); font-size: 12px; }
|
|
7253
|
+
.home-folder-option {
|
|
7254
|
+
display: flex;
|
|
7255
|
+
align-items: center;
|
|
7256
|
+
gap: 8px;
|
|
7257
|
+
padding: 8px;
|
|
7258
|
+
border-radius: 6px;
|
|
7259
|
+
font-size: 13px;
|
|
7260
|
+
overflow-wrap: anywhere;
|
|
7261
|
+
cursor: pointer;
|
|
7262
|
+
}
|
|
7263
|
+
.home-folder-option:has(input:checked) { background: color-mix(in srgb, var(--c-accent) 12%, transparent); }
|
|
7264
|
+
.home-folder-option input { accent-color: var(--c-accent); flex-shrink: 0; }
|
|
7265
|
+
.home-folder-new { display: flex; flex-direction: column; gap: 6px; font-size: 12px; overflow-wrap: anywhere; }
|
|
7266
|
+
.attachment-node { padding: 16px; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; font-size: 13px; overflow: auto; height: 100%; box-sizing: border-box; }
|
|
7267
|
+
.attachment-node p { margin: 0; color: var(--c-text-soft); line-height: 1.5; }
|
|
7268
|
+
.attachment-node a, .md-import-source a { color: var(--c-accent); }
|
|
7269
|
+
.attachment-status { font-weight: 600; }
|
|
7270
|
+
.attachment-node .home-board-action { border-color: var(--c-line); color: var(--c-text); min-height: 34px; }
|
|
7271
|
+
.attachment-node .home-board-action:hover { background: var(--c-panel); border-color: var(--c-accent); }
|
|
7272
|
+
.attachment-review { width: 100%; border-top: 1px solid var(--c-line); padding-top: 12px; }
|
|
7273
|
+
.attachment-review pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.6 var(--mono); padding: 12px; background: var(--c-bg); border-radius: 8px; }
|
|
7274
|
+
.attachment-review h4 { margin-bottom: 6px; }
|
|
7275
|
+
.md-import-source { padding: 6px 12px; font-size: 11px; overflow-wrap: anywhere; color: var(--c-text-soft); border-top: 1px solid var(--c-line); }
|
|
7276
|
+
@media (max-width: 640px) {
|
|
7277
|
+
.home-board { flex-wrap: wrap; }
|
|
7278
|
+
.home-board-open { flex-basis: 100%; }
|
|
7279
|
+
.home-board-actions { padding: 0 8px 4px; }
|
|
7280
|
+
}
|