synthos 0.8.0 → 0.10.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 (368) hide show
  1. package/README.md +1 -1
  2. package/default-pages/application/page.html +42 -0
  3. package/default-pages/application/page.json +10 -0
  4. package/default-pages/elevenlabs_effects_studio/page.html +1363 -0
  5. package/default-pages/elevenlabs_effects_studio/page.json +11 -0
  6. package/default-pages/elevenlabs_voice_studio/page.html +801 -0
  7. package/default-pages/elevenlabs_voice_studio/page.json +11 -0
  8. package/default-pages/{json_tools.html → json_tools/page.html} +13 -11
  9. package/default-pages/json_tools/page.json +10 -0
  10. package/default-pages/my_notes/notes/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json +5 -0
  11. package/default-pages/my_notes/page.html +132 -0
  12. package/default-pages/{my_notes.json → my_notes/page.json} +2 -2
  13. package/default-pages/neon_asteroids/files/Ambient_Space.mp3 +0 -0
  14. package/default-pages/neon_asteroids/files/Ambient_Space2.mp3 +0 -0
  15. package/default-pages/neon_asteroids/files/Ambient_Space3.mp3 +0 -0
  16. package/default-pages/neon_asteroids/files/Asteroid_Explosion.mp3 +0 -0
  17. package/default-pages/neon_asteroids/files/Hyperspace_Jump.mp3 +0 -0
  18. package/default-pages/neon_asteroids/files/Laser_Fire.mp3 +0 -0
  19. package/default-pages/neon_asteroids/files/Menu_Navigate.mp3 +0 -0
  20. package/default-pages/neon_asteroids/files/Power_Up_Collect.mp3 +0 -0
  21. package/default-pages/neon_asteroids/files/Saucer_Alert.mp3 +0 -0
  22. package/default-pages/neon_asteroids/files/Ship_Thrust.mp3 +0 -0
  23. package/default-pages/neon_asteroids/files/effects.json +74 -0
  24. package/default-pages/neon_asteroids/page.html +1803 -0
  25. package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
  26. package/default-pages/{oregon_trail.html → oregon_trail/page.html} +16 -30
  27. package/default-pages/{oregon_trail.json → oregon_trail/page.json} +2 -2
  28. package/default-pages/retro_game_starter/page.html +1308 -0
  29. package/default-pages/retro_game_starter/page.json +12 -0
  30. package/default-pages/{sidebar_page.html → sidebar_page/page.html} +12 -10
  31. package/default-pages/sidebar_page/page.json +10 -0
  32. package/default-pages/{solar_explorer.html → solar_explorer/page.html} +15 -12
  33. package/default-pages/{solar_explorer.json → solar_explorer/page.json} +2 -2
  34. package/default-pages/{solar_tutorial.html → solar_tutorial/page.html} +12 -10
  35. package/default-pages/solar_tutorial/page.json +10 -0
  36. package/default-pages/{two-panel_page.html → two-panel_page/page.html} +13 -11
  37. package/default-pages/two-panel_page/page.json +10 -0
  38. package/default-pages/{us_map.html → us_map/page.html} +193 -192
  39. package/default-pages/{us_map.json → us_map/page.json} +12 -12
  40. package/default-pages/{us_map_1850.html → us_map_1850/page.html} +326 -325
  41. package/default-pages/{us_map_1850.json → us_map_1850/page.json} +12 -12
  42. package/default-pages/{western_cities_1850.html → western_cities_1850/page.html} +527 -526
  43. package/default-pages/{western_cities_1850.json → western_cities_1850/page.json} +12 -12
  44. package/default-themes/aurora-dawn.json +19 -0
  45. package/default-themes/aurora-dawn.v3.css +198 -0
  46. package/default-themes/aurora-dusk.json +19 -0
  47. package/default-themes/aurora-dusk.v3.css +200 -0
  48. package/default-themes/cosmos-dawn.json +19 -0
  49. package/default-themes/cosmos-dawn.v3.css +198 -0
  50. package/default-themes/cosmos-dusk.json +19 -0
  51. package/default-themes/cosmos-dusk.v3.css +200 -0
  52. package/default-themes/high-contrast-dark.json +19 -0
  53. package/default-themes/high-contrast-dark.v3.css +200 -0
  54. package/default-themes/high-contrast-light.json +19 -0
  55. package/default-themes/high-contrast-light.v3.css +198 -0
  56. package/default-themes/nebula-dawn.v2.css +110 -0
  57. package/default-themes/nebula-dawn.v3.css +199 -0
  58. package/default-themes/nebula-dusk.v2.css +104 -0
  59. package/default-themes/nebula-dusk.v3.css +201 -0
  60. package/default-themes/solar-flare-dawn.json +19 -0
  61. package/default-themes/solar-flare-dawn.v3.css +198 -0
  62. package/default-themes/solar-flare-dusk.json +19 -0
  63. package/default-themes/solar-flare-dusk.v3.css +200 -0
  64. package/dist/agents/index.d.ts +1 -1
  65. package/dist/agents/index.d.ts.map +1 -1
  66. package/dist/agents/index.js +2 -1
  67. package/dist/agents/index.js.map +1 -1
  68. package/dist/agents/openclaw/gatewayManager.d.ts +4 -0
  69. package/dist/agents/openclaw/gatewayManager.d.ts.map +1 -1
  70. package/dist/agents/openclaw/gatewayManager.js +27 -11
  71. package/dist/agents/openclaw/gatewayManager.js.map +1 -1
  72. package/dist/agents/openclaw/openclawProvider.d.ts.map +1 -1
  73. package/dist/agents/openclaw/openclawProvider.js +2 -4
  74. package/dist/agents/openclaw/openclawProvider.js.map +1 -1
  75. package/dist/agents/openclaw/sshTunnelManager.d.ts +2 -0
  76. package/dist/agents/openclaw/sshTunnelManager.d.ts.map +1 -1
  77. package/dist/agents/openclaw/sshTunnelManager.js +31 -12
  78. package/dist/agents/openclaw/sshTunnelManager.js.map +1 -1
  79. package/dist/builders/anthropic.d.ts +31 -0
  80. package/dist/builders/anthropic.d.ts.map +1 -0
  81. package/dist/builders/anthropic.js +227 -0
  82. package/dist/builders/anthropic.js.map +1 -0
  83. package/dist/builders/fireworksai.d.ts +9 -0
  84. package/dist/builders/fireworksai.d.ts.map +1 -0
  85. package/dist/builders/fireworksai.js +57 -0
  86. package/dist/builders/fireworksai.js.map +1 -0
  87. package/dist/builders/index.d.ts +13 -0
  88. package/dist/builders/index.d.ts.map +1 -0
  89. package/dist/builders/index.js +31 -0
  90. package/dist/builders/index.js.map +1 -0
  91. package/dist/builders/openai.d.ts +8 -0
  92. package/dist/builders/openai.d.ts.map +1 -0
  93. package/dist/builders/openai.js +87 -0
  94. package/dist/builders/openai.js.map +1 -0
  95. package/dist/builders/types.d.ts +54 -0
  96. package/dist/builders/types.d.ts.map +1 -0
  97. package/dist/builders/types.js +211 -0
  98. package/dist/builders/types.js.map +1 -0
  99. package/dist/connectors/index.d.ts +1 -1
  100. package/dist/connectors/index.d.ts.map +1 -1
  101. package/dist/connectors/index.js +3 -2
  102. package/dist/connectors/index.js.map +1 -1
  103. package/dist/connectors/registry.d.ts +2 -1
  104. package/dist/connectors/registry.d.ts.map +1 -1
  105. package/dist/connectors/registry.js +31 -8
  106. package/dist/connectors/registry.js.map +1 -1
  107. package/dist/customizer/Customizer.d.ts +62 -0
  108. package/dist/customizer/Customizer.d.ts.map +1 -0
  109. package/dist/customizer/Customizer.js +134 -0
  110. package/dist/customizer/Customizer.js.map +1 -0
  111. package/dist/customizer/index.d.ts +4 -0
  112. package/dist/customizer/index.d.ts.map +1 -0
  113. package/dist/customizer/index.js +9 -0
  114. package/dist/customizer/index.js.map +1 -0
  115. package/dist/files.d.ts +16 -0
  116. package/dist/files.d.ts.map +1 -1
  117. package/dist/files.js +60 -1
  118. package/dist/files.js.map +1 -1
  119. package/dist/index.d.ts +2 -0
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +2 -0
  122. package/dist/index.js.map +1 -1
  123. package/dist/init.d.ts +12 -6
  124. package/dist/init.d.ts.map +1 -1
  125. package/dist/init.js +150 -133
  126. package/dist/init.js.map +1 -1
  127. package/dist/migrations.d.ts.map +1 -1
  128. package/dist/migrations.js +23 -10
  129. package/dist/migrations.js.map +1 -1
  130. package/dist/models/anthropic.d.ts +4 -2
  131. package/dist/models/anthropic.d.ts.map +1 -1
  132. package/dist/models/anthropic.js +33 -6
  133. package/dist/models/anthropic.js.map +1 -1
  134. package/dist/models/fireworksai.d.ts.map +1 -1
  135. package/dist/models/fireworksai.js +9 -1
  136. package/dist/models/fireworksai.js.map +1 -1
  137. package/dist/models/index.d.ts +1 -1
  138. package/dist/models/index.d.ts.map +1 -1
  139. package/dist/models/index.js +2 -1
  140. package/dist/models/index.js.map +1 -1
  141. package/dist/models/openai.d.ts +1 -1
  142. package/dist/models/openai.d.ts.map +1 -1
  143. package/dist/models/openai.js +24 -3
  144. package/dist/models/openai.js.map +1 -1
  145. package/dist/models/types.d.ts +20 -1
  146. package/dist/models/types.d.ts.map +1 -1
  147. package/dist/models/types.js +6 -1
  148. package/dist/models/types.js.map +1 -1
  149. package/dist/pages.d.ts +34 -10
  150. package/dist/pages.d.ts.map +1 -1
  151. package/dist/pages.js +229 -79
  152. package/dist/pages.js.map +1 -1
  153. package/dist/service/createCompletePrompt.d.ts +2 -1
  154. package/dist/service/createCompletePrompt.d.ts.map +1 -1
  155. package/dist/service/createCompletePrompt.js +2 -2
  156. package/dist/service/createCompletePrompt.js.map +1 -1
  157. package/dist/service/requiresSettings.d.ts +2 -1
  158. package/dist/service/requiresSettings.d.ts.map +1 -1
  159. package/dist/service/requiresSettings.js +3 -3
  160. package/dist/service/requiresSettings.js.map +1 -1
  161. package/dist/service/server.d.ts +2 -1
  162. package/dist/service/server.d.ts.map +1 -1
  163. package/dist/service/server.js +37 -8
  164. package/dist/service/server.js.map +1 -1
  165. package/dist/service/transformPage.d.ts +47 -20
  166. package/dist/service/transformPage.d.ts.map +1 -1
  167. package/dist/service/transformPage.js +514 -293
  168. package/dist/service/transformPage.js.map +1 -1
  169. package/dist/service/useAgentRoutes.d.ts +2 -1
  170. package/dist/service/useAgentRoutes.d.ts.map +1 -1
  171. package/dist/service/useAgentRoutes.js +17 -14
  172. package/dist/service/useAgentRoutes.js.map +1 -1
  173. package/dist/service/useApiRoutes.d.ts +2 -1
  174. package/dist/service/useApiRoutes.d.ts.map +1 -1
  175. package/dist/service/useApiRoutes.js +287 -172
  176. package/dist/service/useApiRoutes.js.map +1 -1
  177. package/dist/service/useConnectorRoutes.js +17 -17
  178. package/dist/service/useConnectorRoutes.js.map +1 -1
  179. package/dist/service/useDataRoutes.d.ts.map +1 -1
  180. package/dist/service/useDataRoutes.js +13 -10
  181. package/dist/service/useDataRoutes.js.map +1 -1
  182. package/dist/service/useFileRoutes.d.ts +4 -0
  183. package/dist/service/useFileRoutes.d.ts.map +1 -0
  184. package/dist/service/useFileRoutes.js +122 -0
  185. package/dist/service/useFileRoutes.js.map +1 -0
  186. package/dist/service/usePageRoutes.d.ts +2 -1
  187. package/dist/service/usePageRoutes.d.ts.map +1 -1
  188. package/dist/service/usePageRoutes.js +671 -74
  189. package/dist/service/usePageRoutes.js.map +1 -1
  190. package/dist/service/useSharedDataRoutes.d.ts +4 -0
  191. package/dist/service/useSharedDataRoutes.d.ts.map +1 -0
  192. package/dist/service/useSharedDataRoutes.js +107 -0
  193. package/dist/service/useSharedDataRoutes.js.map +1 -0
  194. package/dist/service/useSharedFileRoutes.d.ts +4 -0
  195. package/dist/service/useSharedFileRoutes.d.ts.map +1 -0
  196. package/dist/service/useSharedFileRoutes.js +121 -0
  197. package/dist/service/useSharedFileRoutes.js.map +1 -0
  198. package/dist/settings.d.ts +5 -3
  199. package/dist/settings.d.ts.map +1 -1
  200. package/dist/settings.js +12 -10
  201. package/dist/settings.js.map +1 -1
  202. package/dist/storage/FsStorageProvider.d.ts +25 -0
  203. package/dist/storage/FsStorageProvider.d.ts.map +1 -0
  204. package/dist/storage/FsStorageProvider.js +103 -0
  205. package/dist/storage/FsStorageProvider.js.map +1 -0
  206. package/dist/storage/StorageProvider.d.ts +31 -0
  207. package/dist/storage/StorageProvider.d.ts.map +1 -0
  208. package/dist/storage/StorageProvider.js +3 -0
  209. package/dist/storage/StorageProvider.js.map +1 -0
  210. package/dist/storage/index.d.ts +3 -0
  211. package/dist/storage/index.d.ts.map +1 -0
  212. package/dist/storage/index.js +6 -0
  213. package/dist/storage/index.js.map +1 -0
  214. package/dist/synthos-cli.d.ts.map +1 -1
  215. package/dist/synthos-cli.js +4 -3
  216. package/dist/synthos-cli.js.map +1 -1
  217. package/dist/themes.d.ts +1 -0
  218. package/dist/themes.d.ts.map +1 -1
  219. package/dist/themes.js +65 -28
  220. package/dist/themes.js.map +1 -1
  221. package/migration-rules/v1-to-v2.md +193 -0
  222. package/migration-rules/v2-to-v3.md +481 -0
  223. package/package.json +11 -10
  224. package/required-pages/builder/page.html +43 -0
  225. package/required-pages/builder/page.json +10 -0
  226. package/required-pages/{pages.html → pages/page.html} +238 -233
  227. package/required-pages/pages/page.json +10 -0
  228. package/required-pages/{settings.html → settings/page.html} +389 -275
  229. package/required-pages/settings/page.json +10 -0
  230. package/required-pages/synthos_apis/page.html +846 -0
  231. package/required-pages/synthos_apis/page.json +10 -0
  232. package/required-pages/{synthos_scripts.html → synthos_scripts/page.html} +13 -11
  233. package/required-pages/synthos_scripts/page.json +10 -0
  234. package/src/agents/index.ts +1 -1
  235. package/src/agents/openclaw/gatewayManager.ts +22 -11
  236. package/src/agents/openclaw/openclawProvider.ts +2 -4
  237. package/src/agents/openclaw/sshTunnelManager.ts +19 -11
  238. package/src/builders/anthropic.ts +283 -0
  239. package/src/builders/fireworksai.ts +59 -0
  240. package/src/builders/index.ts +33 -0
  241. package/src/builders/openai.ts +89 -0
  242. package/src/builders/types.ts +261 -0
  243. package/src/connectors/index.ts +1 -1
  244. package/src/connectors/registry.ts +28 -8
  245. package/src/customizer/Customizer.ts +163 -0
  246. package/src/customizer/index.ts +5 -0
  247. package/src/files.ts +57 -0
  248. package/src/index.ts +3 -1
  249. package/src/init.ts +195 -145
  250. package/src/migrations.ts +30 -10
  251. package/src/models/anthropic.ts +40 -10
  252. package/src/models/fireworksai.ts +9 -2
  253. package/src/models/index.ts +1 -1
  254. package/src/models/openai.ts +26 -6
  255. package/src/models/types.ts +31 -1
  256. package/src/pages.ts +230 -77
  257. package/src/service/createCompletePrompt.ts +3 -2
  258. package/src/service/requiresSettings.ts +4 -3
  259. package/src/service/server.ts +36 -9
  260. package/src/service/transformPage.ts +557 -326
  261. package/src/service/useAgentRoutes.ts +19 -14
  262. package/src/service/useApiRoutes.ts +208 -84
  263. package/src/service/useConnectorRoutes.ts +18 -18
  264. package/src/service/useDataRoutes.ts +13 -10
  265. package/src/service/useFileRoutes.ts +128 -0
  266. package/src/service/usePageRoutes.ts +730 -81
  267. package/src/service/useSharedDataRoutes.ts +109 -0
  268. package/src/service/useSharedFileRoutes.ts +127 -0
  269. package/src/settings.ts +14 -10
  270. package/src/storage/FsStorageProvider.ts +87 -0
  271. package/src/storage/StorageProvider.ts +34 -0
  272. package/src/storage/index.ts +2 -0
  273. package/src/synthos-cli.ts +4 -3
  274. package/src/themes.ts +64 -27
  275. package/static-files/favicon.svg +12 -0
  276. package/static-files/fluentlm-instructions.llmd +868 -0
  277. package/static-files/fluentlm-instructions.md +1595 -0
  278. package/static-files/fluentlm.css +4844 -0
  279. package/static-files/fluentlm.js +3602 -0
  280. package/static-files/fluentlm.min.css +1 -0
  281. package/static-files/fluentlm.min.js +1 -0
  282. package/{page-scripts/helpers-v2.js → static-files/helpers.v3.js} +82 -0
  283. package/static-files/page.v3.js +1290 -0
  284. package/static-files/recommended-frameworks.llmd +81 -0
  285. package/static-files/recommended-frameworks.md +137 -0
  286. package/static-files/retro-game.js +877 -0
  287. package/static-files/shell.css +797 -0
  288. package/static-files/theme-dark.css +169 -0
  289. package/static-files/theme-light.css +169 -0
  290. package/tests/builders.spec.ts +139 -0
  291. package/tests/pages.spec.ts +54 -84
  292. package/tests/transformPage.spec.ts +299 -360
  293. package/default-pages/application.html +0 -40
  294. package/default-pages/application.json +0 -1
  295. package/default-pages/json_tools.json +0 -1
  296. package/default-pages/my_notes.html +0 -33
  297. package/default-pages/neon_asteroids.html +0 -77
  298. package/default-pages/sidebar_page.json +0 -1
  299. package/default-pages/solar_tutorial.json +0 -1
  300. package/default-pages/two-panel_page.json +0 -1
  301. package/dist/service/useGatewayRoutes.d.ts +0 -4
  302. package/dist/service/useGatewayRoutes.d.ts.map +0 -1
  303. package/dist/service/useGatewayRoutes.js +0 -168
  304. package/dist/service/useGatewayRoutes.js.map +0 -1
  305. package/page-scripts/page-v2.js +0 -656
  306. package/required-pages/builder.html +0 -48
  307. package/required-pages/builder.json +0 -1
  308. package/required-pages/pages.json +0 -1
  309. package/required-pages/settings.json +0 -1
  310. package/required-pages/synthos_apis.html +0 -327
  311. package/required-pages/synthos_apis.json +0 -1
  312. package/required-pages/synthos_scripts.json +0 -1
  313. package/src/connectors/airtable/connector.json +0 -27
  314. package/src/connectors/alpha-vantage/connector.json +0 -26
  315. package/src/connectors/brave-search/connector.json +0 -26
  316. package/src/connectors/cloudinary/connector.json +0 -27
  317. package/src/connectors/deepl/connector.json +0 -28
  318. package/src/connectors/elevenlabs/connector.json +0 -30
  319. package/src/connectors/giphy/connector.json +0 -27
  320. package/src/connectors/github/connector.json +0 -29
  321. package/src/connectors/huggingface/connector.json +0 -27
  322. package/src/connectors/imgur/connector.json +0 -29
  323. package/src/connectors/instagram/connector.json +0 -43
  324. package/src/connectors/jira/connector.json +0 -28
  325. package/src/connectors/mapbox/connector.json +0 -26
  326. package/src/connectors/nasa/connector.json +0 -27
  327. package/src/connectors/newsapi/connector.json +0 -27
  328. package/src/connectors/notion/connector.json +0 -28
  329. package/src/connectors/open-exchange-rates/connector.json +0 -27
  330. package/src/connectors/openweathermap/connector.json +0 -26
  331. package/src/connectors/pexels/connector.json +0 -27
  332. package/src/connectors/resend/connector.json +0 -29
  333. package/src/connectors/rss2json/connector.json +0 -27
  334. package/src/connectors/sendgrid/connector.json +0 -27
  335. package/src/connectors/spoonacular/connector.json +0 -28
  336. package/src/connectors/stability-ai/connector.json +0 -27
  337. package/src/connectors/twilio/connector.json +0 -28
  338. package/src/connectors/unsplash/connector.json +0 -27
  339. package/src/connectors/wolfram-alpha/connector.json +0 -26
  340. package/src/connectors/youtube-data/connector.json +0 -30
  341. /package/{dist/connectors → service-connectors}/airtable/connector.json +0 -0
  342. /package/{dist/connectors → service-connectors}/alpha-vantage/connector.json +0 -0
  343. /package/{dist/connectors → service-connectors}/brave-search/connector.json +0 -0
  344. /package/{dist/connectors → service-connectors}/cloudinary/connector.json +0 -0
  345. /package/{dist/connectors → service-connectors}/deepl/connector.json +0 -0
  346. /package/{dist/connectors → service-connectors}/elevenlabs/connector.json +0 -0
  347. /package/{dist/connectors → service-connectors}/giphy/connector.json +0 -0
  348. /package/{dist/connectors → service-connectors}/github/connector.json +0 -0
  349. /package/{dist/connectors → service-connectors}/huggingface/connector.json +0 -0
  350. /package/{dist/connectors → service-connectors}/imgur/connector.json +0 -0
  351. /package/{dist/connectors → service-connectors}/instagram/connector.json +0 -0
  352. /package/{dist/connectors → service-connectors}/jira/connector.json +0 -0
  353. /package/{dist/connectors → service-connectors}/mapbox/connector.json +0 -0
  354. /package/{dist/connectors → service-connectors}/nasa/connector.json +0 -0
  355. /package/{dist/connectors → service-connectors}/newsapi/connector.json +0 -0
  356. /package/{dist/connectors → service-connectors}/notion/connector.json +0 -0
  357. /package/{dist/connectors → service-connectors}/open-exchange-rates/connector.json +0 -0
  358. /package/{dist/connectors → service-connectors}/openweathermap/connector.json +0 -0
  359. /package/{dist/connectors → service-connectors}/pexels/connector.json +0 -0
  360. /package/{dist/connectors → service-connectors}/resend/connector.json +0 -0
  361. /package/{dist/connectors → service-connectors}/rss2json/connector.json +0 -0
  362. /package/{dist/connectors → service-connectors}/sendgrid/connector.json +0 -0
  363. /package/{dist/connectors → service-connectors}/spoonacular/connector.json +0 -0
  364. /package/{dist/connectors → service-connectors}/stability-ai/connector.json +0 -0
  365. /package/{dist/connectors → service-connectors}/twilio/connector.json +0 -0
  366. /package/{dist/connectors → service-connectors}/unsplash/connector.json +0 -0
  367. /package/{dist/connectors → service-connectors}/wolfram-alpha/connector.json +0 -0
  368. /package/{dist/connectors → service-connectors}/youtube-data/connector.json +0 -0
@@ -5,8 +5,8 @@
5
5
  ],
6
6
  "pinned": false,
7
7
  "showInAll": true,
8
- "createdDate": "2026-02-13T03:18:30.368Z",
9
- "lastModified": "2026-02-13T03:20:42.803Z",
10
- "pageVersion": 2,
8
+ "createdDate": "2026-03-02T21:38:41.912Z",
9
+ "lastModified": "2026-03-02T21:38:41.912Z",
10
+ "pageVersion": 3,
11
11
  "mode": "unlocked"
12
12
  }
@@ -8,43 +8,29 @@
8
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
9
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
10
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
11
12
  <script id="page-info" src="/api/page-info.js?page=builder"></script>
12
- <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js" id="topojson-lib"></script><style id="us-map-styles">#us-map-container{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden}#us-map-header{min-height:var(--header-min-height);padding:var(--header-padding-vertical) var(--header-padding-horizontal);line-height:var(--header-line-height);display:flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:1.25rem;font-weight:600;color:var(--text-primary);width:100%;border-bottom:1px solid var(--border-color);background:var(--bg-secondary);flex-shrink:0;position:relative}#us-map-svg-wrap{flex:1;width:100%;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;position:relative}#us-map-svg-wrap svg{width:100%;height:100%;position:absolute;top:0;left:0}.region-path{cursor:pointer;transition:filter .2s ease;stroke-linejoin:round}.region-path:hover{filter:brightness(1.25)}.region-state{fill:rgba(46,125,50,0.5);stroke:#1b5e20;stroke-width:1.2}.region-oregon{fill:rgba(230,81,0,0.45);stroke:#bf360c;stroke-width:1.5}.region-minnesota{fill:rgba(255,152,0,0.45);stroke:#e65100;stroke-width:1.5}.region-utah{fill:rgba(255,111,0,0.4);stroke:#bf360c;stroke-width:1.5}.region-newmexico{fill:rgba(239,108,0,0.45);stroke:#bf360c;stroke-width:1.5}.region-unorganized{fill:rgba(141,110,99,0.4);stroke:#4e342e;stroke-width:1.5}.region-indian{fill:rgba(121,85,72,0.45);stroke:#3e2723;stroke-width:1.5}.light-mode .region-state{fill:rgba(46,125,50,0.5);stroke:#1b5e20}.light-mode .region-oregon{fill:rgba(230,81,0,0.45);stroke:#bf360c}.light-mode .region-minnesota{fill:rgba(255,152,0,0.45);stroke:#e65100}.light-mode .region-utah{fill:rgba(255,111,0,0.4);stroke:#bf360c}.light-mode .region-newmexico{fill:rgba(239,108,0,0.45);stroke:#bf360c}.light-mode .region-unorganized{fill:rgba(141,110,99,0.4);stroke:#4e342e}.light-mode .region-indian{fill:rgba(121,85,72,0.45);stroke:#3e2723}#map-tooltip{position:absolute;pointer-events:none;background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-color);border-radius:6px;padding:6px 12px;font-size:0.85rem;font-weight:500;box-shadow:0 2px 8px rgba(0,0,0,0.12);opacity:0;transition:opacity .15s ease;z-index:10;white-space:nowrap}#hist-legend{position:absolute;bottom:16px;left:16px;background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:8px;padding:10px 14px;font-size:0.75rem;color:var(--text-primary);z-index:5;box-shadow:0 2px 8px rgba(0,0,0,0.1)}#hist-legend .legend-item{display:flex;align-items:center;gap:8px;margin-bottom:4px}#hist-legend .legend-item:last-child{margin-bottom:0}#hist-legend .legend-swatch{width:14px;height:14px;border-radius:3px;flex-shrink:0}.trail-path{fill:none;stroke:#d32f2f;stroke-width:3;stroke-dasharray:8,4;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 0 3px rgba(211,47,47,0.5))}.trail-path-glow{fill:none;stroke:rgba(211,47,47,0.25);stroke-width:8;stroke-linecap:round;stroke-linejoin:round}.trail-stop{cursor:pointer}.trail-stop circle.stop-outer{fill:rgba(211,47,47,0.2);stroke:#d32f2f;stroke-width:1.5;transition:r .2s ease, fill .2s ease}.trail-stop circle.stop-inner{fill:#d32f2f;transition:r .2s ease}.trail-stop:hover circle.stop-outer{fill:rgba(211,47,47,0.4)}.trail-stop.active circle.stop-outer{fill:rgba(211,47,47,0.5);stroke-width:2.5;r:9}.trail-stop.active circle.stop-inner{r:4}.trail-label{font-size:8px;font-weight:600;fill:#b71c1c;text-anchor:middle;pointer-events:none;paint-order:stroke;stroke:rgba(255,255,255,0.8);stroke-width:2.5px;stroke-linecap:round;stroke-linejoin:round}.light-mode .trail-path{stroke:#c62828}.light-mode .trail-label{fill:#b71c1c;stroke:rgba(255,255,255,0.85)}#trail-detail-card{position:absolute;top:16px;right:16px;width:340px;max-height:calc(100% - 40px);background:var(--bg-tertiary);border:1px solid var(--border-color);border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,0.15);z-index:20;opacity:0;transform:translateY(-10px) scale(0.97);pointer-events:none;transition:opacity .25s ease,transform .25s ease;overflow:hidden;display:flex;flex-direction:column}#trail-detail-card.visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}#trail-detail-card .card-header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px 8px;border-bottom:1px solid var(--border-color);background:linear-gradient(135deg,rgba(211,47,47,0.08),rgba(211,47,47,0.02));flex-shrink:0}#trail-detail-card .card-header h3{margin:0;font-size:0.95rem;font-weight:700;color:var(--text-primary);line-height:1.3}#trail-detail-card .card-header .card-close{background:none;border:none;font-size:1.3rem;cursor:pointer;color:var(--text-secondary);padding:0 2px;line-height:1;border-radius:4px;transition:background .15s ease}#trail-detail-card .card-header .card-close:hover{background:rgba(0,0,0,0.08)}#trail-detail-card .card-subtitle{font-size:0.72rem;color:var(--text-secondary);margin:2px 0 0;font-weight:500}#trail-detail-card .card-tabs{display:flex;border-bottom:1px solid var(--border-color);flex-shrink:0}#trail-detail-card .card-tab{flex:1;padding:8px 10px;font-size:0.78rem;font-weight:600;text-align:center;cursor:pointer;border:none;background:none;color:var(--text-secondary);transition:all .15s ease;border-bottom:2px solid transparent;position:relative}#trail-detail-card .card-tab:hover{color:var(--text-primary);background:rgba(0,0,0,0.03)}#trail-detail-card .card-tab.active{color:#c62828;border-bottom-color:#c62828;background:rgba(211,47,47,0.05)}#trail-detail-card .card-tab-icon{margin-right:4px}#trail-detail-card .tab-content{flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0}#trail-detail-card .tab-pane{display:none;flex:1;overflow-y:auto;flex-direction:column;min-height:0}#trail-detail-card .tab-pane.active{display:flex}#trail-detail-card .facts-pane{padding:12px 14px;overflow-y:auto}#trail-detail-card .fact-row{display:flex;gap:8px;margin-bottom:8px;align-items:flex-start}#trail-detail-card .fact-icon{font-size:1rem;flex-shrink:0;width:22px;text-align:center;margin-top:1px}#trail-detail-card .fact-content{flex:1}#trail-detail-card .fact-label{font-size:0.65rem;text-transform:uppercase;letter-spacing:0.5px;color:var(--text-secondary);font-weight:600;margin-bottom:1px}#trail-detail-card .fact-value{font-size:0.8rem;color:var(--text-primary);line-height:1.4}#trail-detail-card .card-divider{height:1px;background:var(--border-color);margin:4px 0 8px}#trail-detail-card .card-description{font-size:0.78rem;color:var(--text-primary);line-height:1.5;margin-top:2px}#trail-detail-card .mile-marker{display:inline-flex;align-items:center;gap:4px;background:rgba(211,47,47,0.1);color:#c62828;font-size:0.68rem;font-weight:600;padding:2px 7px;border-radius:12px;margin-bottom:8px}.light-mode #trail-detail-card .mile-marker{background:rgba(211,47,47,0.1);color:#b71c1c}.chat-pane{display:flex;flex-direction:column;min-height:0;flex:1}.chat-pane .chat-messages-area{flex:1;overflow-y:auto;padding:10px 12px;display:flex;flex-direction:column;gap:8px;min-height:120px}.chat-pane .chat-welcome{text-align:center;padding:16px 8px;color:var(--text-secondary);font-size:0.78rem;line-height:1.5}.chat-pane .chat-welcome .welcome-emoji{font-size:1.8rem;margin-bottom:6px;display:block}.chat-pane .chat-welcome strong{color:var(--text-primary)}.chat-pane .chat-bubble{max-width:92%;padding:8px 11px;border-radius:12px;font-size:0.78rem;line-height:1.45;word-wrap:break-word;animation:bubbleIn .2s ease}.chat-pane .chat-bubble.user-bubble{align-self:flex-end;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border-bottom-right-radius:4px}.chat-pane .chat-bubble.ai-bubble{align-self:flex-start;background:var(--bg-secondary);color:var(--text-primary);border:1px solid var(--border-color);border-bottom-left-radius:4px}.chat-pane .chat-bubble.ai-bubble.loading{opacity:0.7}.chat-pane .typing-dots{display:inline-flex;gap:3px;padding:2px 0}.chat-pane .typing-dots span{width:5px;height:5px;border-radius:50%;background:var(--text-secondary);animation:dotBounce .6s ease-in-out infinite}.chat-pane .typing-dots span:nth-child(2){animation-delay:.15s}.chat-pane .typing-dots span:nth-child(3){animation-delay:.3s}@keyframes dotBounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes bubbleIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.chat-pane .chat-input-area{display:flex;gap:6px;padding:8px 10px;border-top:1px solid var(--border-color);background:var(--bg-tertiary);flex-shrink:0;border-radius:0 0 12px 12px}.chat-pane .chat-input-field{flex:1;border:1px solid var(--border-color);border-radius:18px;padding:7px 12px;font-size:0.78rem;background:var(--bg-primary);color:var(--text-primary);outline:none;transition:border-color .15s ease;font-family:inherit}.chat-pane .chat-input-field:focus{border-color:var(--accent-primary)}.chat-pane .chat-input-field::placeholder{color:var(--text-secondary);opacity:0.7}.chat-pane .chat-send-btn{width:32px;height:32px;border-radius:50%;border:none;background:linear-gradient(135deg,#d32f2f,#b71c1c);color:#fff;font-size:0.9rem;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .1s ease,opacity .15s ease;flex-shrink:0}.chat-pane .chat-send-btn:hover{transform:scale(1.08)}.chat-pane .chat-send-btn:disabled{opacity:0.4;cursor:not-allowed;transform:none}.chat-pane .suggested-questions{display:flex;flex-wrap:wrap;gap:4px;padding:0 12px 8px}.chat-pane .suggested-q{font-size:0.68rem;padding:4px 8px;border-radius:12px;border:1px solid var(--border-color);background:var(--bg-primary);color:var(--text-secondary);cursor:pointer;transition:all .15s ease;white-space:nowrap}.chat-pane .suggested-q:hover{background:rgba(211,47,47,0.08);color:#c62828;border-color:rgba(211,47,47,0.3)}</style></head>
13
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js" id="topojson-lib"></script><style id="us-map-styles">#us-map-container{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden}#us-map-header{min-height:var(--header-min-height);padding:var(--header-padding-vertical) var(--header-padding-horizontal);line-height:var(--header-line-height);display:flex;align-items:center;justify-content:center;box-sizing:border-box;font-size:1.25rem;font-weight:600;color:var(--bodyText);width:100%;border-bottom:1px solid var(--variantBorder);background-color:var(--bodyStandoutBackground);flex-shrink:0;position:relative}#us-map-svg-wrap{flex:1;width:100%;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box;position:relative}#us-map-svg-wrap svg{width:100%;height:100%;position:absolute;top:0;left:0}.region-path{cursor:pointer;transition:filter .2s ease;stroke-linejoin:round}.region-path:hover{filter:brightness(1.25)}.region-state{fill:rgba(46,125,50,0.5);stroke:#1b5e20;stroke-width:1.2}.region-oregon{fill:rgba(230,81,0,0.45);stroke:#bf360c;stroke-width:1.5}.region-minnesota{fill:rgba(255,152,0,0.45);stroke:#e65100;stroke-width:1.5}.region-utah{fill:rgba(255,111,0,0.4);stroke:#bf360c;stroke-width:1.5}.region-newmexico{fill:rgba(239,108,0,0.45);stroke:#bf360c;stroke-width:1.5}.region-unorganized{fill:rgba(141,110,99,0.4);stroke:#4e342e;stroke-width:1.5}.region-indian{fill:rgba(121,85,72,0.45);stroke:#3e2723;stroke-width:1.5}.light-mode .region-state{fill:rgba(46,125,50,0.5);stroke:#1b5e20}.light-mode .region-oregon{fill:rgba(230,81,0,0.45);stroke:#bf360c}.light-mode .region-minnesota{fill:rgba(255,152,0,0.45);stroke:#e65100}.light-mode .region-utah{fill:rgba(255,111,0,0.4);stroke:#bf360c}.light-mode .region-newmexico{fill:rgba(239,108,0,0.45);stroke:#bf360c}.light-mode .region-unorganized{fill:rgba(141,110,99,0.4);stroke:#4e342e}.light-mode .region-indian{fill:rgba(121,85,72,0.45);stroke:#3e2723}#map-tooltip{position:absolute;pointer-events:none;background-color:var(--bodyBackground);color:var(--bodyText);border:1px solid var(--variantBorder);border-radius:var(--roundedCorner4);padding:6px 12px;font-size:0.85rem;font-weight:500;box-shadow:var(--elevation8);opacity:0;transition:opacity .15s ease;z-index:10;white-space:nowrap}#hist-legend{position:absolute;bottom:16px;left:16px;background-color:var(--bodyBackground);border:1px solid var(--variantBorder);border-radius:8px;padding:10px 14px;font-size:0.75rem;color:var(--bodyText);z-index:5;box-shadow:0 2px 8px rgba(0,0,0,0.1)}#hist-legend .legend-item{display:flex;align-items:center;gap:8px;margin-bottom:4px}#hist-legend .legend-item:last-child{margin-bottom:0}#hist-legend .legend-swatch{width:14px;height:14px;border-radius:3px;flex-shrink:0}.trail-path{fill:none;stroke:#d32f2f;stroke-width:3;stroke-dasharray:8,4;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 0 3px rgba(211,47,47,0.5))}.trail-path-glow{fill:none;stroke:rgba(211,47,47,0.25);stroke-width:8;stroke-linecap:round;stroke-linejoin:round}.trail-stop{cursor:pointer}.trail-stop circle.stop-outer{fill:rgba(211,47,47,0.2);stroke:#d32f2f;stroke-width:1.5;transition:r .2s ease, fill .2s ease}.trail-stop circle.stop-inner{fill:#d32f2f;transition:r .2s ease}.trail-stop:hover circle.stop-outer{fill:rgba(211,47,47,0.4)}.trail-stop.active circle.stop-outer{fill:rgba(211,47,47,0.5);stroke-width:2.5;r:9}.trail-stop.active circle.stop-inner{r:4}.trail-label{font-size:8px;font-weight:600;fill:#b71c1c;text-anchor:middle;pointer-events:none;paint-order:stroke;stroke:rgba(255,255,255,0.8);stroke-width:2.5px;stroke-linecap:round;stroke-linejoin:round}.light-mode .trail-path{stroke:#c62828}.light-mode .trail-label{fill:#b71c1c;stroke:rgba(255,255,255,0.85)}#trail-detail-card{position:absolute;top:16px;right:16px;width:340px;max-height:calc(100% - 40px);background-color:var(--bodyBackground);border:1px solid var(--variantBorder);border-radius:var(--roundedCorner4);box-shadow:var(--elevation64);z-index:20;opacity:0;transform:translateY(-10px) scale(0.97);pointer-events:none;transition:opacity .25s ease,transform .25s ease;overflow:hidden;display:flex;flex-direction:column}#trail-detail-card.visible{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}#trail-detail-card .card-header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px 8px;border-bottom:1px solid var(--variantBorder);background-color:var(--bodyStandoutBackground);flex-shrink:0}#trail-detail-card .card-header h3{margin:0;font-size:0.95rem;font-weight:700;color:var(--bodyText);line-height:1.3}#trail-detail-card .card-header .card-close{background:none;border:none;font-size:1.3rem;cursor:pointer;color:var(--bodySubtext);padding:0 2px;line-height:1;border-radius:4px;transition:background .15s ease}#trail-detail-card .card-header .card-close:hover{background-color:var(--buttonBackgroundHovered)}#trail-detail-card .card-subtitle{font-size:0.72rem;color:var(--bodySubtext);margin:2px 0 0;font-weight:500}#trail-detail-card .card-tabs{display:flex;border-bottom:1px solid var(--variantBorder);flex-shrink:0}#trail-detail-card .card-tab{flex:1;padding:8px 10px;font-size:0.78rem;font-weight:600;text-align:center;cursor:pointer;border:none;background:none;color:var(--bodySubtext);transition:all .15s ease;border-bottom:2px solid transparent;position:relative}#trail-detail-card .card-tab:hover{color:var(--bodyText);background-color:var(--buttonBackgroundHovered)}#trail-detail-card .card-tab.active{color:var(--themePrimary);border-bottom-color:var(--themePrimary);background-color:var(--buttonBackgroundHovered)}#trail-detail-card .card-tab-icon{margin-right:4px}#trail-detail-card .tab-content{flex:1;overflow:hidden;display:flex;flex-direction:column;min-height:0}#trail-detail-card .tab-pane{display:none;flex:1;overflow-y:auto;flex-direction:column;min-height:0}#trail-detail-card .tab-pane.active{display:flex}#trail-detail-card .facts-pane{padding:12px 14px;overflow-y:auto}#trail-detail-card .fact-row{display:flex;gap:8px;margin-bottom:8px;align-items:flex-start}#trail-detail-card .fact-icon{font-size:1rem;flex-shrink:0;width:22px;text-align:center;margin-top:1px}#trail-detail-card .fact-content{flex:1}#trail-detail-card .fact-label{font-size:0.65rem;text-transform:uppercase;letter-spacing:0.5px;color:var(--bodySubtext);font-weight:600;margin-bottom:1px}#trail-detail-card .fact-value{font-size:0.8rem;color:var(--bodyText);line-height:1.4}#trail-detail-card .card-divider{height:1px;background-color:var(--variantBorder);margin:4px 0 8px}#trail-detail-card .card-description{font-size:0.78rem;color:var(--bodyText);line-height:1.5;margin-top:2px}#trail-detail-card .mile-marker{display:inline-flex;align-items:center;gap:4px;background:rgba(211,47,47,0.1);color:var(--themePrimary);font-size:0.68rem;font-weight:600;padding:2px 7px;border-radius:var(--roundedCorner4);margin-bottom:8px}.light-mode #trail-detail-card .mile-marker{background:rgba(211,47,47,0.1);color:#b71c1c}.chat-pane{display:flex;flex-direction:column;min-height:0;flex:1}.chat-pane .chat-messages-area{flex:1;overflow-y:auto;padding:10px 12px;display:flex;flex-direction:column;gap:8px;min-height:120px}.chat-pane .chat-welcome{text-align:center;padding:16px 8px;color:var(--bodySubtext);font-size:0.78rem;line-height:1.5}.chat-pane .chat-welcome .welcome-emoji{font-size:1.8rem;margin-bottom:6px;display:block}.chat-pane .chat-welcome strong{color:var(--bodyText)}.chat-pane .chat-bubble{max-width:92%;padding:8px 11px;border-radius:var(--roundedCorner4);font-size:0.78rem;line-height:1.45;word-wrap:break-word;animation:bubbleIn .2s ease}.chat-pane .chat-bubble.user-bubble{align-self:flex-end;background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border-bottom-right-radius:4px}.chat-pane .chat-bubble.ai-bubble{align-self:flex-start;background-color:var(--bodyStandoutBackground);color:var(--bodyText);border:1px solid var(--variantBorder);border-bottom-left-radius:4px}.chat-pane .chat-bubble.ai-bubble.loading{opacity:0.7}.chat-pane .typing-dots{display:inline-flex;gap:3px;padding:2px 0}.chat-pane .typing-dots span{width:5px;height:5px;border-radius:50%;background-color:var(--bodySubtext);animation:dotBounce .6s ease-in-out infinite}.chat-pane .typing-dots span:nth-child(2){animation-delay:.15s}.chat-pane .typing-dots span:nth-child(3){animation-delay:.3s}@keyframes dotBounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}@keyframes bubbleIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.chat-pane .chat-input-area{display:flex;gap:6px;padding:8px 10px;border-top:1px solid var(--variantBorder);background-color:var(--bodyBackground);flex-shrink:0;border-radius:0 0 12px 12px}.chat-pane .chat-input-field{flex:1;border:1px solid var(--variantBorder);border-radius:18px;padding:7px 12px;font-size:0.78rem;background-color:var(--inputBackground);color:var(--bodyText);outline:none;transition:border-color .15s ease;font-family:inherit}.chat-pane .chat-input-field:focus{border-color:var(--themePrimary)}.chat-pane .chat-input-field::placeholder{color:var(--bodySubtext);opacity:0.7}.chat-pane .chat-send-btn{width:32px;height:32px;border-radius:50%;border:none;background:linear-gradient(135deg,#d32f2f,#b71c1c);color:#fff;font-size:0.9rem;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .1s ease,opacity .15s ease;flex-shrink:0}.chat-pane .chat-send-btn:hover{transform:scale(1.08)}.chat-pane .chat-send-btn:disabled{opacity:0.4;cursor:not-allowed;transform:none}.chat-pane .suggested-questions{display:flex;flex-wrap:wrap;gap:4px;padding:0 12px 8px}.chat-pane .suggested-q{font-size:0.68rem;padding:4px 8px;border-radius:var(--roundedCorner4);border:1px solid var(--variantBorder);background-color:var(--inputBackground);color:var(--bodySubtext);cursor:pointer;transition:all .15s ease;white-space:nowrap}.chat-pane .suggested-q:hover{background:rgba(211,47,47,0.08);color:var(--themePrimary);border-color:rgba(211,47,47,0.3)}</style></head>
13
14
  <body>
15
+ <div class="shell-toolbar" data-locked="true">
16
+ <button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
17
+ <button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
18
+ <button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
19
+ <div class="shell-toolbar-spacer" data-locked="true"></div>
20
+ <button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><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 1 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 1 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 1 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 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
21
+ </div>
14
22
  <div class="chat-panel" data-locked="true">
15
- <div class="chat-header" data-locked="true">SynthOS</div>
23
+ <div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">&times;</button></div>
16
24
  <div class="chat-messages" id="chatMessages" data-locked="true">
17
- <div class="chat-message" id="defaultGreeting"><p><strong>SynthOS:</strong> What can I create for you? Ask "what can you do?" or "how does this work?" to learn more. Remember to save often!</p></div>
18
- <div class="chat-message"><p><strong>User:</strong> create a map of the united states</p></div><div class="chat-message"><p><strong>SynthOS:</strong> Here's an interactive map of the United States! Hover over any state to see its name. The map is built with D3.js and uses an Albers USA projection that includes Alaska and Hawaii.</p></div><div class="chat-message"><p><strong>User:</strong> now in a second layer can you overlay that with a map of the usa circa 1850s</p></div><div class="chat-message"><p><strong>SynthOS:</strong> I've overlaid the modern map with an 1850s historical layer! The overlay shows the political divisions of the United States around 1850 (after the Compromise of 1850):</p><ul><li><strong style="color:#2e7d32;">Green</strong> — States admitted to the Union by 1850</li><li><strong style="color:#e65100;">Orange</strong> — Organized territories</li><li><strong style="color:#8d6e63;">Brown</strong> — Unorganized territory</li></ul><p>You can toggle the historical overlay on and off with the button in the top-right corner. The modern state boundaries show through underneath for reference.</p></div><div class="chat-message"><p><strong>User:</strong> remove the current state boundaries and draw new boundaries for how the territories were organized</p></div><div class="chat-message"><p><strong>SynthOS:</strong> I've replaced the modern state boundaries with historically-grouped 1850s territorial boundaries. The map now shows the approximate political divisions of the United States circa 1850, with internal state lines dissolved within each territory:</p><ul><li><strong style="color:#2e7d32;">Green</strong> — Individual states (31 states admitted by 1850)</li><li><strong style="color:#e65100;">Orange</strong> — Oregon Territory, Minnesota Territory, Utah Territory, New Mexico Territory</li><li><strong style="color:#8d6e63;">Brown</strong> — Unorganized Territory &amp; Indian Territory</li></ul><p>Note: Since this uses modern state shapes as approximations, the boundaries aren't perfectly historically accurate (e.g., territories that split modern states), but it gives a good sense of how the country was organized. Hover over any region to see its 1850s designation.</p></div><div class="chat-message"><p><strong>User:</strong> now overlay that with the oregon trail</p></div><div class="chat-message"><p><strong>SynthOS:</strong> I've overlaid the Oregon Trail on the 1850s map! The trail is shown as a <strong style="color:#d32f2f;">red dashed line</strong> running from <strong>Independence, Missouri</strong> to <strong>Oregon City, Oregon</strong> — roughly 2,000 miles.</p><p>Key stops along the trail are marked with dots and labels:</p><ul><li><strong>Independence, MO</strong> — the main jumping-off point</li><li><strong>Fort Kearny</strong> — first major military outpost</li><li><strong>Chimney Rock</strong> — famous landmark</li><li><strong>Fort Laramie</strong> — key resupply point</li><li><strong>Independence Rock</strong> — "Register of the Desert"</li><li><strong>South Pass</strong> — crossing the Continental Divide</li><li><strong>Fort Bridger</strong> — trading post</li><li><strong>Fort Hall</strong> — Hudson's Bay Company post</li><li><strong>Fort Boise</strong> — another HBC post</li><li><strong>The Dalles</strong> — end of the overland route</li><li><strong>Oregon City</strong> — final destination</li></ul><p>Hover over any stop for its name. The trail follows the approximate historical route through the Platte River valley, over the Rockies at South Pass, and along the Snake River into Oregon.</p></div><div class="chat-message"><p><strong>User:</strong> create a detail card that tells me facts about key stops along the way</p></div><div class="chat-message"><p><strong>SynthOS:</strong> I've added an interactive detail card! Click on any trail stop marker on the map to see historical facts about that location, including when it was established, its elevation, who used it, and why it mattered to Oregon Trail emigrants. Click the × button or click elsewhere to dismiss the card.</p></div><div class="chat-message"><p><strong>User:</strong> can you add an AI powered chat interface to that card that lets me ask questions relative to that location and the journey as a whole. the target audience should be 8-12 year olds. track the last 10 turns for follow up questions. reorganize the card if you need to</p></div><div class="chat-message"><p><strong>SynthOS:</strong> I've added an AI-powered chat to the detail card! Here's what's new:</p><ul><li><strong>Two tabs</strong> — "📋 Facts" shows the historical info, and "💬 Ask Me!" opens the chat</li><li><strong>Meet Dusty 🤠</strong> — your friendly trail guide who answers questions in fun, kid-friendly language (perfect for ages 8–12)</li><li><strong>Suggested questions</strong> — each stop has starter questions to tap, or kids can type their own</li><li><strong>Conversation memory</strong> — Dusty remembers the last 10 exchanges so kids can ask follow-up questions</li><li><strong>Per-stop context</strong> — switching to a new stop resets the chat with fresh context about that location</li></ul><p>Click any trail stop, then hit the "Ask Me!" tab to start chatting with Dusty!</p></div></div>
19
- <div class="link-group" data-locked="true">
20
- <a href="#" id="saveLink" data-locked="true">Save</a>
21
- <a href="/pages" id="pagesLink" data-locked="true">Pages</a>
22
- <a href="#" id="resetLink" data-locked="true">Reset</a>
23
- </div>
25
+ <div class="chat-message" id="defaultGreeting"><p><strong>SynthOS:</strong> Welcome to the <strong>Oregon Trail</strong> an interactive 1850s map with the Oregon Trail overlaid. Click any trail stop to see historical facts and chat with Dusty, your AI trail guide!</p></div>
26
+ </div>
24
27
  <form action="/" method="POST" id="chatForm" data-locked="true">
25
- <input type="text" class="chat-input" id="chatInput" name="message" placeholder="Type a message..." data-locked="true">
26
- <button type="submit" class="chat-submit" data-locked="true">Send</button>
28
+ <textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
27
29
  </form>
28
30
  </div>
29
31
  <div class="viewer-panel" id="viewerPanel"><div id="us-map-container"><div id="us-map-header">United States — Circa 1850 — with Oregon Trail</div><div id="us-map-svg-wrap"><div id="hist-legend"><div style="font-weight:600;margin-bottom:6px;">Circa 1850</div><div class="legend-item"><div class="legend-swatch" style="background:rgba(46,125,50,0.6);border:1px solid #1b5e20;"></div><span>States (31)</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(230,81,0,0.55);border:1px solid #bf360c;"></div><span>Oregon Territory</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(255,152,0,0.55);border:1px solid #e65100;"></div><span>Minnesota Territory</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(255,111,0,0.5);border:1px solid #bf360c;"></div><span>Utah Territory</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(239,108,0,0.55);border:1px solid #bf360c;"></div><span>New Mexico Territory</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(141,110,99,0.5);border:1px solid #4e342e;"></div><span>Unorganized Territory</span></div><div class="legend-item"><div class="legend-swatch" style="background:rgba(121,85,72,0.55);border:1px solid #3e2723;"></div><span>Indian Territory</span></div><div style="border-top:1px solid var(--border-color);margin-top:6px;padding-top:6px;"></div><div class="legend-item"><div class="legend-swatch" style="background:#d32f2f;border:1px solid #b71c1c;border-radius:50%;"></div><span style="font-weight:600;">Oregon Trail</span></div></div><div id="trail-detail-card"><div class="card-header"><div><h3 id="card-title"></h3><div class="card-subtitle" id="card-subtitle"></div></div><button class="card-close" id="card-close-btn" aria-label="Close">×</button></div><div class="card-tabs"><button class="card-tab active" data-tab="facts"><span class="card-tab-icon">📋</span>Facts</button><button class="card-tab" data-tab="chat"><span class="card-tab-icon">💬</span>Ask Me!</button></div><div class="tab-content"><div class="tab-pane facts-pane active" id="facts-pane"><div id="card-body"></div></div><div class="tab-pane chat-pane" id="chat-pane"><div class="chat-messages-area" id="trail-chat-messages"><div class="chat-welcome"><span class="welcome-emoji">🤠</span>Howdy, explorer! <strong>Click a trail stop</strong> and ask me anything about life on the Oregon Trail!</div></div><div class="suggested-questions" id="trail-suggested-q"></div><div class="chat-input-area"><input type="text" class="chat-input-field" id="trail-chat-input" placeholder="Ask me anything..." autocomplete="off"><button class="chat-send-btn" id="trail-chat-send" aria-label="Send">➤</button></div></div></div></div></div><div id="map-tooltip"></div></div><div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div></div>
30
32
  <div id="instructions" style="display: none;" data-locked="true"></div>
31
- <div id="thoughts" style="display: none;" data-locked="true">User wants an AI-powered chat interface inside the trail detail card so kids (8-12) can ask questions about each stop and the Oregon Trail journey. I need to:
32
-
33
- 1. Reorganize the detail card to have tabs or sections - facts + chat
34
- 2. Add a chat input and message area inside the card
35
- 3. Use synthos.generate.completion() to power the AI responses
36
- 4. Track last 10 conversation turns for context
37
- 5. Style it kid-friendly
38
- 6. The card needs to be taller/scrollable to accommodate both facts and chat
39
-
40
- Plan:
41
- - Restructure the card to have two tabs: "Facts" and "Ask Me!"
42
- - The chat tab has a scrollable message area and input
43
- - Store conversation history per stop (or globally with stop context)
44
- - Use completion API with a kid-friendly system prompt
45
- - Track last 10 turns in a JS array
46
-
47
- I'll update the CSS, the card HTML structure, and the JS to handle all of this.</div>
33
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
48
34
  <script id="idle-animation">function hideIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.classList.add("hidden"),setTimeout(()=>{idleContainer.style.display="none"},1e3))}function showIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.style.display="block",setTimeout(()=>{idleContainer.classList.remove("hidden")},10))}</script>
49
35
  <button class="chat-toggle" aria-label="Toggle chat panel">
50
36
  <span class="chat-toggle-dots">
@@ -265,7 +251,7 @@ sendTrailChat(input.value);
265
251
  });
266
252
 
267
253
  document.getElementById('trail-chat-input').addEventListener('keydown',function(e){
268
- if(e.key==='Enter'){e.preventDefault();e.stopPropagation();sendTrailChat(this.value);}
254
+ if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();e.stopPropagation();sendTrailChat(this.value);}
269
255
  });
270
256
 
271
257
  document.getElementById('trail-chat-input').addEventListener('click',function(e){e.stopPropagation();});
@@ -318,4 +304,4 @@ g.on('mousemove',function(event){tooltip.textContent='Oregon Trail: '+stop.name;
318
304
  }).catch(function(err){console.error('Failed to load US map data:',err);wrap.innerHTML='<p style="color:var(--text-secondary);text-align:center;">Failed to load map data. Please try again.</p>';});
319
305
  }
320
306
  if(typeof topojson!=='undefined'){init();}else{var check=setInterval(function(){if(typeof topojson!=='undefined'){clearInterval(check);init();}},100);setTimeout(function(){clearInterval(check);},10000);}
321
- })();</script><script id="page-helpers" src="/api/page-helpers.js?v=2" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=2" data-locked="true"></script></body></html>
307
+ })();</script><script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script></body></html>
@@ -7,6 +7,6 @@
7
7
  "showInAll": false,
8
8
  "createdDate": "2026-02-16T13:52:41.911Z",
9
9
  "lastModified": "2026-02-16T13:52:41.911Z",
10
- "pageVersion": 2,
10
+ "pageVersion": 3,
11
11
  "mode": "locked"
12
- }
12
+ }