synabun 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/CHANGELOG.md +665 -0
  2. package/LICENSE +191 -0
  3. package/README.md +853 -0
  4. package/hooks/claude-code/post-plan.mjs +391 -0
  5. package/hooks/claude-code/post-remember.mjs +239 -0
  6. package/hooks/claude-code/pre-compact.mjs +241 -0
  7. package/hooks/claude-code/pre-websearch.mjs +90 -0
  8. package/hooks/claude-code/prompt-submit.mjs +861 -0
  9. package/hooks/claude-code/session-start.mjs +494 -0
  10. package/hooks/claude-code/shared.mjs +368 -0
  11. package/hooks/claude-code/stop.mjs +646 -0
  12. package/hooks/claude-code/test-user-learning.mjs +531 -0
  13. package/mcp-server/package.json +38 -0
  14. package/mcp-server/run.mjs +10 -0
  15. package/mcp-server/src/config.ts +70 -0
  16. package/mcp-server/src/http.ts +93 -0
  17. package/mcp-server/src/index.ts +203 -0
  18. package/mcp-server/src/preload-http.ts +25 -0
  19. package/mcp-server/src/preload.ts +29 -0
  20. package/mcp-server/src/scripts/migrate-qdrant-to-sqlite.ts +506 -0
  21. package/mcp-server/src/services/categories.ts +429 -0
  22. package/mcp-server/src/services/discord.ts +702 -0
  23. package/mcp-server/src/services/file-checksums.ts +33 -0
  24. package/mcp-server/src/services/local-embeddings.ts +77 -0
  25. package/mcp-server/src/services/neural-interface.ts +344 -0
  26. package/mcp-server/src/services/sqlite.ts +823 -0
  27. package/mcp-server/src/tools/browser-advanced.ts +123 -0
  28. package/mcp-server/src/tools/browser-interact.ts +255 -0
  29. package/mcp-server/src/tools/browser-navigate.ts +77 -0
  30. package/mcp-server/src/tools/browser-observe.ts +1330 -0
  31. package/mcp-server/src/tools/browser.ts +107 -0
  32. package/mcp-server/src/tools/card-tools.ts +193 -0
  33. package/mcp-server/src/tools/card.ts +22 -0
  34. package/mcp-server/src/tools/category.ts +379 -0
  35. package/mcp-server/src/tools/discord-channel.ts +274 -0
  36. package/mcp-server/src/tools/discord-guild.ts +188 -0
  37. package/mcp-server/src/tools/discord-member.ts +158 -0
  38. package/mcp-server/src/tools/discord-message.ts +231 -0
  39. package/mcp-server/src/tools/discord-onboarding.ts +228 -0
  40. package/mcp-server/src/tools/discord-role.ts +209 -0
  41. package/mcp-server/src/tools/discord-thread.ts +110 -0
  42. package/mcp-server/src/tools/discord-webhook.ts +176 -0
  43. package/mcp-server/src/tools/discord.ts +40 -0
  44. package/mcp-server/src/tools/forget.ts +38 -0
  45. package/mcp-server/src/tools/git-tools.ts +141 -0
  46. package/mcp-server/src/tools/git.ts +13 -0
  47. package/mcp-server/src/tools/image-tools.ts +98 -0
  48. package/mcp-server/src/tools/image.ts +17 -0
  49. package/mcp-server/src/tools/leonardo-browser-tools.ts +281 -0
  50. package/mcp-server/src/tools/leonardo.ts +28 -0
  51. package/mcp-server/src/tools/loop.ts +348 -0
  52. package/mcp-server/src/tools/memories.ts +118 -0
  53. package/mcp-server/src/tools/recall.ts +323 -0
  54. package/mcp-server/src/tools/reflect.ts +145 -0
  55. package/mcp-server/src/tools/remember.ts +115 -0
  56. package/mcp-server/src/tools/response.ts +26 -0
  57. package/mcp-server/src/tools/restore.ts +34 -0
  58. package/mcp-server/src/tools/sync.ts +114 -0
  59. package/mcp-server/src/tools/tictactoe-tools.ts +98 -0
  60. package/mcp-server/src/tools/tictactoe.ts +13 -0
  61. package/mcp-server/src/tools/utils.ts +25 -0
  62. package/mcp-server/src/tools/whiteboard-tools.ts +260 -0
  63. package/mcp-server/src/tools/whiteboard.ts +22 -0
  64. package/mcp-server/src/tui.ts +940 -0
  65. package/mcp-server/src/types.ts +85 -0
  66. package/mcp-server/tsconfig.json +19 -0
  67. package/neural-interface/package.json +27 -0
  68. package/neural-interface/public/apple-touch-icon.png +0 -0
  69. package/neural-interface/public/category-logos/claude.svg +1 -0
  70. package/neural-interface/public/category-logos/gemini-color.svg +1 -0
  71. package/neural-interface/public/category-logos/openai.svg +1 -0
  72. package/neural-interface/public/category-logos/synabun.png +0 -0
  73. package/neural-interface/public/claude-chat.css +878 -0
  74. package/neural-interface/public/claude-chat.html +92 -0
  75. package/neural-interface/public/claude-chat.js +1168 -0
  76. package/neural-interface/public/favicon-16x16.png +0 -0
  77. package/neural-interface/public/favicon-32x32.png +0 -0
  78. package/neural-interface/public/gallery.svg +6 -0
  79. package/neural-interface/public/icon-192.png +0 -0
  80. package/neural-interface/public/icon-512.png +0 -0
  81. package/neural-interface/public/index-legacy.html +14677 -0
  82. package/neural-interface/public/index.html +212 -0
  83. package/neural-interface/public/index2d-legacy.html +8193 -0
  84. package/neural-interface/public/index2d.html +127 -0
  85. package/neural-interface/public/invite.html +351 -0
  86. package/neural-interface/public/leonardoai.svg +1 -0
  87. package/neural-interface/public/logo-synabun.png +0 -0
  88. package/neural-interface/public/logoHD.png +0 -0
  89. package/neural-interface/public/manifest.json +14 -0
  90. package/neural-interface/public/offline.html +299 -0
  91. package/neural-interface/public/onboarding.html +2335 -0
  92. package/neural-interface/public/openclaw-logo-text.png +0 -0
  93. package/neural-interface/public/pin-svgrepo-com.svg +25 -0
  94. package/neural-interface/public/sessionicon.svg +8 -0
  95. package/neural-interface/public/shared/ansi-parser.js +305 -0
  96. package/neural-interface/public/shared/api.js +1043 -0
  97. package/neural-interface/public/shared/colors.js +153 -0
  98. package/neural-interface/public/shared/constants.js +141 -0
  99. package/neural-interface/public/shared/html-shell.js +777 -0
  100. package/neural-interface/public/shared/html-term-renderer.js +1022 -0
  101. package/neural-interface/public/shared/i18n.js +147 -0
  102. package/neural-interface/public/shared/registry.js +82 -0
  103. package/neural-interface/public/shared/state.js +86 -0
  104. package/neural-interface/public/shared/storage.js +150 -0
  105. package/neural-interface/public/shared/styles.css +21212 -0
  106. package/neural-interface/public/shared/ui-automation-studio.js +3573 -0
  107. package/neural-interface/public/shared/ui-bookmarks.js +231 -0
  108. package/neural-interface/public/shared/ui-claude-panel.js +6333 -0
  109. package/neural-interface/public/shared/ui-command-runner.js +534 -0
  110. package/neural-interface/public/shared/ui-cost-widget.js +602 -0
  111. package/neural-interface/public/shared/ui-detail.js +1454 -0
  112. package/neural-interface/public/shared/ui-explorer.js +1356 -0
  113. package/neural-interface/public/shared/ui-file-explorer.js +2750 -0
  114. package/neural-interface/public/shared/ui-games.js +411 -0
  115. package/neural-interface/public/shared/ui-help.js +107 -0
  116. package/neural-interface/public/shared/ui-image-gallery.js +461 -0
  117. package/neural-interface/public/shared/ui-invite.js +519 -0
  118. package/neural-interface/public/shared/ui-keybinds.js +452 -0
  119. package/neural-interface/public/shared/ui-layouts.js +297 -0
  120. package/neural-interface/public/shared/ui-link.js +731 -0
  121. package/neural-interface/public/shared/ui-loading.js +255 -0
  122. package/neural-interface/public/shared/ui-menubar.js +499 -0
  123. package/neural-interface/public/shared/ui-multiselect.js +93 -0
  124. package/neural-interface/public/shared/ui-navbar.js +222 -0
  125. package/neural-interface/public/shared/ui-notifications.js +287 -0
  126. package/neural-interface/public/shared/ui-panels.js +309 -0
  127. package/neural-interface/public/shared/ui-resume.js +653 -0
  128. package/neural-interface/public/shared/ui-search.js +145 -0
  129. package/neural-interface/public/shared/ui-sessions.js +531 -0
  130. package/neural-interface/public/shared/ui-settings.js +5987 -0
  131. package/neural-interface/public/shared/ui-sidebar.js +1905 -0
  132. package/neural-interface/public/shared/ui-skills.js +2805 -0
  133. package/neural-interface/public/shared/ui-stats.js +38 -0
  134. package/neural-interface/public/shared/ui-sync.js +201 -0
  135. package/neural-interface/public/shared/ui-terminal.js +6385 -0
  136. package/neural-interface/public/shared/ui-tooltip.js +123 -0
  137. package/neural-interface/public/shared/ui-trash.js +439 -0
  138. package/neural-interface/public/shared/ui-tutorial-draw.js +875 -0
  139. package/neural-interface/public/shared/ui-tutorial-steps.js +2276 -0
  140. package/neural-interface/public/shared/ui-tutorial.js +1117 -0
  141. package/neural-interface/public/shared/ui-update.js +244 -0
  142. package/neural-interface/public/shared/ui-whiteboard.js +3262 -0
  143. package/neural-interface/public/shared/ui-workspaces.js +722 -0
  144. package/neural-interface/public/shared/utils.js +360 -0
  145. package/neural-interface/public/shared/vterm-buffer.js +1102 -0
  146. package/neural-interface/public/sw.js +52 -0
  147. package/neural-interface/public/synabun.png +0 -0
  148. package/neural-interface/public/toolbar-album.svg +8 -0
  149. package/neural-interface/public/toolbar-question.svg +6 -0
  150. package/neural-interface/public/toolbar-sessions.svg +6 -0
  151. package/neural-interface/public/variant/2d/background.js +113 -0
  152. package/neural-interface/public/variant/2d/context-menu.js +133 -0
  153. package/neural-interface/public/variant/2d/gfx.js +45 -0
  154. package/neural-interface/public/variant/2d/graph.js +1635 -0
  155. package/neural-interface/public/variant/2d/hulls.js +207 -0
  156. package/neural-interface/public/variant/2d/lasso.js +135 -0
  157. package/neural-interface/public/variant/2d/layout.js +594 -0
  158. package/neural-interface/public/variant/2d/main.js +521 -0
  159. package/neural-interface/public/variant/2d/minimap.js +312 -0
  160. package/neural-interface/public/variant/2d/settings-gfx.js +98 -0
  161. package/neural-interface/public/variant/3d/background.js +884 -0
  162. package/neural-interface/public/variant/3d/camera.js +661 -0
  163. package/neural-interface/public/variant/3d/gfx.js +116 -0
  164. package/neural-interface/public/variant/3d/graph.js +2399 -0
  165. package/neural-interface/public/variant/3d/main.js +500 -0
  166. package/neural-interface/public/variant/3d/settings-gfx.js +228 -0
  167. package/neural-interface/scripts/rebuild-pty.js +100 -0
  168. package/neural-interface/server.js +15000 -0
  169. package/neural-interface/templates/CLAUDE-template.md +211 -0
  170. package/package.json +53 -0
  171. package/postinstall.js +135 -0
  172. package/setup.js +260 -0
  173. package/skills/leonardo/SKILL.md +159 -0
  174. package/skills/leonardo/icon.svg +1 -0
  175. package/skills/leonardo/modules/browser-guide.md +378 -0
  176. package/skills/leonardo/modules/image-prompter.md +277 -0
  177. package/skills/leonardo/modules/model-advisor.md +100 -0
  178. package/skills/leonardo/modules/prompt-library.md +110 -0
  179. package/skills/leonardo/modules/style-guide.md +186 -0
  180. package/skills/leonardo/modules/video-prompter.md +311 -0
  181. package/skills/synabun/SKILL.md +185 -0
  182. package/skills/synabun/icon.png +0 -0
  183. package/skills/synabun/modules/audit.md +374 -0
  184. package/skills/synabun/modules/changelog.md +194 -0
  185. package/skills/synabun/modules/idea.md +144 -0
  186. package/skills/synabun/modules/memorize.md +188 -0
  187. package/skills/synabun/synabunicon.png +0 -0
@@ -0,0 +1,777 @@
1
+ // ═══════════════════════════════════════════
2
+ // SynaBun Neural Interface — Shared HTML Shell
3
+ // Source of truth for all DOM elements shared across 2D/3D variants
4
+ // ═══════════════════════════════════════════
5
+
6
+ import { getVariant } from './registry.js';
7
+ import { t } from './i18n.js';
8
+
9
+ /**
10
+ * Returns the full shared HTML string for injection into <body>.
11
+ * Variant-specific elements (camera HUD, controls panel, minimap, etc.)
12
+ * are NOT included — those live in each variant's HTML file.
13
+ */
14
+ export function getSharedHTML() {
15
+ const variant = getVariant() || '3d';
16
+ const is3D = variant === '3d';
17
+
18
+ return `
19
+ <!-- Loading Overlay -->
20
+ <div id="loading-overlay">
21
+ <div id="loading-mascot">
22
+ <svg viewBox="0 0 280 140" width="160" height="80" style="overflow:visible">
23
+ <g class="syna-eye">
24
+ <g class="syna-lid" transform="translate(0,60) scale(1,0.08) translate(0,-60)">
25
+ <rect x="80" y="24" width="38" height="72" rx="19" fill="#ffffff"/>
26
+ </g>
27
+ </g>
28
+ <g class="syna-eye">
29
+ <g class="syna-lid" transform="translate(0,60) scale(1,0.08) translate(0,-60)">
30
+ <rect x="162" y="24" width="38" height="72" rx="19" fill="#ffffff"/>
31
+ </g>
32
+ </g>
33
+ <path d="M125,112 Q140,118 155,112" fill="none" stroke="rgba(255,255,255,0.15)" stroke-width="2.5" stroke-linecap="round"/>
34
+ </svg>
35
+ <span id="loading-zzz">z</span>
36
+ </div>
37
+ <img src="synabun.png?v=2" alt="SynaBun" class="loading-logo">
38
+ <div id="loading-text">${t('loading.connecting')}</div>
39
+ <div id="loading-sub">${t('loading.initializingNeural')}</div>
40
+ <div id="loading-action">
41
+ <button id="loading-action-btn" type="button">
42
+ <svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
43
+ <span id="loading-action-label">${t('loading.startServer')}</span>
44
+ </button>
45
+ <div id="loading-action-status"></div>
46
+ </div>
47
+ <div id="loading-server-cmd">
48
+ <div id="loading-server-cmd-hint">${t('loading.runCommand')}</div>
49
+ <div id="loading-server-cmd-box">
50
+ <code id="loading-cmd-text">npm start</code>
51
+ <button id="loading-cmd-copy" title="${t('loading.copyToClipboard')}">
52
+ <svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
53
+ </button>
54
+ </div>
55
+ <br>
56
+ <button id="loading-retry-btn" type="button">
57
+ <svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
58
+ ${t('loading.retryConnection')}
59
+ </button>
60
+ <div id="loading-retry-status"></div>
61
+ <img src="synabun.png?v=2" alt="SynaBun" style="margin-top:6px;height:32px;width:auto;filter:grayscale(0.5);opacity:0.18;">
62
+ </div>
63
+ </div>
64
+
65
+ <!-- Node Hover Tooltip -->
66
+ <div id="tooltip" class="glass">
67
+ <div id="tooltip-category"></div>
68
+ <div id="tooltip-preview"></div>
69
+ <div id="tooltip-importance"></div>
70
+ </div>
71
+
72
+ <!-- Top Menu Bar -->
73
+ <div id="title-bar">
74
+ <div class="bar-left">
75
+ <img src="synabun.png?v=2" alt="SynaBun" id="titlebar-logo" style="height:24px;width:auto;opacity:0.7;cursor:pointer;" data-tooltip="${t('tooltip.toggleExplorer')}">
76
+ <div class="bar-sep"></div>
77
+ <div class="view-toggle">
78
+ <a class="view-toggle-btn${is3D ? '' : ' active'}" href="${is3D ? '/index2d.html' : '#'}" id="nav-2d-link">${t('nav.toggle2d')}</a>
79
+ <a class="view-toggle-btn${is3D ? ' active' : ''}" href="${is3D ? '#' : '/'}" id="nav-3d-link">${t('nav.toggle3d')}</a>
80
+ <span class="view-toggle-sep"></span>
81
+ <a class="view-toggle-btn" href="/claude-chat.html" id="nav-chat-link" data-tooltip="SynaBun Chat — full Claude Code UI" style="display:none">Chat</a>
82
+ </div>
83
+ <div class="bar-sep"></div>
84
+
85
+ <!-- OS-style menubar -->
86
+ <div class="menubar">
87
+
88
+ <!-- Apps menu -->
89
+ <div class="menubar-item" data-menu="apps">
90
+ <button class="menubar-label">${t('nav.apps')}</button>
91
+ <div class="menubar-dropdown glass">
92
+ <div class="menu-item" id="menu-terminal-claude">
93
+ <span class="menu-check"></span>
94
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z"/></svg></span> ${t('menu.apps.claudeCode')}</span>
95
+ <span class="menu-shortcut" data-keybind-for="launch-claude"></span>
96
+ </div>
97
+ <div class="menu-item" id="menu-terminal-codex">
98
+ <span class="menu-check"></span>
99
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"/></svg></span> ${t('menu.apps.codexCli')}</span>
100
+ <span class="menu-shortcut" data-keybind-for="launch-codex"></span>
101
+ </div>
102
+ <div class="menu-item" id="menu-terminal-gemini">
103
+ <span class="menu-check"></span>
104
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z"/></svg></span> ${t('menu.apps.geminiCli')}</span>
105
+ <span class="menu-shortcut" data-keybind-for="launch-gemini"></span>
106
+ </div>
107
+ <div class="menu-sep"></div>
108
+ <div class="menu-item" id="menu-terminal-shell">
109
+ <span class="menu-check"></span>
110
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg></span> ${t('menu.apps.shell')}</span>
111
+ </div>
112
+ <div class="menu-item" id="menu-terminal-browser">
113
+ <span class="menu-check"></span>
114
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="10"/><ellipse cx="12" cy="12" rx="4" ry="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M4.5 7h15M4.5 17h15" stroke-width="1"/></svg></span> ${t('menu.apps.browser')}</span>
115
+ <span class="menu-shortcut" data-keybind-for="launch-browser"></span>
116
+ </div>
117
+ <div class="menu-item" id="menu-terminal-youtube">
118
+ <span class="menu-check"></span>
119
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg></span> ${t('menu.apps.youtube')}</span>
120
+ <span class="menu-shortcut" data-keybind-for="launch-youtube"></span>
121
+ </div>
122
+ <div class="menu-item" id="menu-terminal-discord">
123
+ <span class="menu-check"></span>
124
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.095 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg></span> Discord</span>
125
+ </div>
126
+ <div class="menu-item" id="menu-terminal-x">
127
+ <span class="menu-check"></span>
128
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg></span> X</span>
129
+ </div>
130
+ <div class="menu-item" id="menu-terminal-whatsapp">
131
+ <span class="menu-check"></span>
132
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg></span> WhatsApp</span>
133
+ </div>
134
+ <div class="menu-item" id="menu-app-leonardo">
135
+ <span class="menu-check"></span>
136
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.5 2l1.5 3.5L14.5 7l-3.5 1.5L9.5 12l-1.5-3.5L4.5 7l3.5-1.5L9.5 2zM19 10l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2zM5 17l1 2 2 1-2 1-1 2-1-2-2-1 2-1 1-2z"/></svg></span> Leonardo.AI</span>
137
+ </div>
138
+ <div class="menu-sep"></div>
139
+ <div class="menu-item" id="menu-command-runner">
140
+ <span class="menu-check"></span>
141
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="6 3 20 12 6 21 6 3"/></svg></span> Command Runner</span>
142
+ </div>
143
+ <div class="menu-item" id="menu-terminal-link">
144
+ <span class="menu-check"></span>
145
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></span> Link Terminals</span>
146
+ </div>
147
+ <div class="menu-item menu-toggle" id="menu-terminal-toggle">
148
+ <span class="menu-check">&#10003;</span>
149
+ <span class="menu-text">${t('menu.apps.showTerminal')}</span>
150
+ <span class="menu-shortcut">T</span>
151
+ </div>
152
+ <div class="menu-sep"></div>
153
+ <div class="menu-item" id="menu-install-app" style="display:none">
154
+ <span class="menu-check"></span>
155
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg></span> Install as App</span>
156
+ </div>
157
+ <div class="menu-item" id="menu-restart-server">
158
+ <span class="menu-check"></span>
159
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M23 4v6h-6"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg></span> Restart Server</span>
160
+ </div>
161
+ </div>
162
+ </div>
163
+
164
+ <!-- Resume menu -->
165
+ <div class="menubar-item" data-menu="resume">
166
+ <button class="menubar-label">Resume</button>
167
+ <div class="menubar-dropdown glass menubar-dropdown--resume">
168
+ <div id="resume-list"></div>
169
+ </div>
170
+ </div>
171
+
172
+ <!-- View menu -->
173
+ <div class="menubar-item" data-menu="view">
174
+ <button class="menubar-label">${t('nav.view')}</button>
175
+ <div class="menubar-dropdown glass">
176
+ <div class="menu-item menu-toggle active" id="menu-toggle-categories">
177
+ <span class="menu-check">&#10003;</span>
178
+ <span class="menu-text">${t('menu.view.categories')}</span>
179
+ <span class="menu-shortcut">C</span>
180
+ </div>
181
+ <div class="menu-item menu-toggle" id="menu-toggle-explorer">
182
+ <span class="menu-check">&#10003;</span>
183
+ <span class="menu-text">${t('menu.view.explorer')}</span>
184
+ <span class="menu-shortcut">F</span>
185
+ </div>
186
+ <div class="menu-item menu-toggle" id="menu-toggle-file-explorer">
187
+ <span class="menu-check">&#10003;</span>
188
+ <span class="menu-text">File Explorer</span>
189
+ <span class="menu-shortcut" data-keybind-for="toggle-file-explorer"></span>
190
+ </div>
191
+ <div class="menu-sep"></div>
192
+ <div id="menu-variant-slot"></div>
193
+ <div class="menu-sep" id="menu-variant-sep" style="display:none"></div>
194
+ <div class="menu-item" id="menu-help">
195
+ <span class="menu-check"></span>
196
+ <span class="menu-text">${t('menu.view.help')}</span>
197
+ <span class="menu-shortcut">?</span>
198
+ </div>
199
+ </div>
200
+ </div>
201
+
202
+ <!-- Graph menu -->
203
+ <div class="menubar-item" data-menu="graph">
204
+ <button class="menubar-label">${t('nav.graph')}</button>
205
+ <div class="menubar-dropdown glass">
206
+ <div class="menu-group-label">${t('menu.graph.linksGroup')}</div>
207
+ <div class="menu-item menu-radio active" data-group="link-mode" data-value="off">
208
+ <span class="menu-check">&#10003;</span>
209
+ <span class="menu-text">${t('menu.graph.linksOff')}</span>
210
+ </div>
211
+ <div class="menu-item menu-radio" data-group="link-mode" data-value="intra">
212
+ <span class="menu-check">&#10003;</span>
213
+ <span class="menu-text">${t('menu.graph.linksIntra')}</span>
214
+ </div>
215
+ <div class="menu-item menu-radio" data-group="link-mode" data-value="all">
216
+ <span class="menu-check">&#10003;</span>
217
+ <span class="menu-text">${t('menu.graph.linksAll')}</span>
218
+ </div>
219
+ <div class="menu-sep"></div>
220
+ <div class="menu-group-label">${t('menu.graph.linkTypeGroup')}</div>
221
+ <div class="menu-item menu-radio active" data-group="link-type" data-value="all">
222
+ <span class="menu-check">&#10003;</span>
223
+ <span class="menu-text">${t('menu.graph.allTypes')}</span>
224
+ </div>
225
+ <div id="menu-link-types-slot"></div>
226
+ <div class="menu-sep"></div>
227
+ <div class="menu-group-label">${t('menu.graph.nodeLimitGroup')}</div>
228
+ <div class="menu-item menu-radio" data-group="node-limit" data-value="500">
229
+ <span class="menu-check">&#10003;</span>
230
+ <span class="menu-text">500</span>
231
+ </div>
232
+ <div class="menu-item menu-radio" data-group="node-limit" data-value="1000">
233
+ <span class="menu-check">&#10003;</span>
234
+ <span class="menu-text">1,000</span>
235
+ </div>
236
+ <div class="menu-item menu-radio" data-group="node-limit" data-value="2000">
237
+ <span class="menu-check">&#10003;</span>
238
+ <span class="menu-text">2,000</span>
239
+ </div>
240
+ <div class="menu-item menu-radio" data-group="node-limit" data-value="4000">
241
+ <span class="menu-check">&#10003;</span>
242
+ <span class="menu-text">4,000</span>
243
+ </div>
244
+ <div class="menu-item menu-radio active" data-group="node-limit" data-value="0">
245
+ <span class="menu-check">&#10003;</span>
246
+ <span class="menu-text">All</span>
247
+ </div>
248
+ <div class="menu-sep"></div>
249
+ <div class="menu-item" id="menu-reset-layout">
250
+ <span class="menu-check"></span>
251
+ <span class="menu-text">${t('menu.graph.resetLayout')}</span>
252
+ </div>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Skills menu -->
257
+ <div class="menubar-item" data-menu="skills">
258
+ <button class="menubar-label">${t('nav.skills')}</button>
259
+ <div class="menubar-dropdown glass">
260
+ <div class="menu-item" id="menu-open-skills-studio">
261
+ <span class="menu-check"></span>
262
+ <span class="menu-text">${t('menu.skills.skillsStudio')}</span>
263
+ <span class="menu-shortcut">K</span>
264
+ </div>
265
+ <div class="menu-sep"></div>
266
+ <div class="menu-item" id="menu-skills-new">
267
+ <span class="menu-check"></span>
268
+ <span class="menu-text">${t('menu.skills.newSkill')}</span>
269
+ </div>
270
+ <div class="menu-item" id="menu-skills-import">
271
+ <span class="menu-check"></span>
272
+ <span class="menu-text">${t('menu.skills.import')}</span>
273
+ </div>
274
+ </div>
275
+ </div>
276
+
277
+ <!-- Automations menu -->
278
+ <div class="menubar-item" data-menu="automations">
279
+ <button class="menubar-label">${t('nav.automations')}</button>
280
+ <div class="menubar-dropdown glass">
281
+ <div class="menu-item" id="menu-open-automation-studio">
282
+ <span class="menu-check"></span>
283
+ <span class="menu-text">${t('menu.automations.studio')}</span>
284
+ <span class="menu-shortcut">A</span>
285
+ </div>
286
+ <div class="menu-sep"></div>
287
+ <div class="menu-item" id="menu-automations-schedules">
288
+ <span class="menu-check"></span>
289
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg></span> Schedules</span>
290
+ </div>
291
+ <div class="menu-sep"></div>
292
+ <div class="menu-item" id="menu-automations-new">
293
+ <span class="menu-check"></span>
294
+ <span class="menu-text">${t('menu.automations.newAutomation')}</span>
295
+ </div>
296
+ <div class="menu-item" id="menu-automations-import">
297
+ <span class="menu-check"></span>
298
+ <span class="menu-text">${t('menu.automations.import')}</span>
299
+ </div>
300
+ </div>
301
+ </div>
302
+
303
+ <!-- Games menu -->
304
+ <div class="menubar-item" data-menu="games">
305
+ <button class="menubar-label">${t('nav.games')}</button>
306
+ <div class="menubar-dropdown glass">
307
+ <div class="menu-item" id="menu-game-tictactoe">
308
+ <span class="menu-check"></span>
309
+ <span class="menu-text"><span class="menu-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="2" x2="8" y2="22"/><line x1="16" y1="2" x2="16" y2="22"/><line x1="2" y1="8" x2="22" y2="8"/><line x1="2" y1="16" x2="22" y2="16"/></svg></span> ${t('menu.games.ticTacToe')}</span>
310
+ </div>
311
+ </div>
312
+ </div>
313
+
314
+ <!-- Settings (text button) -->
315
+ <button class="menubar-label menubar-action" id="menubar-settings-btn">${t('nav.settings')}</button>
316
+
317
+ </div>
318
+ </div>
319
+
320
+ <div class="bar-center" id="search-container">
321
+ <div id="search-wrapper">
322
+ <input type="text" id="search-input" placeholder="${t('search.placeholder')}" autocomplete="off" spellcheck="false">
323
+ <span id="search-badge"></span>
324
+ <button id="search-clear">&times;</button>
325
+ </div>
326
+ </div>
327
+
328
+ <div class="bar-right">
329
+ <div class="bar-group">
330
+ <button id="titlebar-cost-btn" class="bar-icon bar-cost-btn" data-tooltip="Cost Tracker"><span class="bar-cost-label">$0</span></button>
331
+ <button id="titlebar-sessions-btn" class="bar-icon" data-tooltip="Session Monitor"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M2 12.0002C2 7.28611 2 4.92909 3.46447 3.46462C4.70529 2.2238 6.58687 2.03431 10 2.00537M22 12.0002C22 7.28611 22 4.92909 20.5355 3.46462C19.2947 2.2238 17.4131 2.03431 14 2.00537"/><path d="M10 22C7.19974 22 5.79961 22 4.73005 21.455C3.78924 20.9757 3.02433 20.2108 2.54497 19.27C2 18.2004 2 16.8003 2 14C2 11.1997 2 9.79961 2.54497 8.73005C3.02433 7.78924 3.78924 7.02433 4.73005 6.54497C5.79961 6 7.19974 6 10 6H14C16.8003 6 18.2004 6 19.27 6.54497C20.2108 7.02433 20.9757 7.78924 21.455 8.73005C22 9.79961 22 11.1997 22 14C22 16.8003 22 18.2004 21.455 19.27C20.9757 20.2108 20.2108 20.9757 19.27 21.455C18.2004 22 16.8003 22 14 22"/><path d="M12 11L12 17M12 17L14.5 14.5M12 17L9.5 14.5" stroke-linejoin="round"/></svg></button>
332
+ <button id="titlebar-gallery-btn" class="bar-icon" data-tooltip="Image Gallery"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M21.1935 16.793C20.8437 19.2739 20.6689 20.5143 19.7717 21.2572C18.8745 22 17.5512 22 14.9046 22H9.09536C6.44881 22 5.12553 22 4.22834 21.2572C3.33115 20.5143 3.15626 19.2739 2.80648 16.793L2.38351 13.793C1.93748 10.6294 1.71447 9.04765 2.66232 8.02383C3.61017 7 5.29758 7 8.67239 7H15.3276C18.7024 7 20.3898 7 21.3377 8.02383C22.0865 8.83268 22.1045 9.98979 21.8592 12"/><path d="M19.5617 7C19.7904 5.69523 18.7863 4.5 17.4617 4.5H6.53788C5.21323 4.5 4.20922 5.69523 4.43784 7"/><path d="M17.4999 4.5C17.5283 4.24092 17.5425 4.11135 17.5427 4.00435C17.545 2.98072 16.7739 2.12064 15.7561 2.01142C15.6497 2 15.5194 2 15.2588 2H8.74099C8.48035 2 8.35002 2 8.24362 2.01142C7.22584 2.12064 6.45481 2.98072 6.45704 4.00434C6.45727 4.11135 6.47146 4.2409 6.49983 4.5"/><circle cx="16.5" cy="11.5" r="1.5"/><path d="M19.9999 20L17.1157 17.8514C16.1856 17.1586 14.8004 17.0896 13.7766 17.6851L13.5098 17.8403C12.7984 18.2542 11.8304 18.1848 11.2156 17.6758L7.37738 14.4989C6.6113 13.8648 5.38245 13.8309 4.5671 14.4214L3.24316 15.3803"/></svg></button>
333
+ </div>
334
+ <span class="bar-divider"></span>
335
+ <div class="bar-group">
336
+ <button id="titlebar-tutorial-btn" class="bar-icon" data-tooltip="Toggle Tutorial"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M10.125 8.875C10.125 7.83947 10.9645 7 12 7C13.0355 7 13.875 7.83947 13.875 8.875C13.875 9.56245 13.505 10.1635 12.9534 10.4899C12.478 10.7711 12 11.1977 12 11.75V13"/><circle cx="12" cy="16" r="1" fill="currentColor" stroke="none"/><path d="M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C21.5093 4.43821 21.8356 5.80655 21.9449 8"/></svg></button>
337
+ </div>
338
+ <span class="bar-divider"></span>
339
+ <div class="bar-group">
340
+ <button id="titlebar-viz-toggle" class="bar-icon active" data-tooltip="${t('tooltip.toggleViz')}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1" fill="currentColor" stroke="none"/><path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/></svg></button>
341
+ <button id="titlebar-fullscreen-btn" class="bar-icon" data-tooltip="${t('tooltip.fullscreen')}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/><path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/></svg></button>
342
+ </div>
343
+ <span class="bar-divider"></span>
344
+ <div class="bar-group bar-group--clock">
345
+ <span id="titlebar-clock" class="titlebar-clock"></span>
346
+ </div>
347
+ </div>
348
+ </div>
349
+
350
+ <!-- Top-Right Controls (Trash + Grid + Workspace) -->
351
+ <div id="topright-controls">
352
+ <div id="topright-inner">
353
+ <button id="topright-trash-btn" class="topright-icon-btn" data-tooltip="${t('nav.trash')}">
354
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6h16"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><line x1="10" y1="10" x2="10" y2="18"/><line x1="14" y1="10" x2="14" y2="18"/></svg>
355
+ <span class="count-badge count-badge--red" id="titlebar-trash-count"></span>
356
+ </button>
357
+
358
+ <button id="ws-grid-toggle" class="topright-icon-btn" data-tooltip="Snap to Grid">
359
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="1.5"/><circle cx="12" cy="6" r="1.5"/><circle cx="18" cy="6" r="1.5"/><circle cx="6" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="18" cy="12" r="1.5"/><circle cx="6" cy="18" r="1.5"/><circle cx="12" cy="18" r="1.5"/><circle cx="18" cy="18" r="1.5"/></svg>
360
+ </button>
361
+
362
+ <button id="ws-tile-btn" class="topright-icon-btn" data-tooltip="Tile terminals">
363
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="8" height="8" rx="2"/><rect x="13" y="3" width="8" height="8" rx="2"/><rect x="3" y="13" width="8" height="8" rx="2"/><rect x="13" y="13" width="8" height="8" rx="2"/></svg>
364
+ </button>
365
+
366
+ <span class="tr-divider"></span>
367
+
368
+ <button id="topright-update-btn" class="topright-icon-btn" style="display:none" data-tooltip="Update available">
369
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
370
+ <span class="count-badge count-badge--green" id="update-badge"></span>
371
+ </button>
372
+
373
+ <button id="topright-keybinds-btn" class="topright-icon-btn" data-tooltip="Keybinds">
374
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="3"/><circle cx="7" cy="9" r="1" fill="currentColor" stroke="none"/><circle cx="12" cy="9" r="1" fill="currentColor" stroke="none"/><circle cx="17" cy="9" r="1" fill="currentColor" stroke="none"/><path d="M7 15h10"/></svg>
375
+ </button>
376
+
377
+ <button id="topright-memory-explorer-btn" class="topright-icon-btn" data-tooltip="Memory Explorer">
378
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"/><path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z"/><path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4"/></svg>
379
+ </button>
380
+
381
+ <button id="topright-file-explorer-btn" class="topright-icon-btn" data-tooltip="File Explorer">
382
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
383
+ </button>
384
+
385
+ <span class="tr-divider"></span>
386
+
387
+ <div id="bookmarks-overlay">
388
+ <button id="topright-bookmarks-btn" class="topright-icon-btn" data-tooltip="Bookmarks">
389
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
390
+ <span class="count-badge count-badge--gold" id="bookmark-count"></span>
391
+ </button>
392
+ <div id="bookmarks-dropdown" style="display:none;">
393
+ <div id="bookmarks-list"></div>
394
+ </div>
395
+ </div>
396
+ <div id="invite-overlay">
397
+ <button id="invite-btn" class="topright-icon-btn" data-tooltip="Share / Invite">
398
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
399
+ <span class="count-badge count-badge--blue" id="invite-session-count" style="display:none"></span>
400
+ </button>
401
+ <div id="invite-dropdown" style="display:none;"></div>
402
+ </div>
403
+
404
+ <span class="tr-divider"></span>
405
+
406
+ <div id="workspace-overlay">
407
+ <div id="ws-indicator">
408
+ <svg class="ws-icon" viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
409
+ <span id="ws-active-name">No workspace</span>
410
+ <button id="ws-quick-save" class="ws-quick-save" data-tooltip="Quick save"><svg viewBox="0 0 24 24"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg></button>
411
+ <svg class="ws-chevron" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg>
412
+ </div>
413
+ <div id="ws-dropdown" style="display:none;">
414
+ <div class="ws-save-bar">
415
+ <input type="text" id="ws-name-input" placeholder="Save workspace..." autocomplete="off" spellcheck="false">
416
+ <button id="ws-save-btn" data-tooltip="Save"><svg viewBox="0 0 24 24"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg></button>
417
+ </div>
418
+ <button id="ws-clear-btn" class="ws-new-btn"><svg viewBox="0 0 24 24"><path d="M3 6h18"/><path d="M8 6V4h8v2"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/></svg>Clear workspace</button>
419
+ <div class="ws-divider"></div>
420
+ <div id="ws-list" class="ws-list"></div>
421
+ <div class="ws-divider"></div>
422
+ <div class="ws-footer">
423
+ <button id="ws-export-btn" class="ws-footer-btn" title="Export all workspaces"><svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>Export</button>
424
+ <button id="ws-import-btn" class="ws-footer-btn" title="Import workspaces"><svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>Import</button>
425
+ </div>
426
+ <input type="file" id="ws-import-file" accept=".json" style="display:none;">
427
+ </div>
428
+ </div>
429
+ </div>
430
+ <button id="topright-claude-panel-btn" class="topright-icon-btn" data-tooltip="Claude Code side panel">
431
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="15" y1="3" x2="15" y2="21"/></svg>
432
+ </button>
433
+ <button id="topright-collapse-btn" class="topright-collapse-btn" data-tooltip="Toggle toolbar">
434
+ <svg viewBox="0 0 24 24" class="collapse-chevron"><polyline points="9 18 15 12 9 6"/></svg>
435
+ <span class="collapse-dots">
436
+ <span></span><span></span><span></span>
437
+ </span>
438
+ </button>
439
+ <div id="term-minimized-tray"></div>
440
+ </div>
441
+
442
+ <!-- Help Modal -->
443
+ <div id="help-overlay">
444
+ <div id="help-modal" class="glass" style="position:relative;">
445
+ <button class="backdrop-toggle-btn" id="help-backdrop-toggle" data-tooltip="Toggle backdrop" style="position:absolute;top:16px;right:48px;">
446
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
447
+ </button>
448
+ <button id="help-close">&times;</button>
449
+ <h2>${t('help.title')}</h2>
450
+ <div id="help-content"></div>
451
+ </div>
452
+ </div>
453
+
454
+ <!-- Category Sidebar -->
455
+ <div id="category-sidebar" class="glass resizable">
456
+ <div class="resize-handle resize-handle-t" data-resize="t"></div>
457
+ <div class="resize-handle resize-handle-b" data-resize="b"></div>
458
+ <div class="resize-handle resize-handle-l" data-resize="l"></div>
459
+ <div class="resize-handle resize-handle-r" data-resize="r"></div>
460
+ <div class="resize-handle resize-handle-tl" data-resize="tl"></div>
461
+ <div class="resize-handle resize-handle-tr" data-resize="tr"></div>
462
+ <div class="resize-handle resize-handle-bl" data-resize="bl"></div>
463
+ <div class="resize-handle resize-handle-br" data-resize="br"></div>
464
+ <div class="sidebar-header drag-handle" data-drag="category-sidebar">
465
+ <div class="sidebar-header-actions">
466
+ <button class="detail-action-btn" id="category-select-all-btn" data-tooltip="${t('sidebar.selectAll')}"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="3"/><polyline points="9 12 11 14 16 9"/></svg></button>
467
+ <button class="detail-action-btn" id="category-clear-btn" data-tooltip="${t('sidebar.deselectAll')}"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="3"/><line x1="9" y1="9" x2="15" y2="15"/><line x1="15" y1="9" x2="9" y2="15"/></svg></button>
468
+ <div class="detail-action-sep"></div>
469
+ <button class="detail-action-btn" id="label-toggle-btn" data-tooltip="${t('sidebar.toggleLabels')}"><svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
470
+ <button class="detail-action-btn" id="label-size-btn" data-tooltip="${t('sidebar.labelSize')}"><svg viewBox="0 0 24 24"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg></button>
471
+ <div class="detail-action-sep"></div>
472
+ <button class="detail-action-btn pin-btn" data-pin="category-sidebar" data-tooltip="${t('common.pin')}"><svg viewBox="0 0 24 24"><path d="M9 4v4.5L7.5 10H6v2h4v7l2 1 2-1v-7h4v-2h-1.5L15 8.5V4H9z" stroke-linejoin="round" stroke-linecap="round"/></svg></button>
473
+ <button class="detail-action-btn detail-action-btn--close" id="sidebar-close" data-tooltip="${t('common.close')}">&times;</button>
474
+ </div>
475
+ <div class="sidebar-header-title">${t('sidebar.title')}</div>
476
+ </div>
477
+ <div id="category-sidebar-body">
478
+ <div id="sidebar-label-controls">
479
+ <input type="range" id="label-size-slider" min="0.3" max="2.5" step="0.1" value="1.0" style="flex:1;height:3px;accent-color:var(--t-muted);cursor:pointer;opacity:0;transition:opacity 0.2s;pointer-events:none;" data-tooltip="${t('sidebar.labelSize')}">
480
+ </div>
481
+ <div id="category-list"></div>
482
+ <div style="display:flex;gap:8px;padding:0 12px;margin-bottom:8px;">
483
+ <button id="category-add-btn" style="flex:1;" data-tooltip="${t('sidebar.addCategory')}"><svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>${t('sidebar.category')}</button>
484
+ <button id="category-add-parent-btn" style="flex:1;" data-tooltip="${t('sidebar.addParent')}"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>${t('sidebar.parent')}</button>
485
+ </div>
486
+ <div style="display:flex;gap:8px;padding:0 12px;margin-bottom:8px;">
487
+ <button id="settings-btn" style="flex:1;" data-tooltip="${t('common.settings')}"><svg viewBox="0 0 24 24"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>${t('common.settings')}</button>
488
+ </div>
489
+ <div id="category-create-form" data-mode="child">
490
+ <div id="cat-form-title" style="font-weight:600;padding:8px 12px 4px;color:#aaa;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;">${t('sidebar.createCategory')}</div>
491
+ <input class="category-create-input" id="cat-name-input" placeholder="${t('sidebar.categoryName')}" maxlength="30" spellcheck="false">
492
+ <input class="category-create-input" id="cat-desc-input" placeholder="${t('sidebar.shortDescription')}">
493
+ <select class="modal-select" id="cat-parent-select">
494
+ <option value="">${t('sidebar.noneStandalone')}</option>
495
+ </select>
496
+ <div class="color-swatch-row" id="color-swatch-row"></div>
497
+ <div class="category-form-error" id="cat-form-error"></div>
498
+ <div class="category-form-actions">
499
+ <button class="category-form-btn-cancel" id="cat-form-cancel">${t('common.cancel')}</button>
500
+ <button class="category-form-btn-create" id="cat-form-create" disabled>${t('common.create')}</button>
501
+ </div>
502
+ </div>
503
+ </div>
504
+ </div>
505
+
506
+ <!-- Memory Explorer (docked sidebar) -->
507
+ <div id="explorer-panel">
508
+ <div class="explorer-filter">
509
+ <svg class="explorer-filter-icon" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg>
510
+ <input type="text" id="explorer-filter-input" placeholder="${t('explorer.filterPlaceholder')}" autocomplete="off" spellcheck="false">
511
+ <button id="explorer-filter-clear">&times;</button>
512
+ </div>
513
+ <div class="explorer-toolbar">
514
+ <button class="detail-action-btn" id="explorer-collapse-all" data-tooltip="${t('explorer.collapseAll')}"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>
515
+ <button class="detail-action-btn" id="explorer-expand-all" data-tooltip="${t('explorer.expandAll')}"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h10M4 18h16M18 9v6"/></svg></button>
516
+ <div class="detail-action-sep"></div>
517
+ <button class="detail-action-btn" id="explorer-sort-btn" data-tooltip="${t('explorer.sortNewest')}"><svg viewBox="0 0 24 24"><path d="M3 6h7M3 12h5M3 18h3M16 4v16M12 16l4 4 4-4"/></svg></button>
518
+ <div class="detail-action-sep"></div>
519
+ <button class="detail-action-btn" id="explorer-label-toggle" data-tooltip="${t('explorer.toggleLabels')}"><svg viewBox="0 0 24 24"><path d="M2.06 12c.86-2.15 3.64-7 9.94-7s9.08 4.85 9.94 7c-.86 2.15-3.64 7-9.94 7s-9.08-4.85-9.94-7z"/><circle cx="12" cy="12" r="3"/></svg></button>
520
+ <button class="detail-action-btn" id="explorer-label-size" data-tooltip="${t('explorer.labelSize')}"><svg viewBox="0 0 24 24"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg></button>
521
+ <div class="detail-action-sep"></div>
522
+ <button class="detail-action-btn" id="explorer-select-all" data-tooltip="${t('explorer.showAllCategories')}"><svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
523
+ <button class="detail-action-btn" id="explorer-deselect-all" data-tooltip="${t('explorer.hideAllCategories')}"><svg viewBox="0 0 24 24"><path d="M2 2l20 20"/><path d="M6.71 6.71C3.94 8.7 2.5 11.27 2.06 12c.86 2.15 3.64 7 9.94 7 2.08 0 3.82-.6 5.23-1.49"/><path d="M10 5.07A9.77 9.77 0 0 1 12 5c6.3 0 9.08 4.85 9.94 7-.35.87-.85 1.86-1.65 2.82"/></svg></button>
524
+ </div>
525
+ <div id="explorer-label-slider-row" class="explorer-slider-row" style="display:none">
526
+ <input type="range" id="explorer-label-slider" min="0.3" max="2.5" step="0.1" value="1.0">
527
+ </div>
528
+ <div id="explorer-tree" class="explorer-tree"></div>
529
+ <div class="explorer-footer">
530
+ <span id="explorer-count">0 ${t('explorer.memoryCount.other', { count: '' }).trim()}</span>
531
+ </div>
532
+ <div class="explorer-resize-handle" id="explorer-resize-handle"></div>
533
+ </div>
534
+
535
+ <!-- File Explorer (docked sidebar) -->
536
+ <div id="file-explorer-panel">
537
+ <div class="fe-project-row">
538
+ <div class="fe-project-selector" id="fe-project-selector">
539
+ <button class="fe-project-btn" id="fe-project-btn">
540
+ <svg class="fe-project-icon" viewBox="0 0 24 24"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
541
+ <span class="fe-project-label" id="fe-project-label">Project</span>
542
+ <svg class="fe-project-chevron" viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
543
+ </button>
544
+ <div class="fe-project-dropdown" id="fe-project-dropdown"></div>
545
+ </div>
546
+ <button class="fe-branch-btn" id="fe-branch-btn" style="display:none">
547
+ <svg viewBox="0 0 24 24"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>
548
+ <span class="fe-branch-btn-name" id="fe-branch-btn-name"></span>
549
+ <span class="fe-branch-btn-badge" id="fe-branch-btn-badge"></span>
550
+ </button>
551
+ </div>
552
+ <div class="fe-filter">
553
+ <svg class="fe-filter-icon" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg>
554
+ <input type="text" id="fe-filter-input" placeholder="Search files..." autocomplete="off" spellcheck="false">
555
+ <button id="fe-filter-clear">&times;</button>
556
+ </div>
557
+ <div class="fe-toolbar">
558
+ <button class="detail-action-btn" id="fe-collapse-all" data-tooltip="Collapse all"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>
559
+ <button class="detail-action-btn" id="fe-expand-all" data-tooltip="Expand all"><svg viewBox="0 0 24 24"><path d="M4 6h16M4 12h10M4 18h16M18 9v6"/></svg></button>
560
+ <div class="detail-action-sep"></div>
561
+ <button class="detail-action-btn" id="fe-sort-btn" data-tooltip="Sort: name"><svg viewBox="0 0 24 24"><path d="M3 6h7M3 12h5M3 18h3M16 4v16M12 16l4 4 4-4"/></svg></button>
562
+ <div class="detail-action-sep"></div>
563
+ <button class="detail-action-btn fe-disabled" id="fe-undo-btn" data-tooltip="Undo delete"><svg viewBox="0 0 24 24"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg></button>
564
+ <button class="detail-action-btn fe-disabled" id="fe-redo-btn" data-tooltip="Redo delete"><svg viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg></button>
565
+ <div class="detail-action-sep"></div>
566
+ <button class="detail-action-btn" id="fe-refresh" data-tooltip="Refresh"><svg viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg></button>
567
+ </div>
568
+ <div id="fe-tree" class="fe-tree"></div>
569
+ <div class="fe-footer">
570
+ <span id="fe-count">0 items</span>
571
+ </div>
572
+ <div class="fe-resize-handle" id="fe-resize-handle"></div>
573
+ </div>
574
+
575
+ <!-- File Editor (separate panel, slides from file explorer's right edge) -->
576
+ <div id="fe-editor-panel" class="fe-editor-panel">
577
+ <div class="fe-editor-header">
578
+ <button class="fe-editor-back" id="fe-editor-back" data-tooltip="Close editor">
579
+ <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
580
+ </button>
581
+ <span class="fe-editor-dot" id="fe-editor-dot"></span>
582
+ <span class="fe-editor-filepath" id="fe-editor-filepath"></span>
583
+ <div style="flex:1"></div>
584
+ <button class="fe-editor-action" id="fe-editor-find-btn" data-tooltip="Find (Ctrl+F)">
585
+ <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
586
+ </button>
587
+ <button class="fe-editor-action" id="fe-editor-word-wrap" data-tooltip="Toggle word wrap">
588
+ <svg viewBox="0 0 24 24"><path d="M3 6h18M3 12h15a3 3 0 1 1 0 6h-4"/><polyline points="16 16 14 18 16 20"/><path d="M3 18h7"/></svg>
589
+ </button>
590
+ <div class="fe-editor-help-wrap">
591
+ <button class="fe-editor-action fe-editor-help-btn" id="fe-editor-help-btn" data-tooltip="Keyboard shortcuts">
592
+ <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
593
+ </button>
594
+ <div class="fe-editor-keybinds" id="fe-editor-keybinds">
595
+ <div class="fe-editor-keybinds-title">Keyboard Shortcuts</div>
596
+ <div class="fe-editor-kb"><kbd>Ctrl+S</kbd> <span>Save</span></div>
597
+ <div class="fe-editor-kb"><kbd>Ctrl+F</kbd> <span>Find</span></div>
598
+ <div class="fe-editor-kb"><kbd>Ctrl+H</kbd> <span>Replace</span></div>
599
+ <div class="fe-editor-kb"><kbd>Ctrl+G</kbd> <span>Go to Line</span></div>
600
+ <div class="fe-editor-kb"><kbd>Ctrl+D</kbd> <span>Duplicate Line</span></div>
601
+ <div class="fe-editor-kb"><kbd>Ctrl+/</kbd> <span>Toggle Comment</span></div>
602
+ <div class="fe-editor-kb"><kbd>Tab</kbd> <span>Indent</span></div>
603
+ <div class="fe-editor-kb"><kbd>Shift+Tab</kbd> <span>Unindent</span></div>
604
+ <div class="fe-editor-kb"><kbd>Enter</kbd> <span>Auto-indent</span></div>
605
+ <div class="fe-editor-kb"><kbd>Esc</kbd> <span>Close panel</span></div>
606
+ </div>
607
+ </div>
608
+ <div class="fe-editor-sep"></div>
609
+ <div class="fe-editor-view-toggle" id="fe-editor-view-toggle" style="display:none">
610
+ <button class="fe-editor-toggle-btn active" data-mode="raw">Raw</button>
611
+ <button class="fe-editor-toggle-btn" data-mode="preview">Preview</button>
612
+ </div>
613
+ <div class="fe-editor-sep" id="fe-editor-sep-preview" style="display:none"></div>
614
+ <button class="fe-editor-btn" id="fe-editor-discard" disabled>Discard</button>
615
+ <button class="fe-editor-btn fe-editor-save" id="fe-editor-save" disabled>Save</button>
616
+ <button class="fe-editor-btn" id="fe-editor-close">Close</button>
617
+ </div>
618
+ <div class="fe-editor-find" id="fe-editor-find">
619
+ <div class="fe-editor-find-row">
620
+ <input type="text" class="fe-editor-find-input" id="fe-editor-find-input" placeholder="Find..." spellcheck="false" autocomplete="off" />
621
+ <span class="fe-editor-find-count" id="fe-editor-find-count"></span>
622
+ <button class="fe-editor-find-nav" id="fe-editor-find-prev" data-tooltip="Previous">
623
+ <svg viewBox="0 0 24 24"><polyline points="18 15 12 9 6 15"/></svg>
624
+ </button>
625
+ <button class="fe-editor-find-nav" id="fe-editor-find-next" data-tooltip="Next">
626
+ <svg viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
627
+ </button>
628
+ <button class="fe-editor-find-nav" id="fe-editor-find-close" data-tooltip="Close">
629
+ <svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
630
+ </button>
631
+ </div>
632
+ <div class="fe-editor-replace-row">
633
+ <input type="text" class="fe-editor-replace-input" id="fe-editor-replace-input" placeholder="Replace..." spellcheck="false" autocomplete="off" />
634
+ <button class="fe-editor-replace-btn" id="fe-editor-replace">Replace</button>
635
+ <button class="fe-editor-replace-btn" id="fe-editor-replace-all">All</button>
636
+ </div>
637
+ </div>
638
+ <div class="fe-editor-goto" id="fe-editor-goto">
639
+ <span class="fe-editor-goto-label">Go to Line</span>
640
+ <input type="number" class="fe-editor-goto-input" id="fe-editor-goto-input" min="1" placeholder="Line..." />
641
+ </div>
642
+ <div class="fe-editor-body">
643
+ <div class="fe-editor-gutter" id="fe-editor-gutter"></div>
644
+ <div class="fe-editor-line-highlight" id="fe-editor-line-highlight"></div>
645
+ <pre class="fe-editor-highlight" id="fe-editor-highlight" aria-hidden="true"><code id="fe-editor-highlight-code"></code></pre>
646
+ <textarea class="fe-editor-textarea" id="fe-editor-textarea"
647
+ spellcheck="false" autocorrect="off" autocapitalize="off"></textarea>
648
+ <div class="fe-editor-preview" id="fe-editor-preview"></div>
649
+ <div class="fe-editor-scrollmap" id="fe-editor-scrollmap">
650
+ <div class="fe-editor-scrollmap-thumb" id="fe-editor-scrollmap-thumb"></div>
651
+ </div>
652
+ </div>
653
+ <div class="fe-editor-statusbar">
654
+ <span id="fe-editor-lang"></span>
655
+ <div style="flex:1"></div>
656
+ <span id="fe-editor-cursor">Ln 1, Col 1</span>
657
+ <span class="fe-editor-sep"></span>
658
+ <span id="fe-editor-size"></span>
659
+ <span class="fe-editor-sep"></span>
660
+ <span>UTF-8</span>
661
+ </div>
662
+ </div>
663
+
664
+ <!-- Detail cards are spawned dynamically by ui-detail.js -->
665
+
666
+ <!-- Multi-select Action Bar -->
667
+ <div id="multi-select-bar" class="glass">
668
+ <span id="multi-select-count">0 ${t('multiselect.selected.other', { count: '' }).trim()}</span>
669
+ <button id="multi-select-move-cat">${t('multiselect.move')}</button>
670
+ <button id="multi-select-export">${t('multiselect.export')}</button>
671
+ <button id="multi-select-trash">${t('multiselect.trash')}</button>
672
+ <button id="multi-select-clear">${t('multiselect.clear')}</button>
673
+ </div>
674
+
675
+ <!-- Stats Bar -->
676
+ <div id="stats-bar" class="glass">
677
+ <div>${t('stats.memories')} <span class="stat-value" id="stat-total">0</span></div>
678
+ <div class="stat-divider"></div>
679
+ <div>${t('stats.visible')} <span class="stat-value" id="stat-visible">0</span></div>
680
+ <div class="stat-divider"></div>
681
+ <div>${t('stats.links')} <span class="stat-value" id="stat-links">0</span></div>
682
+ <div class="stat-divider"></div>
683
+ <div id="stat-search-status"></div>
684
+ </div>
685
+
686
+ <!-- Static background (shown in Focus Mode) -->
687
+ <div id="static-bg">
688
+ <div class="focus-breathe"></div>
689
+ <img src="synabun.png?v=2" alt="SynaBun" class="static-bg-logo">
690
+
691
+ <!-- Whiteboard (Focus Mode canvas) -->
692
+ <div id="wb-root">
693
+ <div id="wb-toolbar" class="glass">
694
+ <button class="wb-tool active" data-tool="select" data-tooltip="Select">
695
+ <svg viewBox="0 0 24 24"><path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/></svg>
696
+ </button>
697
+ <button class="wb-tool" id="wb-multiselect" data-tooltip="Multi-select (M)">
698
+ <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="1" fill="none" stroke-dasharray="3 2"/><path d="M8 2v2M14 2v2M20 8h2M20 14h2M8 20v2M14 20v2M2 8h2M2 14h2"/></svg>
699
+ </button>
700
+ <button class="wb-tool" data-tool="text" data-tooltip="Text · hold Ctrl = multi">
701
+ <svg viewBox="0 0 24 24"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" y1="20" x2="15" y2="20"/><line x1="12" y1="4" x2="12" y2="20"/></svg>
702
+ </button>
703
+ <button class="wb-tool" data-tool="list" data-tooltip="List · hold Ctrl = multi">
704
+ <svg viewBox="0 0 24 24"><line x1="9" y1="6" x2="20" y2="6"/><line x1="9" y1="12" x2="20" y2="12"/><line x1="9" y1="18" x2="20" y2="18"/><circle cx="4" cy="6" r="1.5" fill="currentColor"/><circle cx="4" cy="12" r="1.5" fill="currentColor"/><circle cx="4" cy="18" r="1.5" fill="currentColor"/></svg>
705
+ </button>
706
+ <button class="wb-tool" data-tool="arrow" data-tooltip="Arrow · hold Ctrl = multi">
707
+ <svg viewBox="0 0 24 24" fill="none"><path d="M5 17L17 5" stroke-width="2" stroke-linecap="round"/><path d="M17 5L10 5M17 5L17 12" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
708
+ </button>
709
+ <button class="wb-tool" data-tool="shape" data-tooltip="Shape · hold Ctrl = multi">
710
+ <svg viewBox="0 0 24 24" fill="none"><rect x="3" y="3" width="18" height="18" rx="3"/></svg>
711
+ </button>
712
+ <div id="wb-shape-picker" class="glass" style="display:none;"></div>
713
+ <button class="wb-tool" data-tool="pen" data-tooltip="Pencil · hold Ctrl = multi">
714
+ <svg viewBox="0 0 24 24"><path d="M17 3a2.83 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg>
715
+ </button>
716
+ <button class="wb-tool" data-tool="section" data-tooltip="Wireframe section · hold Ctrl = multi">
717
+ <svg viewBox="0 0 24 24" fill="none"><rect x="2" y="3" width="20" height="4" rx="1"/><rect x="2" y="9" width="6" height="12" rx="1"/><rect x="10" y="9" width="12" height="7" rx="1"/><rect x="10" y="18" width="12" height="3" rx="1"/></svg>
718
+ </button>
719
+ <div id="wb-section-picker" class="glass" style="display:none;"></div>
720
+ <div class="wb-tool-sep"></div>
721
+ <button class="wb-tool" id="wb-color-btn" data-tooltip="Color">
722
+ <span id="wb-color-dot"></span>
723
+ </button>
724
+ <div id="wb-color-picker" class="glass" style="display:none;"></div>
725
+ <div class="wb-tool-sep"></div>
726
+ <button class="wb-tool" id="wb-undo" data-tooltip="Undo (Ctrl+Z)">
727
+ <svg viewBox="0 0 24 24"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>
728
+ </button>
729
+ <button class="wb-tool" id="wb-redo" data-tooltip="Redo (Ctrl+Shift+Z)">
730
+ <svg viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
731
+ </button>
732
+ <div class="wb-tool-sep"></div>
733
+ <button class="wb-tool" id="wb-delete" data-tooltip="Delete (Del)">
734
+ <svg viewBox="0 0 24 24"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
735
+ </button>
736
+ <div class="wb-tool-sep"></div>
737
+ <button class="wb-tool wb-tool-sm" id="wb-toggle-logo" data-tooltip="Toggle logo">
738
+ <img src="logo-synabun.png" alt="" style="width:18px;height:auto;opacity:0.6;">
739
+ </button>
740
+ </div>
741
+
742
+ <div id="wb-canvas">
743
+ <svg id="wb-arrows" class="wb-arrow-layer">
744
+ <defs>
745
+ <marker id="wb-arrowhead" markerWidth="20" markerHeight="20" refX="2" refY="10" orient="auto" markerUnits="userSpaceOnUse" overflow="visible">
746
+ <path d="M 2 2 L 18 10 L 2 18 Z" fill="rgba(255,255,255,0.9)" stroke="none"/>
747
+ </marker>
748
+ <marker id="wb-arrowhead-sel" markerWidth="20" markerHeight="20" refX="2" refY="10" orient="auto" markerUnits="userSpaceOnUse" overflow="visible">
749
+ <path d="M 2 2 L 18 10 L 2 18 Z" fill="var(--accent-blue, #60a5fa)" stroke="none"/>
750
+ </marker>
751
+ </defs>
752
+ </svg>
753
+ <div id="wb-elements"></div>
754
+ </div>
755
+
756
+ <svg id="wb-arrow-preview" class="wb-arrow-preview">
757
+ <defs>
758
+ <marker id="wb-arrowhead-preview" markerWidth="20" markerHeight="20" refX="2" refY="10" orient="auto" markerUnits="userSpaceOnUse" overflow="visible">
759
+ <path d="M 2 2 L 18 10 L 2 18 Z" fill="rgba(255,255,255,0.3)" stroke="none"/>
760
+ </marker>
761
+ </defs>
762
+ </svg>
763
+ </div>
764
+ </div>
765
+
766
+ <!-- Graph Container -->
767
+ <div id="graph-container"></div>
768
+ `;
769
+ }
770
+
771
+ /**
772
+ * Inject the shared HTML shell into the document body.
773
+ * Call this once at the start of variant main.js, BEFORE any DOM queries.
774
+ */
775
+ export function injectSharedHTML() {
776
+ document.body.insertAdjacentHTML('afterbegin', getSharedHTML());
777
+ }