reflectt-node 0.1.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 (486) hide show
  1. package/LICENSE +178 -0
  2. package/README.md +188 -0
  3. package/dist/activationEvents.d.ts +110 -0
  4. package/dist/activationEvents.d.ts.map +1 -0
  5. package/dist/activationEvents.js +378 -0
  6. package/dist/activationEvents.js.map +1 -0
  7. package/dist/activity-signal.d.ts +30 -0
  8. package/dist/activity-signal.d.ts.map +1 -0
  9. package/dist/activity-signal.js +93 -0
  10. package/dist/activity-signal.js.map +1 -0
  11. package/dist/alert-integrity.d.ts +100 -0
  12. package/dist/alert-integrity.d.ts.map +1 -0
  13. package/dist/alert-integrity.js +333 -0
  14. package/dist/alert-integrity.js.map +1 -0
  15. package/dist/alert-preflight.d.ts +40 -0
  16. package/dist/alert-preflight.d.ts.map +1 -0
  17. package/dist/alert-preflight.js +235 -0
  18. package/dist/alert-preflight.js.map +1 -0
  19. package/dist/analytics.d.ts +131 -0
  20. package/dist/analytics.d.ts.map +1 -0
  21. package/dist/analytics.js +371 -0
  22. package/dist/analytics.js.map +1 -0
  23. package/dist/artifact-mirror.d.ts +26 -0
  24. package/dist/artifact-mirror.d.ts.map +1 -0
  25. package/dist/artifact-mirror.js +170 -0
  26. package/dist/artifact-mirror.js.map +1 -0
  27. package/dist/artifact-resolver.d.ts +48 -0
  28. package/dist/artifact-resolver.d.ts.map +1 -0
  29. package/dist/artifact-resolver.js +164 -0
  30. package/dist/artifact-resolver.js.map +1 -0
  31. package/dist/assignment.d.ts +116 -0
  32. package/dist/assignment.d.ts.map +1 -0
  33. package/dist/assignment.js +475 -0
  34. package/dist/assignment.js.map +1 -0
  35. package/dist/auditLedger.d.ts +50 -0
  36. package/dist/auditLedger.d.ts.map +1 -0
  37. package/dist/auditLedger.js +136 -0
  38. package/dist/auditLedger.js.map +1 -0
  39. package/dist/boardHealthWorker.d.ts +134 -0
  40. package/dist/boardHealthWorker.d.ts.map +1 -0
  41. package/dist/boardHealthWorker.js +882 -0
  42. package/dist/boardHealthWorker.js.map +1 -0
  43. package/dist/bootstrap-team.d.ts +42 -0
  44. package/dist/bootstrap-team.d.ts.map +1 -0
  45. package/dist/bootstrap-team.js +111 -0
  46. package/dist/bootstrap-team.js.map +1 -0
  47. package/dist/buildInfo.d.ts +17 -0
  48. package/dist/buildInfo.d.ts.map +1 -0
  49. package/dist/buildInfo.js +56 -0
  50. package/dist/buildInfo.js.map +1 -0
  51. package/dist/calendar-events.d.ts +133 -0
  52. package/dist/calendar-events.d.ts.map +1 -0
  53. package/dist/calendar-events.js +615 -0
  54. package/dist/calendar-events.js.map +1 -0
  55. package/dist/calendar-ical.d.ts +41 -0
  56. package/dist/calendar-ical.d.ts.map +1 -0
  57. package/dist/calendar-ical.js +413 -0
  58. package/dist/calendar-ical.js.map +1 -0
  59. package/dist/calendar-reminder-engine.d.ts +10 -0
  60. package/dist/calendar-reminder-engine.d.ts.map +1 -0
  61. package/dist/calendar-reminder-engine.js +143 -0
  62. package/dist/calendar-reminder-engine.js.map +1 -0
  63. package/dist/calendar.d.ts +75 -0
  64. package/dist/calendar.d.ts.map +1 -0
  65. package/dist/calendar.js +391 -0
  66. package/dist/calendar.js.map +1 -0
  67. package/dist/canvas-multiplexer.d.ts +44 -0
  68. package/dist/canvas-multiplexer.d.ts.map +1 -0
  69. package/dist/canvas-multiplexer.js +150 -0
  70. package/dist/canvas-multiplexer.js.map +1 -0
  71. package/dist/canvas-slots.d.ts +83 -0
  72. package/dist/canvas-slots.d.ts.map +1 -0
  73. package/dist/canvas-slots.js +144 -0
  74. package/dist/canvas-slots.js.map +1 -0
  75. package/dist/canvas-types.d.ts +56 -0
  76. package/dist/canvas-types.d.ts.map +1 -0
  77. package/dist/canvas-types.js +54 -0
  78. package/dist/canvas-types.js.map +1 -0
  79. package/dist/cf-keepalive.d.ts +40 -0
  80. package/dist/cf-keepalive.d.ts.map +1 -0
  81. package/dist/cf-keepalive.js +153 -0
  82. package/dist/cf-keepalive.js.map +1 -0
  83. package/dist/changeFeed.d.ts +38 -0
  84. package/dist/changeFeed.d.ts.map +1 -0
  85. package/dist/changeFeed.js +324 -0
  86. package/dist/changeFeed.js.map +1 -0
  87. package/dist/channels.d.ts +28 -0
  88. package/dist/channels.d.ts.map +1 -0
  89. package/dist/channels.js +23 -0
  90. package/dist/channels.js.map +1 -0
  91. package/dist/chat-approval-detector.d.ts +47 -0
  92. package/dist/chat-approval-detector.d.ts.map +1 -0
  93. package/dist/chat-approval-detector.js +224 -0
  94. package/dist/chat-approval-detector.js.map +1 -0
  95. package/dist/chat.d.ts +119 -0
  96. package/dist/chat.d.ts.map +1 -0
  97. package/dist/chat.js +666 -0
  98. package/dist/chat.js.map +1 -0
  99. package/dist/cli.d.ts +3 -0
  100. package/dist/cli.d.ts.map +1 -0
  101. package/dist/cli.js +1142 -0
  102. package/dist/cli.js.map +1 -0
  103. package/dist/cloud.d.ts +45 -0
  104. package/dist/cloud.d.ts.map +1 -0
  105. package/dist/cloud.js +962 -0
  106. package/dist/cloud.js.map +1 -0
  107. package/dist/config.d.ts +17 -0
  108. package/dist/config.d.ts.map +1 -0
  109. package/dist/config.js +33 -0
  110. package/dist/config.js.map +1 -0
  111. package/dist/connectivity.d.ts +59 -0
  112. package/dist/connectivity.d.ts.map +1 -0
  113. package/dist/connectivity.js +173 -0
  114. package/dist/connectivity.js.map +1 -0
  115. package/dist/contacts.d.ts +59 -0
  116. package/dist/contacts.d.ts.map +1 -0
  117. package/dist/contacts.js +183 -0
  118. package/dist/contacts.js.map +1 -0
  119. package/dist/content.d.ts +130 -0
  120. package/dist/content.d.ts.map +1 -0
  121. package/dist/content.js +186 -0
  122. package/dist/content.js.map +1 -0
  123. package/dist/context-budget.d.ts +87 -0
  124. package/dist/context-budget.d.ts.map +1 -0
  125. package/dist/context-budget.js +459 -0
  126. package/dist/context-budget.js.map +1 -0
  127. package/dist/continuity-loop.d.ts +55 -0
  128. package/dist/continuity-loop.d.ts.map +1 -0
  129. package/dist/continuity-loop.js +267 -0
  130. package/dist/continuity-loop.js.map +1 -0
  131. package/dist/dashboard.d.ts +6 -0
  132. package/dist/dashboard.d.ts.map +1 -0
  133. package/dist/dashboard.js +2348 -0
  134. package/dist/dashboard.js.map +1 -0
  135. package/dist/db.d.ts +44 -0
  136. package/dist/db.d.ts.map +1 -0
  137. package/dist/db.js +648 -0
  138. package/dist/db.js.map +1 -0
  139. package/dist/doctor.d.ts +30 -0
  140. package/dist/doctor.d.ts.map +1 -0
  141. package/dist/doctor.js +159 -0
  142. package/dist/doctor.js.map +1 -0
  143. package/dist/duplicateClosureGuard.d.ts +31 -0
  144. package/dist/duplicateClosureGuard.d.ts.map +1 -0
  145. package/dist/duplicateClosureGuard.js +83 -0
  146. package/dist/duplicateClosureGuard.js.map +1 -0
  147. package/dist/embeddings.d.ts +13 -0
  148. package/dist/embeddings.d.ts.map +1 -0
  149. package/dist/embeddings.js +78 -0
  150. package/dist/embeddings.js.map +1 -0
  151. package/dist/escalation.d.ts +80 -0
  152. package/dist/escalation.d.ts.map +1 -0
  153. package/dist/escalation.js +213 -0
  154. package/dist/escalation.js.map +1 -0
  155. package/dist/events.d.ts +130 -0
  156. package/dist/events.d.ts.map +1 -0
  157. package/dist/events.js +382 -0
  158. package/dist/events.js.map +1 -0
  159. package/dist/executionSweeper.d.ts +97 -0
  160. package/dist/executionSweeper.d.ts.map +1 -0
  161. package/dist/executionSweeper.js +875 -0
  162. package/dist/executionSweeper.js.map +1 -0
  163. package/dist/experiments.d.ts +47 -0
  164. package/dist/experiments.d.ts.map +1 -0
  165. package/dist/experiments.js +133 -0
  166. package/dist/experiments.js.map +1 -0
  167. package/dist/feedback.d.ts +179 -0
  168. package/dist/feedback.d.ts.map +1 -0
  169. package/dist/feedback.js +397 -0
  170. package/dist/feedback.js.map +1 -0
  171. package/dist/files.d.ts +52 -0
  172. package/dist/files.d.ts.map +1 -0
  173. package/dist/files.js +172 -0
  174. package/dist/files.js.map +1 -0
  175. package/dist/format-duration.d.ts +19 -0
  176. package/dist/format-duration.d.ts.map +1 -0
  177. package/dist/format-duration.js +33 -0
  178. package/dist/format-duration.js.map +1 -0
  179. package/dist/github-actor-auth.d.ts +20 -0
  180. package/dist/github-actor-auth.d.ts.map +1 -0
  181. package/dist/github-actor-auth.js +54 -0
  182. package/dist/github-actor-auth.js.map +1 -0
  183. package/dist/github-ci.d.ts +16 -0
  184. package/dist/github-ci.d.ts.map +1 -0
  185. package/dist/github-ci.js +37 -0
  186. package/dist/github-ci.js.map +1 -0
  187. package/dist/github-identity.d.ts +30 -0
  188. package/dist/github-identity.d.ts.map +1 -0
  189. package/dist/github-identity.js +96 -0
  190. package/dist/github-identity.js.map +1 -0
  191. package/dist/github-reviews.d.ts +24 -0
  192. package/dist/github-reviews.d.ts.map +1 -0
  193. package/dist/github-reviews.js +56 -0
  194. package/dist/github-reviews.js.map +1 -0
  195. package/dist/health.d.ts +391 -0
  196. package/dist/health.d.ts.map +1 -0
  197. package/dist/health.js +1841 -0
  198. package/dist/health.js.map +1 -0
  199. package/dist/host-keepalive.d.ts +22 -0
  200. package/dist/host-keepalive.d.ts.map +1 -0
  201. package/dist/host-keepalive.js +126 -0
  202. package/dist/host-keepalive.js.map +1 -0
  203. package/dist/host-registry.d.ts +43 -0
  204. package/dist/host-registry.d.ts.map +1 -0
  205. package/dist/host-registry.js +93 -0
  206. package/dist/host-registry.js.map +1 -0
  207. package/dist/inbox.d.ts +87 -0
  208. package/dist/inbox.d.ts.map +1 -0
  209. package/dist/inbox.js +410 -0
  210. package/dist/inbox.js.map +1 -0
  211. package/dist/index.d.ts +2 -0
  212. package/dist/index.d.ts.map +1 -0
  213. package/dist/index.js +306 -0
  214. package/dist/index.js.map +1 -0
  215. package/dist/insight-mutation.d.ts +32 -0
  216. package/dist/insight-mutation.d.ts.map +1 -0
  217. package/dist/insight-mutation.js +160 -0
  218. package/dist/insight-mutation.js.map +1 -0
  219. package/dist/insight-promotion.d.ts +89 -0
  220. package/dist/insight-promotion.d.ts.map +1 -0
  221. package/dist/insight-promotion.js +278 -0
  222. package/dist/insight-promotion.js.map +1 -0
  223. package/dist/insight-task-bridge.d.ts +77 -0
  224. package/dist/insight-task-bridge.d.ts.map +1 -0
  225. package/dist/insight-task-bridge.js +556 -0
  226. package/dist/insight-task-bridge.js.map +1 -0
  227. package/dist/insights.d.ts +222 -0
  228. package/dist/insights.d.ts.map +1 -0
  229. package/dist/insights.js +871 -0
  230. package/dist/insights.js.map +1 -0
  231. package/dist/intake-pipeline.d.ts +74 -0
  232. package/dist/intake-pipeline.d.ts.map +1 -0
  233. package/dist/intake-pipeline.js +199 -0
  234. package/dist/intake-pipeline.js.map +1 -0
  235. package/dist/intensity.d.ts +31 -0
  236. package/dist/intensity.d.ts.map +1 -0
  237. package/dist/intensity.js +94 -0
  238. package/dist/intensity.js.map +1 -0
  239. package/dist/knowledge-auto-index.d.ts +37 -0
  240. package/dist/knowledge-auto-index.d.ts.map +1 -0
  241. package/dist/knowledge-auto-index.js +149 -0
  242. package/dist/knowledge-auto-index.js.map +1 -0
  243. package/dist/knowledge-docs.d.ts +45 -0
  244. package/dist/knowledge-docs.d.ts.map +1 -0
  245. package/dist/knowledge-docs.js +188 -0
  246. package/dist/knowledge-docs.js.map +1 -0
  247. package/dist/lane-config.d.ts +25 -0
  248. package/dist/lane-config.d.ts.map +1 -0
  249. package/dist/lane-config.js +105 -0
  250. package/dist/lane-config.js.map +1 -0
  251. package/dist/lineage.d.ts +86 -0
  252. package/dist/lineage.d.ts.map +1 -0
  253. package/dist/lineage.js +303 -0
  254. package/dist/lineage.js.map +1 -0
  255. package/dist/logStore.d.ts +25 -0
  256. package/dist/logStore.d.ts.map +1 -0
  257. package/dist/logStore.js +83 -0
  258. package/dist/logStore.js.map +1 -0
  259. package/dist/manage.d.ts +12 -0
  260. package/dist/manage.d.ts.map +1 -0
  261. package/dist/manage.js +253 -0
  262. package/dist/manage.js.map +1 -0
  263. package/dist/mcp.d.ts +5 -0
  264. package/dist/mcp.d.ts.map +1 -0
  265. package/dist/mcp.js +604 -0
  266. package/dist/mcp.js.map +1 -0
  267. package/dist/memory.d.ts +47 -0
  268. package/dist/memory.d.ts.map +1 -0
  269. package/dist/memory.js +149 -0
  270. package/dist/memory.js.map +1 -0
  271. package/dist/mention-ack.d.ts +80 -0
  272. package/dist/mention-ack.d.ts.map +1 -0
  273. package/dist/mention-ack.js +175 -0
  274. package/dist/mention-ack.js.map +1 -0
  275. package/dist/messageRouter.d.ts +60 -0
  276. package/dist/messageRouter.d.ts.map +1 -0
  277. package/dist/messageRouter.js +309 -0
  278. package/dist/messageRouter.js.map +1 -0
  279. package/dist/mutationAlert.d.ts +44 -0
  280. package/dist/mutationAlert.d.ts.map +1 -0
  281. package/dist/mutationAlert.js +174 -0
  282. package/dist/mutationAlert.js.map +1 -0
  283. package/dist/noise-budget.d.ts +136 -0
  284. package/dist/noise-budget.d.ts.map +1 -0
  285. package/dist/noise-budget.js +340 -0
  286. package/dist/noise-budget.js.map +1 -0
  287. package/dist/notifications.d.ts +67 -0
  288. package/dist/notifications.d.ts.map +1 -0
  289. package/dist/notifications.js +253 -0
  290. package/dist/notifications.js.map +1 -0
  291. package/dist/openclaw.d.ts +34 -0
  292. package/dist/openclaw.d.ts.map +1 -0
  293. package/dist/openclaw.js +208 -0
  294. package/dist/openclaw.js.map +1 -0
  295. package/dist/pause-controls.d.ts +31 -0
  296. package/dist/pause-controls.d.ts.map +1 -0
  297. package/dist/pause-controls.js +130 -0
  298. package/dist/pause-controls.js.map +1 -0
  299. package/dist/pidlock.d.ts +25 -0
  300. package/dist/pidlock.d.ts.map +1 -0
  301. package/dist/pidlock.js +179 -0
  302. package/dist/pidlock.js.map +1 -0
  303. package/dist/policy.d.ts +139 -0
  304. package/dist/policy.d.ts.map +1 -0
  305. package/dist/policy.js +264 -0
  306. package/dist/policy.js.map +1 -0
  307. package/dist/polls.d.ts +47 -0
  308. package/dist/polls.d.ts.map +1 -0
  309. package/dist/polls.js +162 -0
  310. package/dist/polls.js.map +1 -0
  311. package/dist/portability.d.ts +55 -0
  312. package/dist/portability.d.ts.map +1 -0
  313. package/dist/portability.js +292 -0
  314. package/dist/portability.js.map +1 -0
  315. package/dist/pr-integrity.d.ts +45 -0
  316. package/dist/pr-integrity.d.ts.map +1 -0
  317. package/dist/pr-integrity.js +124 -0
  318. package/dist/pr-integrity.js.map +1 -0
  319. package/dist/prAutoMerge.d.ts +62 -0
  320. package/dist/prAutoMerge.d.ts.map +1 -0
  321. package/dist/prAutoMerge.js +493 -0
  322. package/dist/prAutoMerge.js.map +1 -0
  323. package/dist/preflight.d.ts +66 -0
  324. package/dist/preflight.d.ts.map +1 -0
  325. package/dist/preflight.js +864 -0
  326. package/dist/preflight.js.map +1 -0
  327. package/dist/presence.d.ts +98 -0
  328. package/dist/presence.d.ts.map +1 -0
  329. package/dist/presence.js +347 -0
  330. package/dist/presence.js.map +1 -0
  331. package/dist/provisioning.d.ts +101 -0
  332. package/dist/provisioning.d.ts.map +1 -0
  333. package/dist/provisioning.js +430 -0
  334. package/dist/provisioning.js.map +1 -0
  335. package/dist/reflection-automation.d.ts +59 -0
  336. package/dist/reflection-automation.d.ts.map +1 -0
  337. package/dist/reflection-automation.js +350 -0
  338. package/dist/reflection-automation.js.map +1 -0
  339. package/dist/reflections.d.ts +65 -0
  340. package/dist/reflections.d.ts.map +1 -0
  341. package/dist/reflections.js +306 -0
  342. package/dist/reflections.js.map +1 -0
  343. package/dist/release.d.ts +67 -0
  344. package/dist/release.d.ts.map +1 -0
  345. package/dist/release.js +275 -0
  346. package/dist/release.js.map +1 -0
  347. package/dist/request-tracker.d.ts +36 -0
  348. package/dist/request-tracker.d.ts.map +1 -0
  349. package/dist/request-tracker.js +109 -0
  350. package/dist/request-tracker.js.map +1 -0
  351. package/dist/research.d.ts +75 -0
  352. package/dist/research.d.ts.map +1 -0
  353. package/dist/research.js +171 -0
  354. package/dist/research.js.map +1 -0
  355. package/dist/routing-approvals.d.ts +73 -0
  356. package/dist/routing-approvals.d.ts.map +1 -0
  357. package/dist/routing-approvals.js +88 -0
  358. package/dist/routing-approvals.js.map +1 -0
  359. package/dist/routing-override.d.ts +94 -0
  360. package/dist/routing-override.d.ts.map +1 -0
  361. package/dist/routing-override.js +290 -0
  362. package/dist/routing-override.js.map +1 -0
  363. package/dist/scope-routing.d.ts +18 -0
  364. package/dist/scope-routing.d.ts.map +1 -0
  365. package/dist/scope-routing.js +29 -0
  366. package/dist/scope-routing.js.map +1 -0
  367. package/dist/secrets.d.ts +77 -0
  368. package/dist/secrets.d.ts.map +1 -0
  369. package/dist/secrets.js +287 -0
  370. package/dist/secrets.js.map +1 -0
  371. package/dist/server.d.ts +3 -0
  372. package/dist/server.d.ts.map +1 -0
  373. package/dist/server.js +10887 -0
  374. package/dist/server.js.map +1 -0
  375. package/dist/service-probe.d.ts +53 -0
  376. package/dist/service-probe.d.ts.map +1 -0
  377. package/dist/service-probe.js +225 -0
  378. package/dist/service-probe.js.map +1 -0
  379. package/dist/shared-workspace-api.d.ts +73 -0
  380. package/dist/shared-workspace-api.d.ts.map +1 -0
  381. package/dist/shared-workspace-api.js +281 -0
  382. package/dist/shared-workspace-api.js.map +1 -0
  383. package/dist/shipped-heartbeat.d.ts +91 -0
  384. package/dist/shipped-heartbeat.d.ts.map +1 -0
  385. package/dist/shipped-heartbeat.js +272 -0
  386. package/dist/shipped-heartbeat.js.map +1 -0
  387. package/dist/starter-team.d.ts +23 -0
  388. package/dist/starter-team.d.ts.map +1 -0
  389. package/dist/starter-team.js +88 -0
  390. package/dist/starter-team.js.map +1 -0
  391. package/dist/suppression-ledger.d.ts +73 -0
  392. package/dist/suppression-ledger.d.ts.map +1 -0
  393. package/dist/suppression-ledger.js +125 -0
  394. package/dist/suppression-ledger.js.map +1 -0
  395. package/dist/system-loop-state.d.ts +4 -0
  396. package/dist/system-loop-state.d.ts.map +1 -0
  397. package/dist/system-loop-state.js +40 -0
  398. package/dist/system-loop-state.js.map +1 -0
  399. package/dist/taskCommentIngest.d.ts +43 -0
  400. package/dist/taskCommentIngest.d.ts.map +1 -0
  401. package/dist/taskCommentIngest.js +59 -0
  402. package/dist/taskCommentIngest.js.map +1 -0
  403. package/dist/taskPrecheck.d.ts +20 -0
  404. package/dist/taskPrecheck.d.ts.map +1 -0
  405. package/dist/taskPrecheck.js +329 -0
  406. package/dist/taskPrecheck.js.map +1 -0
  407. package/dist/taskStateSync.d.ts +8 -0
  408. package/dist/taskStateSync.d.ts.map +1 -0
  409. package/dist/taskStateSync.js +79 -0
  410. package/dist/taskStateSync.js.map +1 -0
  411. package/dist/tasks.d.ts +140 -0
  412. package/dist/tasks.d.ts.map +1 -0
  413. package/dist/tasks.js +1281 -0
  414. package/dist/tasks.js.map +1 -0
  415. package/dist/team-config.d.ts +24 -0
  416. package/dist/team-config.d.ts.map +1 -0
  417. package/dist/team-config.js +221 -0
  418. package/dist/team-config.js.map +1 -0
  419. package/dist/team-doctor.d.ts +22 -0
  420. package/dist/team-doctor.d.ts.map +1 -0
  421. package/dist/team-doctor.js +270 -0
  422. package/dist/team-doctor.js.map +1 -0
  423. package/dist/team-pulse.d.ts +52 -0
  424. package/dist/team-pulse.d.ts.map +1 -0
  425. package/dist/team-pulse.js +176 -0
  426. package/dist/team-pulse.js.map +1 -0
  427. package/dist/telemetry.d.ts +74 -0
  428. package/dist/telemetry.d.ts.map +1 -0
  429. package/dist/telemetry.js +256 -0
  430. package/dist/telemetry.js.map +1 -0
  431. package/dist/test-task-filter.d.ts +21 -0
  432. package/dist/test-task-filter.d.ts.map +1 -0
  433. package/dist/test-task-filter.js +48 -0
  434. package/dist/test-task-filter.js.map +1 -0
  435. package/dist/types.d.ts +126 -0
  436. package/dist/types.d.ts.map +1 -0
  437. package/dist/types.js +4 -0
  438. package/dist/types.js.map +1 -0
  439. package/dist/usage-tracking.d.ts +101 -0
  440. package/dist/usage-tracking.d.ts.map +1 -0
  441. package/dist/usage-tracking.js +325 -0
  442. package/dist/usage-tracking.js.map +1 -0
  443. package/dist/vector-store.d.ts +87 -0
  444. package/dist/vector-store.d.ts.map +1 -0
  445. package/dist/vector-store.js +247 -0
  446. package/dist/vector-store.js.map +1 -0
  447. package/dist/watchdog/idleNudgeLane.d.ts +22 -0
  448. package/dist/watchdog/idleNudgeLane.d.ts.map +1 -0
  449. package/dist/watchdog/idleNudgeLane.js +98 -0
  450. package/dist/watchdog/idleNudgeLane.js.map +1 -0
  451. package/dist/webhooks.d.ts +103 -0
  452. package/dist/webhooks.d.ts.map +1 -0
  453. package/dist/webhooks.js +398 -0
  454. package/dist/webhooks.js.map +1 -0
  455. package/dist/working-contract.d.ts +42 -0
  456. package/dist/working-contract.d.ts.map +1 -0
  457. package/dist/working-contract.js +228 -0
  458. package/dist/working-contract.js.map +1 -0
  459. package/dist/ws-heartbeat.d.ts +66 -0
  460. package/dist/ws-heartbeat.d.ts.map +1 -0
  461. package/dist/ws-heartbeat.js +174 -0
  462. package/dist/ws-heartbeat.js.map +1 -0
  463. package/package.json +87 -0
  464. package/plugins/reflectt-channel/README.md +96 -0
  465. package/plugins/reflectt-channel/index.ts +789 -0
  466. package/plugins/reflectt-channel/openclaw.plugin.json +23 -0
  467. package/plugins/reflectt-channel/package.json +23 -0
  468. package/plugins/reflectt-channel/src/channel.ts +433 -0
  469. package/plugins/reflectt-channel/src/types.ts +29 -0
  470. package/public/avatars/echo.png +0 -0
  471. package/public/avatars/harmony.png +0 -0
  472. package/public/avatars/kai.png +0 -0
  473. package/public/avatars/link.png +0 -0
  474. package/public/avatars/pixel.png +0 -0
  475. package/public/avatars/rhythm.png +0 -0
  476. package/public/avatars/ryan.png +0 -0
  477. package/public/avatars/sage.png +0 -0
  478. package/public/avatars/scout.png +0 -0
  479. package/public/avatars/spark.png +0 -0
  480. package/public/dashboard-animations.css +381 -0
  481. package/public/dashboard.js +3479 -0
  482. package/public/docs.md +1062 -0
  483. package/public/file-upload-mock.html +1097 -0
  484. package/public/og-card.png +0 -0
  485. package/public/ui-kit.html +318 -0
  486. package/public/widget/feedback.js +194 -0
@@ -0,0 +1,1097 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>File Upload UI — Reflectt Design Mock</title>
7
+ <style>
8
+ /* ── Design Tokens (from reflectt-node tokens v1) ── */
9
+ :root {
10
+ --bg: #0d1117;
11
+ --surface: #161b22;
12
+ --surface-raised: #1c2129;
13
+ --surface-hover: #21262d;
14
+ --border: #30363d;
15
+ --border-subtle: #21262d;
16
+ --border-focus: #58a6ff;
17
+ --text: #e6edf3;
18
+ --text-muted: #8b949e;
19
+ --text-dim: #6e7681;
20
+ --accent: #58a6ff;
21
+ --accent-hover: #79c0ff;
22
+ --accent-dim: rgba(56,139,253,0.15);
23
+ --green: #3fb950;
24
+ --green-dim: rgba(63,185,80,0.15);
25
+ --red: #f85149;
26
+ --red-dim: rgba(248,81,73,0.15);
27
+ --yellow: #d29922;
28
+ --yellow-dim: rgba(210,153,34,0.15);
29
+ --radius-sm: 6px;
30
+ --radius-md: 8px;
31
+ --radius-lg: 12px;
32
+ --space-1: 4px;
33
+ --space-2: 8px;
34
+ --space-3: 12px;
35
+ --space-4: 16px;
36
+ --space-5: 20px;
37
+ --space-6: 24px;
38
+ --text-xs: 11px;
39
+ --text-sm: 12px;
40
+ --text-base: 14px;
41
+ --text-lg: 16px;
42
+ --text-xl: 20px;
43
+ --font-weight-normal: 400;
44
+ --font-weight-medium: 500;
45
+ --font-weight-semibold: 600;
46
+ --transition-fast: 150ms;
47
+ --transition-normal: 200ms;
48
+ --easing-smooth: cubic-bezier(0.4, 0, 0.2, 1);
49
+ --focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--border-focus);
50
+ --shadow-hover: 0 2px 8px rgba(0,0,0,0.3);
51
+ --shadow-card: 0 1px 3px rgba(0,0,0,0.2);
52
+ }
53
+
54
+ * { margin: 0; padding: 0; box-sizing: border-box; }
55
+ body {
56
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
57
+ background: var(--bg);
58
+ color: var(--text);
59
+ font-size: var(--text-base);
60
+ line-height: 1.5;
61
+ padding: var(--space-6);
62
+ max-width: 900px;
63
+ margin: 0 auto;
64
+ }
65
+
66
+ h1 { font-size: var(--text-xl); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-2); }
67
+ h2 { font-size: var(--text-lg); font-weight: var(--font-weight-semibold); margin: var(--space-6) 0 var(--space-3); color: var(--text-muted); }
68
+ .subtitle { color: var(--text-muted); font-size: var(--text-sm); margin-bottom: var(--space-6); }
69
+
70
+ /* ── Section panels ── */
71
+ .section {
72
+ background: var(--surface);
73
+ border: 1px solid var(--border-subtle);
74
+ border-radius: var(--radius-lg);
75
+ padding: var(--space-5);
76
+ margin-bottom: var(--space-5);
77
+ }
78
+ .section-title {
79
+ font-size: var(--text-base);
80
+ font-weight: var(--font-weight-semibold);
81
+ margin-bottom: var(--space-4);
82
+ display: flex;
83
+ align-items: center;
84
+ gap: var(--space-2);
85
+ }
86
+
87
+ /* ── Drop Zone ── */
88
+ .drop-zone {
89
+ border: 2px dashed var(--border);
90
+ border-radius: var(--radius-lg);
91
+ padding: var(--space-6) var(--space-4);
92
+ text-align: center;
93
+ cursor: pointer;
94
+ transition: all var(--transition-normal) var(--easing-smooth);
95
+ position: relative;
96
+ min-height: 140px;
97
+ display: flex;
98
+ flex-direction: column;
99
+ align-items: center;
100
+ justify-content: center;
101
+ gap: var(--space-2);
102
+ }
103
+ .drop-zone .icon {
104
+ font-size: 32px;
105
+ opacity: 0.6;
106
+ transition: opacity var(--transition-fast) var(--easing-smooth);
107
+ }
108
+ .drop-zone .label {
109
+ font-size: var(--text-base);
110
+ color: var(--text-muted);
111
+ }
112
+ .drop-zone .label strong {
113
+ color: var(--accent);
114
+ font-weight: var(--font-weight-medium);
115
+ }
116
+ .drop-zone .hint {
117
+ font-size: var(--text-xs);
118
+ color: var(--text-dim);
119
+ }
120
+ .drop-zone input[type="file"] {
121
+ position: absolute;
122
+ inset: 0;
123
+ opacity: 0;
124
+ cursor: pointer;
125
+ }
126
+
127
+ @media (hover: hover) and (pointer: fine) {
128
+ .drop-zone:hover {
129
+ border-color: var(--accent);
130
+ background: var(--accent-dim);
131
+ }
132
+ .drop-zone:hover .icon { opacity: 1; }
133
+ }
134
+
135
+ .drop-zone.drag-over {
136
+ border-color: var(--accent);
137
+ background: var(--accent-dim);
138
+ border-style: solid;
139
+ transform: scale(1.01);
140
+ }
141
+ .drop-zone.drag-over .icon { opacity: 1; }
142
+
143
+ .drop-zone:focus-within {
144
+ box-shadow: var(--focus-ring);
145
+ border-color: var(--border-focus);
146
+ }
147
+
148
+ /* ── Upload Progress ── */
149
+ .upload-queue {
150
+ margin-top: var(--space-3);
151
+ display: flex;
152
+ flex-direction: column;
153
+ gap: var(--space-2);
154
+ }
155
+ .upload-item {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: var(--space-3);
159
+ padding: var(--space-2) var(--space-3);
160
+ background: var(--surface-raised);
161
+ border-radius: var(--radius-sm);
162
+ border: 1px solid var(--border-subtle);
163
+ }
164
+ .upload-item .file-icon {
165
+ font-size: 18px;
166
+ flex-shrink: 0;
167
+ width: 24px;
168
+ text-align: center;
169
+ }
170
+ .upload-item .file-info {
171
+ flex: 1;
172
+ min-width: 0;
173
+ }
174
+ .upload-item .file-name {
175
+ font-size: var(--text-sm);
176
+ font-weight: var(--font-weight-medium);
177
+ white-space: nowrap;
178
+ overflow: hidden;
179
+ text-overflow: ellipsis;
180
+ }
181
+ .upload-item .file-size {
182
+ font-size: var(--text-xs);
183
+ color: var(--text-dim);
184
+ }
185
+ .upload-item .progress-bar {
186
+ flex: 1;
187
+ height: 4px;
188
+ background: var(--border-subtle);
189
+ border-radius: 2px;
190
+ overflow: hidden;
191
+ max-width: 200px;
192
+ }
193
+ .upload-item .progress-fill {
194
+ height: 100%;
195
+ border-radius: 2px;
196
+ transition: width var(--transition-normal) var(--easing-smooth);
197
+ }
198
+ .upload-item .progress-fill.uploading { background: var(--accent); }
199
+ .upload-item .progress-fill.done { background: var(--green); }
200
+ .upload-item .progress-fill.error { background: var(--red); }
201
+
202
+ .upload-item .status-icon { flex-shrink: 0; font-size: var(--text-sm); }
203
+ .upload-item .status-icon.done { color: var(--green); }
204
+ .upload-item .status-icon.error { color: var(--red); }
205
+
206
+ .upload-item .cancel-btn {
207
+ background: none;
208
+ border: none;
209
+ color: var(--text-dim);
210
+ cursor: pointer;
211
+ font-size: var(--text-sm);
212
+ padding: var(--space-1);
213
+ border-radius: var(--radius-sm);
214
+ transition: color var(--transition-fast);
215
+ font-family: inherit;
216
+ }
217
+ @media (hover: hover) and (pointer: fine) {
218
+ .upload-item .cancel-btn:hover { color: var(--red); }
219
+ }
220
+
221
+ /* ── File List / Browser ── */
222
+ .file-toolbar {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: var(--space-2);
226
+ margin-bottom: var(--space-3);
227
+ flex-wrap: wrap;
228
+ }
229
+ .file-search {
230
+ flex: 1;
231
+ min-width: 180px;
232
+ background: var(--surface-raised);
233
+ border: 1px solid var(--border-subtle);
234
+ border-radius: var(--radius-sm);
235
+ padding: var(--space-2) var(--space-3);
236
+ color: var(--text);
237
+ font-size: var(--text-sm);
238
+ font-family: inherit;
239
+ transition: border-color var(--transition-fast);
240
+ }
241
+ .file-search:focus {
242
+ outline: none;
243
+ border-color: var(--border-focus);
244
+ box-shadow: var(--focus-ring);
245
+ }
246
+ .file-search::placeholder { color: var(--text-dim); }
247
+
248
+ .view-toggle {
249
+ display: flex;
250
+ border: 1px solid var(--border-subtle);
251
+ border-radius: var(--radius-sm);
252
+ overflow: hidden;
253
+ }
254
+ .view-toggle button {
255
+ background: var(--surface-raised);
256
+ border: none;
257
+ color: var(--text-muted);
258
+ padding: var(--space-1) var(--space-2);
259
+ cursor: pointer;
260
+ font-size: var(--text-sm);
261
+ font-family: inherit;
262
+ transition: all var(--transition-fast);
263
+ }
264
+ .view-toggle button.active {
265
+ background: var(--accent-dim);
266
+ color: var(--accent);
267
+ }
268
+ .view-toggle button + button { border-left: 1px solid var(--border-subtle); }
269
+
270
+ .file-grid {
271
+ display: grid;
272
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
273
+ gap: var(--space-3);
274
+ }
275
+ .file-card {
276
+ background: var(--surface-raised);
277
+ border: 1px solid var(--border-subtle);
278
+ border-radius: var(--radius-md);
279
+ padding: var(--space-3);
280
+ cursor: pointer;
281
+ transition: all var(--transition-normal) var(--easing-smooth);
282
+ text-align: center;
283
+ }
284
+ @media (hover: hover) and (pointer: fine) {
285
+ .file-card:hover {
286
+ border-color: var(--border);
287
+ box-shadow: var(--shadow-hover);
288
+ transform: translateY(-1px);
289
+ }
290
+ }
291
+ .file-card:focus-visible {
292
+ box-shadow: var(--focus-ring);
293
+ outline: none;
294
+ }
295
+ .file-card .thumb {
296
+ width: 100%;
297
+ aspect-ratio: 4/3;
298
+ background: var(--surface);
299
+ border-radius: var(--radius-sm);
300
+ margin-bottom: var(--space-2);
301
+ display: flex;
302
+ align-items: center;
303
+ justify-content: center;
304
+ overflow: hidden;
305
+ }
306
+ .file-card .thumb img {
307
+ width: 100%;
308
+ height: 100%;
309
+ object-fit: cover;
310
+ border-radius: var(--radius-sm);
311
+ }
312
+ .file-card .thumb .type-icon {
313
+ font-size: 28px;
314
+ opacity: 0.5;
315
+ }
316
+ .file-card .card-name {
317
+ font-size: var(--text-sm);
318
+ font-weight: var(--font-weight-medium);
319
+ white-space: nowrap;
320
+ overflow: hidden;
321
+ text-overflow: ellipsis;
322
+ }
323
+ .file-card .card-meta {
324
+ font-size: var(--text-xs);
325
+ color: var(--text-dim);
326
+ margin-top: 2px;
327
+ }
328
+
329
+ /* List view */
330
+ .file-list {
331
+ display: flex;
332
+ flex-direction: column;
333
+ gap: 1px;
334
+ background: var(--border-subtle);
335
+ border-radius: var(--radius-md);
336
+ overflow: hidden;
337
+ }
338
+ .file-list-item {
339
+ display: flex;
340
+ align-items: center;
341
+ gap: var(--space-3);
342
+ padding: var(--space-2) var(--space-3);
343
+ background: var(--surface-raised);
344
+ cursor: pointer;
345
+ transition: background var(--transition-fast);
346
+ }
347
+ @media (hover: hover) and (pointer: fine) {
348
+ .file-list-item:hover { background: var(--surface-hover); }
349
+ }
350
+ .file-list-item:focus-visible {
351
+ box-shadow: var(--focus-ring);
352
+ outline: none;
353
+ z-index: 1;
354
+ }
355
+ .file-list-item .list-icon { font-size: 16px; flex-shrink: 0; width: 24px; text-align: center; }
356
+ .file-list-item .list-thumb {
357
+ width: 32px;
358
+ height: 32px;
359
+ border-radius: 4px;
360
+ object-fit: cover;
361
+ flex-shrink: 0;
362
+ }
363
+ .file-list-item .list-name {
364
+ flex: 1;
365
+ font-size: var(--text-sm);
366
+ font-weight: var(--font-weight-medium);
367
+ white-space: nowrap;
368
+ overflow: hidden;
369
+ text-overflow: ellipsis;
370
+ }
371
+ .file-list-item .list-meta {
372
+ font-size: var(--text-xs);
373
+ color: var(--text-dim);
374
+ flex-shrink: 0;
375
+ }
376
+ .file-list-item .list-actions {
377
+ display: flex;
378
+ gap: var(--space-1);
379
+ opacity: 0;
380
+ transition: opacity var(--transition-fast);
381
+ }
382
+ @media (hover: hover) and (pointer: fine) {
383
+ .file-list-item:hover .list-actions { opacity: 1; }
384
+ }
385
+ .file-list-item:focus-within .list-actions { opacity: 1; }
386
+ .action-btn {
387
+ background: none;
388
+ border: none;
389
+ color: var(--text-dim);
390
+ cursor: pointer;
391
+ padding: var(--space-1);
392
+ border-radius: var(--radius-sm);
393
+ font-size: var(--text-xs);
394
+ font-family: inherit;
395
+ transition: color var(--transition-fast);
396
+ }
397
+ @media (hover: hover) and (pointer: fine) {
398
+ .action-btn:hover { color: var(--text); }
399
+ .action-btn.delete:hover { color: var(--red); }
400
+ }
401
+
402
+ /* ── Chat Attachment Bar ── */
403
+ .chat-input-bar {
404
+ display: flex;
405
+ align-items: center;
406
+ gap: var(--space-2);
407
+ padding: var(--space-3);
408
+ background: var(--surface);
409
+ border: 1px solid var(--border-subtle);
410
+ border-radius: var(--radius-md);
411
+ }
412
+ .attach-btn {
413
+ background: none;
414
+ border: none;
415
+ color: var(--text-muted);
416
+ cursor: pointer;
417
+ font-size: 18px;
418
+ padding: var(--space-1);
419
+ border-radius: var(--radius-sm);
420
+ transition: color var(--transition-fast);
421
+ flex-shrink: 0;
422
+ font-family: inherit;
423
+ position: relative;
424
+ }
425
+ @media (hover: hover) and (pointer: fine) {
426
+ .attach-btn:hover { color: var(--accent); }
427
+ }
428
+ .attach-btn:focus-visible {
429
+ box-shadow: var(--focus-ring);
430
+ outline: none;
431
+ }
432
+ .attach-btn input[type="file"] {
433
+ position: absolute;
434
+ inset: 0;
435
+ opacity: 0;
436
+ cursor: pointer;
437
+ }
438
+ .chat-text-input {
439
+ flex: 1;
440
+ background: transparent;
441
+ border: none;
442
+ color: var(--text);
443
+ font-size: var(--text-base);
444
+ font-family: inherit;
445
+ outline: none;
446
+ }
447
+ .chat-text-input::placeholder { color: var(--text-dim); }
448
+ .chat-send-btn {
449
+ background: var(--accent);
450
+ color: var(--bg);
451
+ border: none;
452
+ border-radius: var(--radius-sm);
453
+ padding: var(--space-2) var(--space-3);
454
+ font-size: var(--text-sm);
455
+ font-weight: var(--font-weight-semibold);
456
+ cursor: pointer;
457
+ font-family: inherit;
458
+ transition: background var(--transition-fast);
459
+ flex-shrink: 0;
460
+ }
461
+ @media (hover: hover) and (pointer: fine) {
462
+ .chat-send-btn:hover { background: var(--accent-hover); }
463
+ }
464
+
465
+ /* Attachment preview strip */
466
+ .attachment-preview {
467
+ display: flex;
468
+ gap: var(--space-2);
469
+ padding: var(--space-2) var(--space-3);
470
+ flex-wrap: wrap;
471
+ }
472
+ .attachment-chip {
473
+ display: flex;
474
+ align-items: center;
475
+ gap: var(--space-2);
476
+ background: var(--surface-raised);
477
+ border: 1px solid var(--border-subtle);
478
+ border-radius: var(--radius-sm);
479
+ padding: var(--space-1) var(--space-2);
480
+ font-size: var(--text-xs);
481
+ max-width: 200px;
482
+ }
483
+ .attachment-chip img {
484
+ width: 24px;
485
+ height: 24px;
486
+ border-radius: 3px;
487
+ object-fit: cover;
488
+ }
489
+ .attachment-chip .chip-name {
490
+ white-space: nowrap;
491
+ overflow: hidden;
492
+ text-overflow: ellipsis;
493
+ flex: 1;
494
+ }
495
+ .attachment-chip .chip-remove {
496
+ background: none;
497
+ border: none;
498
+ color: var(--text-dim);
499
+ cursor: pointer;
500
+ font-size: var(--text-xs);
501
+ padding: 0 2px;
502
+ font-family: inherit;
503
+ }
504
+ @media (hover: hover) and (pointer: fine) {
505
+ .attachment-chip .chip-remove:hover { color: var(--red); }
506
+ }
507
+
508
+ /* ── Chat Message with File ── */
509
+ .chat-message {
510
+ display: flex;
511
+ gap: var(--space-3);
512
+ padding: var(--space-3);
513
+ border-radius: var(--radius-md);
514
+ }
515
+ .msg-avatar {
516
+ width: 28px;
517
+ height: 28px;
518
+ border-radius: 50%;
519
+ background: var(--accent-dim);
520
+ color: var(--accent);
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: center;
524
+ font-size: var(--text-xs);
525
+ font-weight: var(--font-weight-semibold);
526
+ flex-shrink: 0;
527
+ }
528
+ .msg-body { flex: 1; min-width: 0; }
529
+ .msg-header {
530
+ display: flex;
531
+ align-items: baseline;
532
+ gap: var(--space-2);
533
+ margin-bottom: var(--space-1);
534
+ }
535
+ .msg-sender {
536
+ font-size: var(--text-sm);
537
+ font-weight: var(--font-weight-semibold);
538
+ }
539
+ .msg-time {
540
+ font-size: var(--text-xs);
541
+ color: var(--text-dim);
542
+ }
543
+ .msg-text {
544
+ font-size: var(--text-sm);
545
+ color: var(--text-muted);
546
+ margin-bottom: var(--space-2);
547
+ }
548
+
549
+ .msg-file-card {
550
+ display: inline-flex;
551
+ align-items: center;
552
+ gap: var(--space-2);
553
+ background: var(--surface-raised);
554
+ border: 1px solid var(--border-subtle);
555
+ border-radius: var(--radius-md);
556
+ padding: var(--space-2) var(--space-3);
557
+ cursor: pointer;
558
+ transition: all var(--transition-fast);
559
+ text-decoration: none;
560
+ color: var(--text);
561
+ max-width: 100%;
562
+ }
563
+ @media (hover: hover) and (pointer: fine) {
564
+ .msg-file-card:hover {
565
+ border-color: var(--border);
566
+ background: var(--surface-hover);
567
+ }
568
+ }
569
+ .msg-file-card .file-thumb {
570
+ width: 40px;
571
+ height: 40px;
572
+ border-radius: var(--radius-sm);
573
+ object-fit: cover;
574
+ flex-shrink: 0;
575
+ }
576
+ .msg-file-card .file-thumb-placeholder {
577
+ width: 40px;
578
+ height: 40px;
579
+ border-radius: var(--radius-sm);
580
+ background: var(--surface);
581
+ display: flex;
582
+ align-items: center;
583
+ justify-content: center;
584
+ font-size: 18px;
585
+ flex-shrink: 0;
586
+ }
587
+ .msg-file-info { min-width: 0; }
588
+ .msg-file-info .name {
589
+ font-size: var(--text-sm);
590
+ font-weight: var(--font-weight-medium);
591
+ white-space: nowrap;
592
+ overflow: hidden;
593
+ text-overflow: ellipsis;
594
+ }
595
+ .msg-file-info .meta {
596
+ font-size: var(--text-xs);
597
+ color: var(--text-dim);
598
+ }
599
+ .msg-file-card .download-icon {
600
+ color: var(--text-dim);
601
+ font-size: var(--text-sm);
602
+ flex-shrink: 0;
603
+ margin-left: var(--space-2);
604
+ }
605
+
606
+ /* Inline image preview in chat */
607
+ .msg-image-preview {
608
+ max-width: 320px;
609
+ border-radius: var(--radius-md);
610
+ border: 1px solid var(--border-subtle);
611
+ overflow: hidden;
612
+ margin-top: var(--space-2);
613
+ cursor: pointer;
614
+ }
615
+ .msg-image-preview img {
616
+ width: 100%;
617
+ display: block;
618
+ }
619
+ .msg-image-preview .img-meta {
620
+ padding: var(--space-1) var(--space-2);
621
+ background: var(--surface-raised);
622
+ font-size: var(--text-xs);
623
+ color: var(--text-dim);
624
+ display: flex;
625
+ justify-content: space-between;
626
+ }
627
+
628
+ /* ── Task Attachment ── */
629
+ .task-attachments {
630
+ margin-top: var(--space-3);
631
+ padding-top: var(--space-3);
632
+ border-top: 1px solid var(--border-subtle);
633
+ }
634
+ .task-attachments-label {
635
+ font-size: var(--text-xs);
636
+ color: var(--text-dim);
637
+ text-transform: uppercase;
638
+ letter-spacing: 0.5px;
639
+ margin-bottom: var(--space-2);
640
+ font-weight: var(--font-weight-semibold);
641
+ }
642
+ .task-attachment-list {
643
+ display: flex;
644
+ flex-wrap: wrap;
645
+ gap: var(--space-2);
646
+ }
647
+ .task-attachment-chip {
648
+ display: flex;
649
+ align-items: center;
650
+ gap: var(--space-2);
651
+ background: var(--surface-raised);
652
+ border: 1px solid var(--border-subtle);
653
+ border-radius: var(--radius-sm);
654
+ padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
655
+ font-size: var(--text-xs);
656
+ cursor: pointer;
657
+ transition: border-color var(--transition-fast);
658
+ }
659
+ @media (hover: hover) and (pointer: fine) {
660
+ .task-attachment-chip:hover { border-color: var(--border); }
661
+ }
662
+ .task-attachment-chip img {
663
+ width: 20px;
664
+ height: 20px;
665
+ border-radius: 3px;
666
+ object-fit: cover;
667
+ }
668
+ .add-attachment-btn {
669
+ display: flex;
670
+ align-items: center;
671
+ gap: var(--space-1);
672
+ background: none;
673
+ border: 1px dashed var(--border);
674
+ border-radius: var(--radius-sm);
675
+ padding: var(--space-1) var(--space-2);
676
+ color: var(--text-dim);
677
+ font-size: var(--text-xs);
678
+ cursor: pointer;
679
+ font-family: inherit;
680
+ transition: all var(--transition-fast);
681
+ }
682
+ @media (hover: hover) and (pointer: fine) {
683
+ .add-attachment-btn:hover {
684
+ border-color: var(--accent);
685
+ color: var(--accent);
686
+ }
687
+ }
688
+
689
+ /* ── States ── */
690
+ .empty-state {
691
+ text-align: center;
692
+ padding: var(--space-6);
693
+ color: var(--text-dim);
694
+ font-size: var(--text-sm);
695
+ }
696
+
697
+ /* ── Responsive ── */
698
+ @media (max-width: 600px) {
699
+ body { padding: var(--space-3); }
700
+ .file-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
701
+ .chat-input-bar { flex-wrap: wrap; }
702
+ .chat-send-btn { width: 100%; min-height: 44px; }
703
+ }
704
+
705
+ /* ── Demo controls ── */
706
+ .demo-controls {
707
+ display: flex;
708
+ gap: var(--space-2);
709
+ margin-bottom: var(--space-4);
710
+ flex-wrap: wrap;
711
+ }
712
+ .demo-btn {
713
+ background: var(--surface-raised);
714
+ border: 1px solid var(--border);
715
+ color: var(--text-muted);
716
+ padding: var(--space-2) var(--space-3);
717
+ border-radius: var(--radius-sm);
718
+ font-size: var(--text-sm);
719
+ cursor: pointer;
720
+ font-family: inherit;
721
+ transition: all var(--transition-fast);
722
+ }
723
+ @media (hover: hover) and (pointer: fine) {
724
+ .demo-btn:hover { border-color: var(--accent); color: var(--accent); }
725
+ }
726
+ .demo-btn.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
727
+ .hidden { display: none !important; }
728
+ hr { border: none; border-top: 1px solid var(--border-subtle); margin: var(--space-6) 0; }
729
+ </style>
730
+ </head>
731
+ <body>
732
+
733
+ <h1>📁 File Upload UI</h1>
734
+ <p class="subtitle">Design mock — reflectt-node dashboard file sharing. All states are interactive.</p>
735
+
736
+ <div class="demo-controls">
737
+ <button class="demo-btn active" onclick="showSection('all')">All States</button>
738
+ <button class="demo-btn" onclick="showSection('upload')">Upload Zone</button>
739
+ <button class="demo-btn" onclick="showSection('progress')">Upload Progress</button>
740
+ <button class="demo-btn" onclick="showSection('browser')">File Browser</button>
741
+ <button class="demo-btn" onclick="showSection('chat')">Chat Attachment</button>
742
+ <button class="demo-btn" onclick="showSection('task')">Task Attachment</button>
743
+ </div>
744
+
745
+ <!-- ═══════════════════════════════════════════ -->
746
+ <!-- SECTION 1: DRAG & DROP UPLOAD ZONE -->
747
+ <!-- ═══════════════════════════════════════════ -->
748
+ <div class="section" id="sec-upload">
749
+ <div class="section-title">📤 Upload Zone</div>
750
+
751
+ <div class="drop-zone" id="dropZone" role="button" tabindex="0" aria-label="Upload files — drag and drop or click to browse">
752
+ <div class="icon">📂</div>
753
+ <div class="label">Drag files here or <strong>browse</strong></div>
754
+ <div class="hint">PDF, PNG, JPG, CSV, XLSX, TXT, MD — up to 50MB</div>
755
+ <input type="file" multiple accept=".pdf,.png,.jpg,.jpeg,.csv,.xlsx,.txt,.md" aria-label="Choose files to upload" id="fileInput">
756
+ </div>
757
+ </div>
758
+
759
+ <!-- ═══════════════════════════════════════════ -->
760
+ <!-- SECTION 2: UPLOAD PROGRESS -->
761
+ <!-- ═══════════════════════════════════════════ -->
762
+ <div class="section" id="sec-progress">
763
+ <div class="section-title">⏳ Upload Progress</div>
764
+
765
+ <div class="upload-queue" role="log" aria-label="Upload progress" aria-live="polite">
766
+ <!-- Uploading -->
767
+ <div class="upload-item">
768
+ <span class="file-icon">📄</span>
769
+ <div class="file-info">
770
+ <div class="file-name">bank-statement-jan-2026.pdf</div>
771
+ <div class="file-size">2.4 MB</div>
772
+ </div>
773
+ <div class="progress-bar"><div class="progress-fill uploading" style="width: 65%" id="progressDemo"></div></div>
774
+ <button class="cancel-btn" aria-label="Cancel upload">✕</button>
775
+ </div>
776
+
777
+ <!-- Done -->
778
+ <div class="upload-item">
779
+ <span class="file-icon">🖼️</span>
780
+ <div class="file-info">
781
+ <div class="file-name">screenshot-dashboard.png</div>
782
+ <div class="file-size">847 KB</div>
783
+ </div>
784
+ <div class="progress-bar"><div class="progress-fill done" style="width: 100%"></div></div>
785
+ <span class="status-icon done" aria-label="Upload complete">✓</span>
786
+ </div>
787
+
788
+ <!-- Error -->
789
+ <div class="upload-item">
790
+ <span class="file-icon">📊</span>
791
+ <div class="file-info">
792
+ <div class="file-name">financials-q4.xlsx</div>
793
+ <div class="file-size">68 MB — exceeds 50MB limit</div>
794
+ </div>
795
+ <div class="progress-bar"><div class="progress-fill error" style="width: 100%"></div></div>
796
+ <span class="status-icon error" aria-label="Upload failed">✕</span>
797
+ </div>
798
+ </div>
799
+ </div>
800
+
801
+ <!-- ═══════════════════════════════════════════ -->
802
+ <!-- SECTION 3: FILE BROWSER -->
803
+ <!-- ═══════════════════════════════════════════ -->
804
+ <div class="section" id="sec-browser">
805
+ <div class="section-title">📁 Files</div>
806
+
807
+ <div class="file-toolbar">
808
+ <input class="file-search" type="search" placeholder="Search files…" aria-label="Search files">
809
+ <div class="view-toggle" role="radiogroup" aria-label="View mode">
810
+ <button class="active" role="radio" aria-checked="true" onclick="setView('grid', this)" aria-label="Grid view">▦</button>
811
+ <button role="radio" aria-checked="false" onclick="setView('list', this)" aria-label="List view">☰</button>
812
+ </div>
813
+ </div>
814
+
815
+ <!-- Grid View -->
816
+ <div class="file-grid" id="gridView">
817
+ <div class="file-card" tabindex="0" role="button" aria-label="bank-statement-jan-2026.pdf, 2.4 MB">
818
+ <div class="thumb"><span class="type-icon">📄</span></div>
819
+ <div class="card-name">bank-statement-jan-2026.pdf</div>
820
+ <div class="card-meta">2.4 MB · 2m ago</div>
821
+ </div>
822
+ <div class="file-card" tabindex="0" role="button" aria-label="screenshot-dashboard.png, 847 KB">
823
+ <div class="thumb">
824
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='120' fill='%231c2129'%3E%3Crect width='160' height='120' rx='6'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%2358a6ff' font-size='12' font-family='sans-serif'%3Edashboard.png%3C/text%3E%3C/svg%3E" alt="Screenshot preview">
825
+ </div>
826
+ <div class="card-name">screenshot-dashboard.png</div>
827
+ <div class="card-meta">847 KB · 5m ago</div>
828
+ </div>
829
+ <div class="file-card" tabindex="0" role="button" aria-label="team-notes.md, 12 KB">
830
+ <div class="thumb"><span class="type-icon">📝</span></div>
831
+ <div class="card-name">team-notes.md</div>
832
+ <div class="card-meta">12 KB · 1h ago</div>
833
+ </div>
834
+ <div class="file-card" tabindex="0" role="button" aria-label="revenue-data.csv, 156 KB">
835
+ <div class="thumb"><span class="type-icon">📊</span></div>
836
+ <div class="card-name">revenue-data.csv</div>
837
+ <div class="card-meta">156 KB · 3h ago</div>
838
+ </div>
839
+ <div class="file-card" tabindex="0" role="button" aria-label="logo-v2.png, 340 KB">
840
+ <div class="thumb">
841
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='120' fill='%231c2129'%3E%3Crect width='160' height='120' rx='6'/%3E%3Ccircle cx='80' cy='55' r='25' fill='%233fb950' opacity='0.4'/%3E%3Ctext x='50%25' y='85%25' dominant-baseline='middle' text-anchor='middle' fill='%233fb950' font-size='10' font-family='sans-serif'%3Elogo-v2.png%3C/text%3E%3C/svg%3E" alt="Logo preview">
842
+ </div>
843
+ <div class="card-name">logo-v2.png</div>
844
+ <div class="card-meta">340 KB · yesterday</div>
845
+ </div>
846
+ </div>
847
+
848
+ <!-- List View (hidden by default) -->
849
+ <div class="file-list hidden" id="listView">
850
+ <div class="file-list-item" tabindex="0" role="button">
851
+ <span class="list-icon">📄</span>
852
+ <span class="list-name">bank-statement-jan-2026.pdf</span>
853
+ <span class="list-meta">2.4 MB</span>
854
+ <span class="list-meta">2m ago</span>
855
+ <div class="list-actions">
856
+ <button class="action-btn" aria-label="Download">⬇</button>
857
+ <button class="action-btn delete" aria-label="Delete">🗑</button>
858
+ </div>
859
+ </div>
860
+ <div class="file-list-item" tabindex="0" role="button">
861
+ <span class="list-icon">🖼️</span>
862
+ <img class="list-thumb" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' fill='%231c2129'%3E%3Crect width='32' height='32' rx='4'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%2358a6ff' font-size='6' font-family='sans-serif'%3Epng%3C/text%3E%3C/svg%3E" alt="Thumbnail">
863
+ <span class="list-name">screenshot-dashboard.png</span>
864
+ <span class="list-meta">847 KB</span>
865
+ <span class="list-meta">5m ago</span>
866
+ <div class="list-actions">
867
+ <button class="action-btn" aria-label="Download">⬇</button>
868
+ <button class="action-btn delete" aria-label="Delete">🗑</button>
869
+ </div>
870
+ </div>
871
+ <div class="file-list-item" tabindex="0" role="button">
872
+ <span class="list-icon">📝</span>
873
+ <span class="list-name">team-notes.md</span>
874
+ <span class="list-meta">12 KB</span>
875
+ <span class="list-meta">1h ago</span>
876
+ <div class="list-actions">
877
+ <button class="action-btn" aria-label="Download">⬇</button>
878
+ <button class="action-btn delete" aria-label="Delete">🗑</button>
879
+ </div>
880
+ </div>
881
+ <div class="file-list-item" tabindex="0" role="button">
882
+ <span class="list-icon">📊</span>
883
+ <span class="list-name">revenue-data.csv</span>
884
+ <span class="list-meta">156 KB</span>
885
+ <span class="list-meta">3h ago</span>
886
+ <div class="list-actions">
887
+ <button class="action-btn" aria-label="Download">⬇</button>
888
+ <button class="action-btn delete" aria-label="Delete">🗑</button>
889
+ </div>
890
+ </div>
891
+ <div class="file-list-item" tabindex="0" role="button">
892
+ <span class="list-icon">🖼️</span>
893
+ <img class="list-thumb" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' fill='%231c2129'%3E%3Crect width='32' height='32' rx='4'/%3E%3Ccircle cx='16' cy='14' r='6' fill='%233fb950' opacity='0.4'/%3E%3Ctext x='50%25' y='85%25' dominant-baseline='middle' text-anchor='middle' fill='%233fb950' font-size='5' font-family='sans-serif'%3Elogo%3C/text%3E%3C/svg%3E" alt="Logo thumbnail">
894
+ <span class="list-name">logo-v2.png</span>
895
+ <span class="list-meta">340 KB</span>
896
+ <span class="list-meta">yesterday</span>
897
+ <div class="list-actions">
898
+ <button class="action-btn" aria-label="Download">⬇</button>
899
+ <button class="action-btn delete" aria-label="Delete">🗑</button>
900
+ </div>
901
+ </div>
902
+ </div>
903
+ </div>
904
+
905
+ <hr>
906
+
907
+ <!-- ═══════════════════════════════════════════ -->
908
+ <!-- SECTION 4: CHAT ATTACHMENT FLOW -->
909
+ <!-- ═══════════════════════════════════════════ -->
910
+ <div class="section" id="sec-chat">
911
+ <div class="section-title">💬 Chat — Attachment Flow</div>
912
+
913
+ <!-- State: attachment selected, ready to send -->
914
+ <div class="attachment-preview" aria-label="Attached files">
915
+ <div class="attachment-chip">
916
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%231c2129'%3E%3Crect width='24' height='24' rx='3'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%2358a6ff' font-size='6' font-family='sans-serif'%3Epdf%3C/text%3E%3C/svg%3E" alt="">
917
+ <span class="chip-name">bank-statement.pdf</span>
918
+ <button class="chip-remove" aria-label="Remove attachment">✕</button>
919
+ </div>
920
+ </div>
921
+
922
+ <div class="chat-input-bar">
923
+ <button class="attach-btn" aria-label="Attach file" title="Attach file">
924
+ 📎
925
+ <input type="file" multiple accept=".pdf,.png,.jpg,.jpeg,.csv,.xlsx,.txt,.md" aria-label="Choose file to attach">
926
+ </button>
927
+ <input class="chat-text-input" type="text" placeholder="Message as ryan…" value="Here's the January statement for review">
928
+ <button class="chat-send-btn">Send</button>
929
+ </div>
930
+
931
+ <h2>Message with file attachment (non-image)</h2>
932
+ <div class="chat-message">
933
+ <div class="msg-avatar">R</div>
934
+ <div class="msg-body">
935
+ <div class="msg-header">
936
+ <span class="msg-sender">ryan</span>
937
+ <span class="msg-time">2:34 PM</span>
938
+ </div>
939
+ <div class="msg-text">Here's the January statement for review</div>
940
+ <a class="msg-file-card" href="#" aria-label="Download bank-statement-jan-2026.pdf">
941
+ <div class="file-thumb-placeholder">📄</div>
942
+ <div class="msg-file-info">
943
+ <div class="name">bank-statement-jan-2026.pdf</div>
944
+ <div class="meta">PDF · 2.4 MB</div>
945
+ </div>
946
+ <span class="download-icon">⬇</span>
947
+ </a>
948
+ </div>
949
+ </div>
950
+
951
+ <h2>Message with image (inline preview)</h2>
952
+ <div class="chat-message">
953
+ <div class="msg-avatar" style="background: var(--green-dim); color: var(--green);">P</div>
954
+ <div class="msg-body">
955
+ <div class="msg-header">
956
+ <span class="msg-sender">pixel</span>
957
+ <span class="msg-time">2:41 PM</span>
958
+ </div>
959
+ <div class="msg-text">Updated dashboard design — check the sidebar nav</div>
960
+ <div class="msg-image-preview">
961
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='180' fill='%231c2129'%3E%3Crect width='320' height='180' rx='0'/%3E%3Crect x='10' y='10' width='60' height='160' rx='6' fill='%2321262d'/%3E%3Crect x='80' y='10' width='230' height='76' rx='6' fill='%2321262d'/%3E%3Crect x='80' y='94' width='110' height='76' rx='6' fill='%2321262d'/%3E%3Crect x='198' y='94' width='112' height='76' rx='6' fill='%2321262d'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%2358a6ff' font-size='11' font-family='sans-serif'%3Edashboard-redesign.png%3C/text%3E%3C/svg%3E" alt="Dashboard redesign screenshot">
962
+ <div class="img-meta">
963
+ <span>dashboard-redesign.png</span>
964
+ <span>847 KB</span>
965
+ </div>
966
+ </div>
967
+ </div>
968
+ </div>
969
+ </div>
970
+
971
+ <hr>
972
+
973
+ <!-- ═══════════════════════════════════════════ -->
974
+ <!-- SECTION 5: TASK ATTACHMENTS -->
975
+ <!-- ═══════════════════════════════════════════ -->
976
+ <div class="section" id="sec-task">
977
+ <div class="section-title">📋 Task — File Attachments</div>
978
+
979
+ <div style="background: var(--surface-raised); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: var(--space-4);">
980
+ <div style="display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2);">
981
+ <span style="background: var(--yellow-dim); color: var(--yellow); font-size: var(--text-xs); padding: 2px 6px; border-radius: 3px; font-weight: var(--font-weight-semibold);">P1</span>
982
+ <span style="font-weight: var(--font-weight-semibold);">Review bank statements for Q1 reconciliation</span>
983
+ </div>
984
+ <div style="font-size: var(--text-sm); color: var(--text-muted); margin-bottom: var(--space-2);">Assigned to: <strong>kai</strong> · Status: doing</div>
985
+
986
+ <div class="task-attachments">
987
+ <div class="task-attachments-label">📎 Attachments (2)</div>
988
+ <div class="task-attachment-list">
989
+ <div class="task-attachment-chip" tabindex="0" role="button" aria-label="Open bank-statement-jan-2026.pdf">
990
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%231c2129'%3E%3Crect width='20' height='20' rx='3'/%3E%3Ctext x='50%25' y='55%25' dominant-baseline='middle' text-anchor='middle' fill='%23f85149' font-size='6' font-family='sans-serif'%3EPDF%3C/text%3E%3C/svg%3E" alt="">
991
+ <span>bank-statement-jan-2026.pdf</span>
992
+ </div>
993
+ <div class="task-attachment-chip" tabindex="0" role="button" aria-label="Open revenue-data.csv">
994
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%231c2129'%3E%3Crect width='20' height='20' rx='3'/%3E%3Ctext x='50%25' y='55%25' dominant-baseline='middle' text-anchor='middle' fill='%233fb950' font-size='6' font-family='sans-serif'%3ECSV%3C/text%3E%3C/svg%3E" alt="">
995
+ <span>revenue-data.csv</span>
996
+ </div>
997
+ <button class="add-attachment-btn" aria-label="Attach file to task">+ Add file</button>
998
+ </div>
999
+ </div>
1000
+ </div>
1001
+ </div>
1002
+
1003
+ <script>
1004
+ // ── Demo interactivity ──
1005
+
1006
+ // Drop zone drag states
1007
+ const dropZone = document.getElementById('dropZone');
1008
+ const fileInput = document.getElementById('fileInput');
1009
+
1010
+ ['dragenter', 'dragover'].forEach(e => {
1011
+ dropZone.addEventListener(e, (ev) => {
1012
+ ev.preventDefault();
1013
+ dropZone.classList.add('drag-over');
1014
+ });
1015
+ });
1016
+ ['dragleave', 'drop'].forEach(e => {
1017
+ dropZone.addEventListener(e, (ev) => {
1018
+ ev.preventDefault();
1019
+ dropZone.classList.remove('drag-over');
1020
+ });
1021
+ });
1022
+ dropZone.addEventListener('drop', (ev) => {
1023
+ const files = ev.dataTransfer?.files;
1024
+ if (files?.length) {
1025
+ alert('Would upload ' + files.length + ' file(s): ' + Array.from(files).map(f => f.name).join(', '));
1026
+ }
1027
+ });
1028
+ fileInput.addEventListener('change', () => {
1029
+ if (fileInput.files?.length) {
1030
+ alert('Would upload ' + fileInput.files.length + ' file(s): ' + Array.from(fileInput.files).map(f => f.name).join(', '));
1031
+ }
1032
+ });
1033
+
1034
+ // Keyboard activation for drop zone
1035
+ dropZone.addEventListener('keydown', (e) => {
1036
+ if (e.key === 'Enter' || e.key === ' ') {
1037
+ e.preventDefault();
1038
+ fileInput.click();
1039
+ }
1040
+ });
1041
+
1042
+ // Animated progress bar demo
1043
+ let progress = 0;
1044
+ const progressFill = document.getElementById('progressDemo');
1045
+ function animateProgress() {
1046
+ progress += Math.random() * 8;
1047
+ if (progress > 100) progress = 0;
1048
+ progressFill.style.width = Math.min(progress, 100) + '%';
1049
+ if (progress >= 100) {
1050
+ progressFill.classList.remove('uploading');
1051
+ progressFill.classList.add('done');
1052
+ setTimeout(() => {
1053
+ progressFill.classList.remove('done');
1054
+ progressFill.classList.add('uploading');
1055
+ progress = 0;
1056
+ animateProgress();
1057
+ }, 2000);
1058
+ return;
1059
+ }
1060
+ setTimeout(animateProgress, 300 + Math.random() * 500);
1061
+ }
1062
+ animateProgress();
1063
+
1064
+ // View toggle (grid/list)
1065
+ function setView(view, btn) {
1066
+ document.getElementById('gridView').classList.toggle('hidden', view !== 'grid');
1067
+ document.getElementById('listView').classList.toggle('hidden', view !== 'list');
1068
+ document.querySelectorAll('.view-toggle button').forEach(b => {
1069
+ b.classList.remove('active');
1070
+ b.setAttribute('aria-checked', 'false');
1071
+ });
1072
+ btn.classList.add('active');
1073
+ btn.setAttribute('aria-checked', 'true');
1074
+ }
1075
+
1076
+ // Section filter
1077
+ function showSection(id) {
1078
+ const sections = ['upload', 'progress', 'browser', 'chat', 'task'];
1079
+ document.querySelectorAll('.demo-btn').forEach(b => b.classList.remove('active'));
1080
+ event.target.classList.add('active');
1081
+
1082
+ if (id === 'all') {
1083
+ sections.forEach(s => {
1084
+ document.getElementById('sec-' + s).classList.remove('hidden');
1085
+ });
1086
+ document.querySelectorAll('hr').forEach(el => el.classList.remove('hidden'));
1087
+ return;
1088
+ }
1089
+ sections.forEach(s => {
1090
+ document.getElementById('sec-' + s).classList.toggle('hidden', s !== id);
1091
+ });
1092
+ document.querySelectorAll('hr').forEach(el => el.classList.add('hidden'));
1093
+ }
1094
+ </script>
1095
+
1096
+ </body>
1097
+ </html>