synthos 0.10.0 → 0.11.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 (312) hide show
  1. package/README.md +5 -5
  2. package/default-pages/elevenlabs_effects_studio/chat-history.json +1 -0
  3. package/default-pages/elevenlabs_effects_studio/page.html +1345 -1363
  4. package/default-pages/elevenlabs_effects_studio/page.json +13 -11
  5. package/default-pages/elevenlabs_voice_studio/chat-history.json +1 -0
  6. package/default-pages/elevenlabs_voice_studio/page.html +782 -801
  7. package/default-pages/elevenlabs_voice_studio/page.json +13 -11
  8. package/default-pages/json_tools/chat-history.json +1 -0
  9. package/default-pages/json_tools/page.html +70 -90
  10. package/default-pages/json_tools/page.json +12 -10
  11. package/default-pages/my_notes/chat-history.json +1 -0
  12. package/default-pages/my_notes/page.html +115 -131
  13. package/default-pages/my_notes/page.json +14 -12
  14. package/default-pages/neon_asteroids/chat-history.json +1 -0
  15. package/default-pages/neon_asteroids/page.html +1777 -1803
  16. package/default-pages/neon_asteroids/page.json +14 -12
  17. package/default-pages/oregon_trail/chat-history.json +1 -0
  18. package/default-pages/oregon_trail/page.html +290 -307
  19. package/default-pages/oregon_trail/page.json +14 -12
  20. package/default-pages/solar_explorer/chat-history.json +1 -0
  21. package/default-pages/solar_explorer/page.html +1929 -1951
  22. package/default-pages/solar_explorer/page.json +14 -12
  23. package/default-pages/solar_tutorial/chat-history.json +1 -0
  24. package/default-pages/solar_tutorial/page.html +464 -478
  25. package/default-pages/solar_tutorial/page.json +12 -10
  26. package/default-pages/us_map/chat-history.json +1 -0
  27. package/default-pages/us_map/page.html +170 -193
  28. package/default-pages/us_map/page.json +14 -12
  29. package/default-pages/us_map/page.light.png +0 -0
  30. package/default-pages/us_map_1850/chat-history.json +1 -0
  31. package/default-pages/us_map_1850/page.html +302 -326
  32. package/default-pages/us_map_1850/page.json +14 -12
  33. package/default-pages/western_cities_1850/chat-history.json +1 -0
  34. package/default-pages/western_cities_1850/page.html +503 -527
  35. package/default-pages/western_cities_1850/page.json +14 -12
  36. package/default-themes/aurora-dawn.v3.css +15 -14
  37. package/default-themes/aurora-dusk.v3.css +26 -26
  38. package/default-themes/cosmos-dawn.v3.css +15 -14
  39. package/default-themes/cosmos-dusk.v3.css +26 -26
  40. package/default-themes/elemental-dawn.v3.css +200 -0
  41. package/default-themes/nebula-dawn.v3.css +15 -14
  42. package/default-themes/nebula-dusk.v3.css +24 -24
  43. package/default-themes/solar-flare-dawn.v3.css +15 -14
  44. package/default-themes/solar-flare-dusk.v3.css +26 -26
  45. package/dist/builders/anthropic.d.ts +26 -2
  46. package/dist/builders/anthropic.d.ts.map +1 -1
  47. package/dist/builders/anthropic.js +132 -31
  48. package/dist/builders/anthropic.js.map +1 -1
  49. package/dist/builders/claudecode.d.ts +13 -0
  50. package/dist/builders/claudecode.d.ts.map +1 -0
  51. package/dist/builders/claudecode.js +253 -0
  52. package/dist/builders/claudecode.js.map +1 -0
  53. package/dist/builders/index.d.ts +2 -1
  54. package/dist/builders/index.d.ts.map +1 -1
  55. package/dist/builders/index.js +8 -1
  56. package/dist/builders/index.js.map +1 -1
  57. package/dist/builders/openai.js +2 -1
  58. package/dist/builders/openai.js.map +1 -1
  59. package/dist/builders/types.d.ts +31 -7
  60. package/dist/builders/types.d.ts.map +1 -1
  61. package/dist/builders/types.js +60 -28
  62. package/dist/builders/types.js.map +1 -1
  63. package/dist/connectors/types.d.ts +8 -0
  64. package/dist/connectors/types.d.ts.map +1 -1
  65. package/dist/init.d.ts.map +1 -1
  66. package/dist/init.js +13 -6
  67. package/dist/init.js.map +1 -1
  68. package/dist/migrations.d.ts.map +1 -1
  69. package/dist/migrations.js +161 -14
  70. package/dist/migrations.js.map +1 -1
  71. package/dist/models/anthropic.d.ts +1 -0
  72. package/dist/models/anthropic.d.ts.map +1 -1
  73. package/dist/models/anthropic.js +129 -29
  74. package/dist/models/anthropic.js.map +1 -1
  75. package/dist/models/chainOfThought.d.ts.map +1 -1
  76. package/dist/models/chainOfThought.js +32 -19
  77. package/dist/models/chainOfThought.js.map +1 -1
  78. package/dist/models/index.d.ts +2 -2
  79. package/dist/models/index.d.ts.map +1 -1
  80. package/dist/models/index.js +2 -1
  81. package/dist/models/index.js.map +1 -1
  82. package/dist/models/providers.d.ts +1 -0
  83. package/dist/models/providers.d.ts.map +1 -1
  84. package/dist/models/providers.js +12 -4
  85. package/dist/models/providers.js.map +1 -1
  86. package/dist/models/types.d.ts +15 -1
  87. package/dist/models/types.d.ts.map +1 -1
  88. package/dist/models/types.js.map +1 -1
  89. package/dist/pages.d.ts +57 -8
  90. package/dist/pages.d.ts.map +1 -1
  91. package/dist/pages.js +258 -45
  92. package/dist/pages.js.map +1 -1
  93. package/dist/service/createCompletePrompt.d.ts.map +1 -1
  94. package/dist/service/createCompletePrompt.js +5 -0
  95. package/dist/service/createCompletePrompt.js.map +1 -1
  96. package/dist/service/mediaCache.d.ts +36 -0
  97. package/dist/service/mediaCache.d.ts.map +1 -0
  98. package/dist/service/mediaCache.js +182 -0
  99. package/dist/service/mediaCache.js.map +1 -0
  100. package/dist/service/pageValidator.d.ts +25 -0
  101. package/dist/service/pageValidator.d.ts.map +1 -0
  102. package/dist/service/pageValidator.js +315 -0
  103. package/dist/service/pageValidator.js.map +1 -0
  104. package/dist/service/server.d.ts.map +1 -1
  105. package/dist/service/server.js +4 -0
  106. package/dist/service/server.js.map +1 -1
  107. package/dist/service/sharedTableSchema.d.ts +73 -0
  108. package/dist/service/sharedTableSchema.d.ts.map +1 -0
  109. package/dist/service/sharedTableSchema.js +206 -0
  110. package/dist/service/sharedTableSchema.js.map +1 -0
  111. package/dist/service/transformPage.d.ts +49 -11
  112. package/dist/service/transformPage.d.ts.map +1 -1
  113. package/dist/service/transformPage.js +354 -241
  114. package/dist/service/transformPage.js.map +1 -1
  115. package/dist/service/useApiRoutes.d.ts.map +1 -1
  116. package/dist/service/useApiRoutes.js +288 -34
  117. package/dist/service/useApiRoutes.js.map +1 -1
  118. package/dist/service/useConnectorRoutes.d.ts.map +1 -1
  119. package/dist/service/useConnectorRoutes.js +170 -32
  120. package/dist/service/useConnectorRoutes.js.map +1 -1
  121. package/dist/service/useDataRoutes.d.ts.map +1 -1
  122. package/dist/service/useDataRoutes.js +59 -2
  123. package/dist/service/useDataRoutes.js.map +1 -1
  124. package/dist/service/useExtractRoutes.d.ts +4 -0
  125. package/dist/service/useExtractRoutes.d.ts.map +1 -0
  126. package/dist/service/useExtractRoutes.js +304 -0
  127. package/dist/service/useExtractRoutes.js.map +1 -0
  128. package/dist/service/usePageRoutes.d.ts +17 -0
  129. package/dist/service/usePageRoutes.d.ts.map +1 -1
  130. package/dist/service/usePageRoutes.js +1385 -483
  131. package/dist/service/usePageRoutes.js.map +1 -1
  132. package/dist/service/useSharedDataRoutes.d.ts.map +1 -1
  133. package/dist/service/useSharedDataRoutes.js +54 -2
  134. package/dist/service/useSharedDataRoutes.js.map +1 -1
  135. package/dist/settings.d.ts +27 -0
  136. package/dist/settings.d.ts.map +1 -1
  137. package/dist/settings.js +40 -1
  138. package/dist/settings.js.map +1 -1
  139. package/dist/themes.d.ts +0 -5
  140. package/dist/themes.d.ts.map +1 -1
  141. package/dist/themes.js +3 -95
  142. package/dist/themes.js.map +1 -1
  143. package/migration-rules/v2-to-v3.md +277 -119
  144. package/package.json +5 -1
  145. package/{default-pages/application → required-pages/_shell}/page.html +56 -42
  146. package/required-pages/_shell/page.json +14 -0
  147. package/required-pages/_starters/page.html +534 -0
  148. package/required-pages/_starters/page.json +12 -0
  149. package/required-pages/builder/page.html +353 -43
  150. package/required-pages/builder/page.json +12 -10
  151. package/required-pages/pages/page.html +697 -924
  152. package/required-pages/pages/page.json +12 -10
  153. package/required-pages/settings/page.html +1879 -1753
  154. package/required-pages/settings/page.json +12 -10
  155. package/required-pages/synthos_apis/page.html +834 -845
  156. package/required-pages/synthos_apis/page.json +12 -10
  157. package/required-pages/synthos_scripts/page.html +74 -88
  158. package/required-pages/synthos_scripts/page.json +12 -10
  159. package/scripts/append-instructions.py +90 -0
  160. package/scripts/audit-instructions.py +76 -0
  161. package/scripts/cleanup-shell-markup.mjs +112 -0
  162. package/service-connectors/buffer/connector.json +46 -0
  163. package/service-connectors/canva/connector.json +67 -0
  164. package/service-connectors/elevenlabs/connector.json +1 -1
  165. package/src/builders/anthropic.ts +155 -30
  166. package/src/builders/claudecode.ts +310 -0
  167. package/src/builders/index.ts +7 -1
  168. package/src/builders/openai.ts +2 -1
  169. package/src/builders/types.ts +93 -32
  170. package/src/connectors/types.ts +8 -0
  171. package/src/init.ts +13 -7
  172. package/src/migrations.ts +187 -16
  173. package/src/models/anthropic.ts +140 -30
  174. package/src/models/chainOfThought.ts +33 -18
  175. package/src/models/index.ts +2 -2
  176. package/src/models/providers.ts +12 -3
  177. package/src/models/types.ts +21 -1
  178. package/src/pages.ts +271 -35
  179. package/src/service/createCompletePrompt.ts +6 -0
  180. package/src/service/mediaCache.ts +206 -0
  181. package/src/service/pageValidator.ts +337 -0
  182. package/src/service/server.ts +4 -0
  183. package/src/service/sharedTableSchema.ts +236 -0
  184. package/src/service/transformPage.ts +370 -260
  185. package/src/service/useApiRoutes.ts +282 -32
  186. package/src/service/useConnectorRoutes.ts +189 -34
  187. package/src/service/useDataRoutes.ts +198 -116
  188. package/src/service/useExtractRoutes.ts +331 -0
  189. package/src/service/usePageRoutes.ts +1411 -394
  190. package/src/service/useSharedDataRoutes.ts +184 -109
  191. package/src/settings.ts +65 -0
  192. package/src/themes.ts +78 -180
  193. package/starters/blank_starter/chat-history.json +1 -0
  194. package/starters/blank_starter/page.dark.png +0 -0
  195. package/starters/blank_starter/page.html +47 -0
  196. package/starters/blank_starter/page.json +13 -0
  197. package/starters/blank_starter/page.light.png +0 -0
  198. package/starters/calculator_starter/chat-history.json +1 -0
  199. package/starters/calculator_starter/page.dark.png +0 -0
  200. package/starters/calculator_starter/page.html +232 -0
  201. package/starters/calculator_starter/page.json +13 -0
  202. package/starters/calculator_starter/page.light.png +0 -0
  203. package/starters/calendar_starter/chat-history.json +1 -0
  204. package/starters/calendar_starter/page.dark.png +0 -0
  205. package/starters/calendar_starter/page.html +495 -0
  206. package/starters/calendar_starter/page.json +13 -0
  207. package/starters/calendar_starter/page.light.png +0 -0
  208. package/starters/chat_starter/chat-history.json +1 -0
  209. package/starters/chat_starter/page.dark.png +0 -0
  210. package/starters/chat_starter/page.html +351 -0
  211. package/starters/chat_starter/page.json +13 -0
  212. package/starters/chat_starter/page.light.png +0 -0
  213. package/starters/checklist_starter/chat-history.json +1 -0
  214. package/starters/checklist_starter/page.dark.png +0 -0
  215. package/starters/checklist_starter/page.html +437 -0
  216. package/starters/checklist_starter/page.json +13 -0
  217. package/starters/checklist_starter/page.light.png +0 -0
  218. package/starters/dashboard_starter/chat-history.json +1 -0
  219. package/starters/dashboard_starter/page.dark.png +0 -0
  220. package/starters/dashboard_starter/page.html +195 -0
  221. package/starters/dashboard_starter/page.json +13 -0
  222. package/starters/dashboard_starter/page.light.png +0 -0
  223. package/starters/form_starter/chat-history.json +1 -0
  224. package/starters/form_starter/page.dark.png +0 -0
  225. package/starters/form_starter/page.html +313 -0
  226. package/starters/form_starter/page.json +13 -0
  227. package/starters/form_starter/page.light.png +0 -0
  228. package/starters/gallery_starter/chat-history.json +1 -0
  229. package/starters/gallery_starter/page.dark.png +0 -0
  230. package/starters/gallery_starter/page.html +418 -0
  231. package/starters/gallery_starter/page.json +13 -0
  232. package/starters/gallery_starter/page.light.png +0 -0
  233. package/starters/generator_starter/chat-history.json +1 -0
  234. package/starters/generator_starter/page.dark.png +0 -0
  235. package/starters/generator_starter/page.html +261 -0
  236. package/starters/generator_starter/page.json +13 -0
  237. package/starters/generator_starter/page.light.png +0 -0
  238. package/starters/index.html +538 -0
  239. package/starters/kanban_starter/chat-history.json +1 -0
  240. package/starters/kanban_starter/page.dark.png +0 -0
  241. package/starters/kanban_starter/page.html +432 -0
  242. package/starters/kanban_starter/page.json +13 -0
  243. package/starters/kanban_starter/page.light.png +0 -0
  244. package/starters/presentation_builder/chat-history.json +1 -0
  245. package/starters/presentation_builder/page.dark.png +0 -0
  246. package/starters/presentation_builder/page.html +970 -0
  247. package/starters/presentation_builder/page.json +15 -0
  248. package/starters/presentation_builder/page.light.png +0 -0
  249. package/starters/presentation_builder/presentation_voice/voice_config.json +9 -0
  250. package/starters/pulse_starter/chat-history.json +1 -0
  251. package/starters/pulse_starter/page.dark.png +0 -0
  252. package/starters/pulse_starter/page.html +698 -0
  253. package/starters/pulse_starter/page.json +13 -0
  254. package/starters/pulse_starter/page.light.png +0 -0
  255. package/starters/quiz_starter/chat-history.json +1 -0
  256. package/starters/quiz_starter/page.dark.png +0 -0
  257. package/starters/quiz_starter/page.html +292 -0
  258. package/starters/quiz_starter/page.json +13 -0
  259. package/starters/quiz_starter/page.light.png +0 -0
  260. package/starters/reference_starter/chat-history.json +1 -0
  261. package/starters/reference_starter/page.dark.png +0 -0
  262. package/starters/reference_starter/page.html +250 -0
  263. package/starters/reference_starter/page.json +13 -0
  264. package/starters/reference_starter/page.light.png +0 -0
  265. package/starters/retro_game_starter/chat-history.json +1 -0
  266. package/starters/retro_game_starter/page.dark.png +0 -0
  267. package/{default-pages → starters}/retro_game_starter/page.html +1281 -1308
  268. package/starters/retro_game_starter/page.json +15 -0
  269. package/starters/retro_game_starter/page.light.png +0 -0
  270. package/starters/roster_starter/chat-history.json +1 -0
  271. package/starters/roster_starter/page.dark.png +0 -0
  272. package/starters/roster_starter/page.html +600 -0
  273. package/starters/roster_starter/page.json +13 -0
  274. package/starters/roster_starter/page.light.png +0 -0
  275. package/starters/server.js +182 -0
  276. package/starters/start.cmd +1 -0
  277. package/starters/timeline_starter/chat-history.json +1 -0
  278. package/starters/timeline_starter/page.dark.png +0 -0
  279. package/starters/timeline_starter/page.html +446 -0
  280. package/starters/timeline_starter/page.json +13 -0
  281. package/starters/timeline_starter/page.light.png +0 -0
  282. package/starters/tutorial_starter/chat-history.json +1 -0
  283. package/starters/tutorial_starter/page.dark.png +0 -0
  284. package/starters/tutorial_starter/page.html +283 -0
  285. package/starters/tutorial_starter/page.json +13 -0
  286. package/starters/tutorial_starter/page.light.png +0 -0
  287. package/static-files/agent.v3.js +122 -0
  288. package/static-files/connector.v3.js +48 -0
  289. package/static-files/extract.v3.js +188 -0
  290. package/static-files/helpers.v3.js +50 -6
  291. package/static-files/page-bridge.js +114 -0
  292. package/static-files/page.v3.js +1292 -1290
  293. package/static-files/script.v3.js +32 -0
  294. package/static-files/server.v3.js +89 -0
  295. package/static-files/shell-bridge.v3.js +174 -0
  296. package/static-files/shell-modals.v3.js +521 -0
  297. package/static-files/{shell.css → shell.v3.css} +271 -22
  298. package/static-files/shell.v3.js +1865 -0
  299. package/static-files/storage.v3.js +176 -0
  300. package/tests/anthropic.spec.ts +42 -7
  301. package/tests/builders.spec.ts +72 -4
  302. package/tests/pageValidator.spec.ts +548 -0
  303. package/tests/profiles.spec.ts +122 -0
  304. package/tests/providers.spec.ts +1 -1
  305. package/tests/sharedTableSchema.spec.ts +242 -0
  306. package/tests/transformPage.spec.ts +62 -81
  307. package/default-pages/application/page.json +0 -10
  308. package/default-pages/retro_game_starter/page.json +0 -12
  309. package/default-pages/sidebar_page/page.html +0 -51
  310. package/default-pages/sidebar_page/page.json +0 -10
  311. package/default-pages/two-panel_page/page.html +0 -68
  312. package/default-pages/two-panel_page/page.json +0 -10
@@ -0,0 +1,418 @@
1
+ <!DOCTYPE html><html lang="en"><head>
2
+ <meta charset="UTF-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <title>SynthOS - Gallery Starter</title>
5
+ <script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
6
+ <link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
7
+ <style>
8
+ html, body { height: 100%; }
9
+ body { margin: 0; }
10
+ .viewer-panel { height: 100%; }
11
+ .gl-app {
12
+ display: flex;
13
+ flex-direction: column;
14
+ height: 100%;
15
+ min-height: 100%;
16
+ box-sizing: border-box;
17
+ }
18
+ .gl-header {
19
+ display: flex;
20
+ justify-content: space-between;
21
+ align-items: center;
22
+ padding: 14px 24px;
23
+ border-bottom: 1px solid var(--bodyDivider, #edebe9);
24
+ background: var(--defaultStateBackground, #faf9f8);
25
+ gap: 12px;
26
+ flex: 0 0 auto;
27
+ flex-wrap: wrap;
28
+ }
29
+ .gl-header h1 {
30
+ margin: 0;
31
+ font-size: 18px;
32
+ font-weight: 700;
33
+ color: var(--bodyText, #333333);
34
+ }
35
+ .gl-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
36
+ .filter-row {
37
+ display: flex;
38
+ gap: 6px;
39
+ align-items: center;
40
+ flex-wrap: wrap;
41
+ }
42
+ .filter-chip {
43
+ padding: 4px 10px;
44
+ border: 1px solid var(--inputBorder, #d2d0ce);
45
+ border-radius: 14px;
46
+ background: var(--bodyBackground, #ffffff);
47
+ color: var(--bodyText, #333333);
48
+ font-size: 12px;
49
+ cursor: pointer;
50
+ }
51
+ .filter-chip:hover { background: var(--bodyBackgroundHovered, #f3f2f1); }
52
+ .filter-chip.active {
53
+ background: var(--themePrimary, #0078d4);
54
+ border-color: var(--themePrimary, #0078d4);
55
+ color: #ffffff;
56
+ }
57
+
58
+ .gl-scroll {
59
+ flex: 1 1 auto;
60
+ min-height: 0;
61
+ overflow-y: auto;
62
+ background: var(--bodyBackground, #ffffff);
63
+ }
64
+ .gl-grid {
65
+ display: grid;
66
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
67
+ gap: 16px;
68
+ padding: 20px 24px;
69
+ }
70
+ .gl-empty {
71
+ text-align: center;
72
+ color: var(--bodySubtext, #605e5c);
73
+ padding: 48px 24px;
74
+ font-size: 13px;
75
+ }
76
+ .gl-card {
77
+ background: var(--defaultStateBackground, #faf9f8);
78
+ border: 1px solid var(--bodyDivider, #edebe9);
79
+ border-radius: 8px;
80
+ overflow: hidden;
81
+ cursor: pointer;
82
+ display: flex;
83
+ flex-direction: column;
84
+ transition: border-color 0.15s ease, transform 0.15s ease;
85
+ }
86
+ .gl-card:hover {
87
+ border-color: var(--themePrimary, #0078d4);
88
+ transform: translateY(-1px);
89
+ }
90
+ .gl-thumb {
91
+ width: 100%;
92
+ aspect-ratio: 16 / 9;
93
+ object-fit: cover;
94
+ display: block;
95
+ background: var(--bodyDivider, #edebe9);
96
+ }
97
+ .gl-info {
98
+ padding: 10px 12px 12px;
99
+ display: flex;
100
+ flex-direction: column;
101
+ gap: 4px;
102
+ }
103
+ .gl-title {
104
+ font-size: 14px;
105
+ font-weight: 600;
106
+ color: var(--bodyText, #333333);
107
+ line-height: 1.3;
108
+ }
109
+ .gl-caption {
110
+ font-size: 12px;
111
+ color: var(--bodySubtext, #605e5c);
112
+ line-height: 1.4;
113
+ display: -webkit-box;
114
+ -webkit-line-clamp: 2;
115
+ -webkit-box-orient: vertical;
116
+ overflow: hidden;
117
+ }
118
+ .gl-cat {
119
+ display: inline-block;
120
+ margin-top: 4px;
121
+ padding: 2px 8px;
122
+ border-radius: 10px;
123
+ font-size: 10px;
124
+ font-weight: 600;
125
+ text-transform: uppercase;
126
+ letter-spacing: 0.4px;
127
+ background: var(--bodyDivider, #edebe9);
128
+ color: var(--bodyText, #333333);
129
+ align-self: flex-start;
130
+ }
131
+
132
+ /* Lightbox (local — v3 themes do not inject overlay styles into iframe content) */
133
+ .lightbox-overlay {
134
+ display: none;
135
+ position: fixed;
136
+ inset: 0;
137
+ background: rgba(0, 0, 0, 0.85);
138
+ z-index: 200;
139
+ align-items: center;
140
+ justify-content: center;
141
+ flex-direction: column;
142
+ padding: 24px;
143
+ box-sizing: border-box;
144
+ }
145
+ .lightbox-overlay.open { display: flex; }
146
+ .lightbox-stage {
147
+ position: relative;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ flex: 1 1 auto;
152
+ min-height: 0;
153
+ width: 100%;
154
+ max-width: 1200px;
155
+ }
156
+ .lightbox-img {
157
+ max-width: 100%;
158
+ max-height: 100%;
159
+ object-fit: contain;
160
+ display: block;
161
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
162
+ border-radius: 4px;
163
+ }
164
+ .lightbox-caption {
165
+ margin-top: 16px;
166
+ color: #ffffff;
167
+ text-align: center;
168
+ font-size: 13px;
169
+ line-height: 1.5;
170
+ max-width: 720px;
171
+ }
172
+ .lightbox-caption .lb-title { font-weight: 600; font-size: 15px; margin-bottom: 4px; }
173
+ .lightbox-caption .lb-cap { opacity: 0.85; }
174
+ .lightbox-nav {
175
+ position: absolute;
176
+ top: 50%;
177
+ transform: translateY(-50%);
178
+ background: rgba(0, 0, 0, 0.5);
179
+ color: #ffffff;
180
+ border: none;
181
+ border-radius: 50%;
182
+ width: 44px;
183
+ height: 44px;
184
+ font-size: 22px;
185
+ cursor: pointer;
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ }
190
+ .lightbox-nav:hover { background: rgba(0, 0, 0, 0.75); }
191
+ .lightbox-nav.prev { left: 0; }
192
+ .lightbox-nav.next { right: 0; }
193
+ .lightbox-close {
194
+ position: absolute;
195
+ top: 16px;
196
+ right: 16px;
197
+ background: rgba(0, 0, 0, 0.5);
198
+ color: #ffffff;
199
+ border: none;
200
+ border-radius: 50%;
201
+ width: 36px;
202
+ height: 36px;
203
+ font-size: 18px;
204
+ cursor: pointer;
205
+ display: flex;
206
+ align-items: center;
207
+ justify-content: center;
208
+ }
209
+ .lightbox-close:hover { background: rgba(0, 0, 0, 0.75); }
210
+ </style>
211
+ </head>
212
+ <body>
213
+ <div class="viewer-panel" id="viewerPanel" style="padding: 0;">
214
+ <div class="gl-app">
215
+ <div class="gl-header">
216
+ <div>
217
+ <h1>[Gallery Title]</h1>
218
+ </div>
219
+ <div class="gl-actions">
220
+ <div class="filter-row" id="filterRow">
221
+ <button class="filter-chip active" data-cat="all">All</button>
222
+ <button class="filter-chip" data-cat="featured">Featured</button>
223
+ <button class="filter-chip" data-cat="archive">Archive</button>
224
+ <button class="filter-chip" data-cat="draft">Draft</button>
225
+ </div>
226
+ <button class="flm-button flm-button--primary" id="addItemBtn" data-icon="Add">Add Item</button>
227
+ </div>
228
+ </div>
229
+ <div class="gl-scroll">
230
+ <div class="gl-grid" id="grid"></div>
231
+ </div>
232
+ </div>
233
+ </div>
234
+
235
+ <div class="lightbox-overlay" id="lightboxOverlay" role="dialog" aria-modal="true" aria-label="Image preview">
236
+ <button class="lightbox-close" id="lbClose" aria-label="Close">×</button>
237
+ <div class="lightbox-stage">
238
+ <button class="lightbox-nav prev" id="lbPrev" aria-label="Previous">&#10094;</button>
239
+ <img class="lightbox-img" id="lbImg" alt="">
240
+ <button class="lightbox-nav next" id="lbNext" aria-label="Next">&#10095;</button>
241
+ </div>
242
+ <div class="lightbox-caption">
243
+ <div class="lb-title" id="lbTitle"></div>
244
+ <div class="lb-cap" id="lbCap"></div>
245
+ </div>
246
+ </div>
247
+
248
+ <div id="instructions" style="display: none;" data-locked="true">Gallery archetype (STARTERS.md §3.11). Image-first responsive card grid (auto-fill, min 240px) with lightbox preview. Card image is locked to aspect-ratio: 16/9 + object-fit: cover so layout never shifts as images load. Filter chips narrow visible items by category. Click a card to open the lightbox; ←/→ navigate, Esc closes. The lightbox overlay uses LOCAL .lightbox-overlay CSS — v3 themes do not inject those styles into iframe content (per WISDOM iframe-modal-overlay rule). Default placeholder thumbnails are theme-neutral SVG data-uris embedded in PLACEHOLDER_SVG so the empty state is not a stack of broken-image icons. Persist items with synthos.shared.data.save("&lt;table&gt;", item) / .list("&lt;table&gt;") / .remove("&lt;table&gt;", id). Default fields: id, imageUrl, title, caption, category. Replace [Gallery Title] and the category list with the user's domain. Use theme tokens (avoid the natural pallet) unless the user requests an alternative color.</div>
249
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
250
+
251
+ <script>
252
+ (function () {
253
+ // Theme-aware SVG placeholder: very light tint of --themePrimary so the
254
+ // empty state reads as a soft accent in both light and dark themes
255
+ // (a hard-coded light gray washes out under dark themes).
256
+ function buildPlaceholderSvg() {
257
+ var primary = (getComputedStyle(document.documentElement)
258
+ .getPropertyValue('--themePrimary') || '').trim() || '#0078d4';
259
+ return 'data:image/svg+xml;utf8,' + encodeURIComponent(
260
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 180">' +
261
+ '<rect width="100%" height="100%" fill="' + primary + '" fill-opacity="0.14"/>' +
262
+ '<g fill="' + primary + '" fill-opacity="0.45">' +
263
+ '<circle cx="120" cy="80" r="14"/>' +
264
+ '<path d="M70 130 L130 80 L180 120 L240 70 L260 130 Z"/>' +
265
+ '</g>' +
266
+ '</svg>'
267
+ );
268
+ }
269
+ var PLACEHOLDER_SVG = buildPlaceholderSvg();
270
+
271
+ var items = [
272
+ { id: 'g1', imageUrl: PLACEHOLDER_SVG, title: '[Item Title]', caption: '[Short caption describing this item.]', category: 'featured' },
273
+ { id: 'g2', imageUrl: PLACEHOLDER_SVG, title: '[Item Title]', caption: '[Short caption describing this item.]', category: 'archive' },
274
+ { id: 'g3', imageUrl: PLACEHOLDER_SVG, title: '[Item Title]', caption: '[Short caption describing this item.]', category: 'featured' },
275
+ { id: 'g4', imageUrl: PLACEHOLDER_SVG, title: '[Item Title]', caption: '[Short caption describing this item.]', category: 'draft' }
276
+ ];
277
+
278
+ var activeCat = 'all';
279
+ var lbIndex = -1;
280
+
281
+ var grid = document.getElementById('grid');
282
+ var filterRow = document.getElementById('filterRow');
283
+ var lbOverlay = document.getElementById('lightboxOverlay');
284
+ var lbImg = document.getElementById('lbImg');
285
+ var lbTitle = document.getElementById('lbTitle');
286
+ var lbCap = document.getElementById('lbCap');
287
+
288
+ function escapeHtml(s) {
289
+ return String(s).replace(/[&<>"']/g, function (c) {
290
+ return ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' })[c];
291
+ });
292
+ }
293
+
294
+ function escapeAttr(s) { return escapeHtml(s); }
295
+
296
+ function visibleItems() {
297
+ if (activeCat === 'all') return items.slice();
298
+ return items.filter(function (i) { return i.category === activeCat; });
299
+ }
300
+
301
+ function render() {
302
+ var rows = visibleItems();
303
+ if (!rows.length) {
304
+ grid.innerHTML = '<div class="gl-empty">' +
305
+ (items.length ? 'No items match this filter.' : 'No items yet — click Add Item to get started.') +
306
+ '</div>';
307
+ return;
308
+ }
309
+ grid.innerHTML = rows.map(function (it) {
310
+ var img = it.imageUrl || PLACEHOLDER_SVG;
311
+ return '<div class="gl-card" data-id="' + it.id + '">' +
312
+ '<img class="gl-thumb" src="' + escapeAttr(img) + '" alt="' + escapeAttr(it.title || '') + '" loading="lazy">' +
313
+ '<div class="gl-info">' +
314
+ '<div class="gl-title">' + escapeHtml(it.title || 'Untitled') + '</div>' +
315
+ (it.caption ? '<div class="gl-caption">' + escapeHtml(it.caption) + '</div>' : '') +
316
+ (it.category ? '<span class="gl-cat">' + escapeHtml(it.category) + '</span>' : '') +
317
+ '</div>' +
318
+ '</div>';
319
+ }).join('');
320
+ }
321
+
322
+ // Lightbox: indexes are into the currently-visible filtered list,
323
+ // so prev/next walks visible items (intuitive when a filter is active).
324
+ function openLightbox(itemId) {
325
+ var rows = visibleItems();
326
+ var idx = rows.findIndex(function (it) { return it.id === itemId; });
327
+ if (idx < 0) return;
328
+ lbIndex = idx;
329
+ showLightbox(rows);
330
+ lbOverlay.classList.add('open');
331
+ }
332
+
333
+ function showLightbox(rows) {
334
+ rows = rows || visibleItems();
335
+ if (!rows.length) { closeLightbox(); return; }
336
+ if (lbIndex < 0) lbIndex = 0;
337
+ if (lbIndex >= rows.length) lbIndex = rows.length - 1;
338
+ var it = rows[lbIndex];
339
+ lbImg.src = it.imageUrl || PLACEHOLDER_SVG;
340
+ lbImg.alt = it.title || '';
341
+ lbTitle.textContent = it.title || '';
342
+ lbCap.textContent = it.caption || '';
343
+ }
344
+
345
+ function closeLightbox() {
346
+ lbOverlay.classList.remove('open');
347
+ lbIndex = -1;
348
+ lbImg.src = '';
349
+ }
350
+
351
+ function navLightbox(delta) {
352
+ var rows = visibleItems();
353
+ if (!rows.length) return;
354
+ lbIndex = (lbIndex + delta + rows.length) % rows.length;
355
+ showLightbox(rows);
356
+ }
357
+
358
+ // Card click -> lightbox
359
+ grid.addEventListener('click', function (e) {
360
+ var card = e.target.closest('.gl-card');
361
+ if (!card) return;
362
+ openLightbox(card.getAttribute('data-id'));
363
+ });
364
+
365
+ // Filter chips
366
+ filterRow.addEventListener('click', function (e) {
367
+ var chip = e.target.closest('.filter-chip');
368
+ if (!chip) return;
369
+ filterRow.querySelectorAll('.filter-chip').forEach(function (c) {
370
+ c.classList.toggle('active', c === chip);
371
+ });
372
+ activeCat = chip.getAttribute('data-cat');
373
+ render();
374
+ });
375
+
376
+ // Lightbox controls
377
+ document.getElementById('lbClose').addEventListener('click', closeLightbox);
378
+ document.getElementById('lbPrev').addEventListener('click', function (e) { e.stopPropagation(); navLightbox(-1); });
379
+ document.getElementById('lbNext').addEventListener('click', function (e) { e.stopPropagation(); navLightbox(1); });
380
+ lbOverlay.addEventListener('click', function (e) {
381
+ if (e.target === lbOverlay || e.target.classList.contains('lightbox-stage')) closeLightbox();
382
+ });
383
+
384
+ document.addEventListener('keydown', function (e) {
385
+ if (!lbOverlay.classList.contains('open')) return;
386
+ if (e.key === 'Escape') { e.preventDefault(); closeLightbox(); }
387
+ else if (e.key === 'ArrowLeft') { e.preventDefault(); navLightbox(-1); }
388
+ else if (e.key === 'ArrowRight') { e.preventDefault(); navLightbox(1); }
389
+ });
390
+
391
+ // Add Item — minimal stub. Chat agent should wire this to the user's
392
+ // preferred image source (file upload, URL paste, __synthOSExtract, etc.)
393
+ document.getElementById('addItemBtn').addEventListener('click', function () {
394
+ var url = prompt('Image URL (leave blank for placeholder):');
395
+ if (url === null) return;
396
+ var title = prompt('Title:') || 'Untitled';
397
+ var caption = prompt('Caption (optional):') || '';
398
+ var item = {
399
+ id: 'g_' + Math.random().toString(36).slice(2, 9),
400
+ imageUrl: (url || '').trim() || PLACEHOLDER_SVG,
401
+ title: title.trim() || 'Untitled',
402
+ caption: caption.trim(),
403
+ category: activeCat === 'all' ? 'featured' : activeCat
404
+ };
405
+ items.push(item);
406
+ // synthos.shared.data.save('gallery_items', item);
407
+ render();
408
+ });
409
+
410
+ // Load persisted items (uncomment to enable):
411
+ // synthos.shared.data.list('gallery_items').then(function (rows) {
412
+ // if (rows && rows.length) { items = rows; render(); }
413
+ // });
414
+
415
+ render();
416
+ })();
417
+ </script>
418
+ </body></html>
@@ -0,0 +1,13 @@
1
+ {
2
+ "title": "Gallery",
3
+ "description": "Showcase images in a responsive card grid with lightbox preview for portfolios, products, or moodboards.",
4
+ "categories": [
5
+ "_Starters"
6
+ ],
7
+ "pinned": false,
8
+ "showInAll": false,
9
+ "pageVersion": 3,
10
+ "mode": "unlocked",
11
+ "greeting": "Welcome to the Gallery starter — an image-first responsive card grid with lightbox preview. Tell me what you'd like to showcase (e.g. photo album, product showcase, design portfolio, moodboard, recipe collection, travel album) and I'll wire the cards, categories, and lightbox.",
12
+ "firstRunGreeting": ""
13
+ }
@@ -0,0 +1 @@
1
+ [{"role":"assistant","content":"Welcome to the Generator starter — Archetype B from BLUEPRINT.md. Use this scaffold for input-form → AI-output → save-to-history pages. Tell me what you'd like to generate (e.g. thank-you replies, drip emails, social posts) and I'll wire the form fields, tone selector, and history list."}]