agmon 0.2.0 → 0.2.1

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 (278) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/fallback-build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +8 -8
  5. package/.next/server/app/_global-error.html +1 -1
  6. package/.next/server/app/_global-error.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  11. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/_not-found.html +1 -1
  13. package/.next/server/app/_not-found.rsc +15 -14
  14. package/.next/server/app/_not-found.segments/_full.segment.rsc +15 -14
  15. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -3
  16. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  17. package/.next/server/app/api/media/route.js.nft.json +1 -1
  18. package/.next/server/app/api/reports/tokens/route.js.nft.json +1 -1
  19. package/.next/server/app/api/sessions/[id]/transcript/route.js.nft.json +1 -1
  20. package/.next/server/app/api/traces/stream/route.js.nft.json +1 -1
  21. package/.next/server/app/api/version/route.js.nft.json +1 -1
  22. package/.next/server/app/api/workspace/file-content/route.js.nft.json +1 -1
  23. package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
  24. package/.next/server/app/chat/page.js.nft.json +1 -1
  25. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  26. package/.next/server/app/chat.html +1 -1
  27. package/.next/server/app/chat.rsc +20 -19
  28. package/.next/server/app/chat.segments/_full.segment.rsc +20 -19
  29. package/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
  30. package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +21 -20
  31. package/.next/server/app/index.html +1 -1
  32. package/.next/server/app/index.rsc +20 -18
  33. package/.next/server/app/index.segments/__PAGE__.segment.rsc +8 -8
  34. package/.next/server/app/index.segments/_full.segment.rsc +20 -18
  35. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  36. package/.next/server/app/page.js.nft.json +1 -1
  37. package/.next/server/app/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/reports/page.js.nft.json +1 -1
  39. package/.next/server/app/reports/page_client-reference-manifest.js +1 -1
  40. package/.next/server/app/reports.html +1 -1
  41. package/.next/server/app/reports.rsc +4 -4
  42. package/.next/server/app/reports.segments/_full.segment.rsc +4 -4
  43. package/.next/server/app/reports.segments/_tree.segment.rsc +2 -2
  44. package/.next/server/app/reports.segments/reports/__PAGE__.segment.rsc +4 -4
  45. package/.next/server/app/store/page.js.nft.json +1 -1
  46. package/.next/server/app/store/page_client-reference-manifest.js +1 -1
  47. package/.next/server/app/store.html +1 -1
  48. package/.next/server/app/store.rsc +5 -5
  49. package/.next/server/app/store.segments/_full.segment.rsc +5 -5
  50. package/.next/server/app/store.segments/_tree.segment.rsc +2 -2
  51. package/.next/server/app/store.segments/store/__PAGE__.segment.rsc +5 -5
  52. package/.next/server/chunks/_0ao-_t4jkb46h._.js +2 -2
  53. package/.next/server/chunks/_0ao-_t4jkb46h._.js.map +1 -1
  54. package/.next/server/chunks/src_lib_watchers_antigravityWatcher_0w1-atg39y__p.js.map +1 -1
  55. package/.next/server/chunks/ssr/[root-of-the-server]__0i2rbwbkxbdog._.js +3 -0
  56. package/.next/server/chunks/ssr/[root-of-the-server]__0i2rbwbkxbdog._.js.map +1 -0
  57. package/.next/server/chunks/ssr/[root-of-the-server]__0qzscpxebh28_._.js +3 -0
  58. package/.next/server/chunks/ssr/[root-of-the-server]__0qzscpxebh28_._.js.map +1 -0
  59. package/.next/server/chunks/ssr/[root-of-the-server]__1jwplflwix8wi._.js +427 -0
  60. package/.next/server/chunks/ssr/[root-of-the-server]__1jwplflwix8wi._.js.map +1 -0
  61. package/.next/server/chunks/ssr/[root-of-the-server]__1kt7h7bz59mdn._.js +1 -1
  62. package/.next/server/chunks/ssr/[root-of-the-server]__1kt7h7bz59mdn._.js.map +1 -1
  63. package/.next/server/chunks/ssr/[root-of-the-server]__1otsvjy81s8my._.js +427 -0
  64. package/.next/server/chunks/ssr/[root-of-the-server]__1otsvjy81s8my._.js.map +1 -0
  65. package/.next/server/chunks/ssr/_0--937zhi743v._.js +3 -0
  66. package/.next/server/chunks/ssr/_0--937zhi743v._.js.map +1 -0
  67. package/.next/server/chunks/ssr/_0e3frtjrk-wi9._.js +3 -0
  68. package/.next/server/chunks/ssr/_0e3frtjrk-wi9._.js.map +1 -0
  69. package/.next/server/chunks/ssr/_0h29jdf4relbq._.js +3 -0
  70. package/.next/server/chunks/ssr/_0h29jdf4relbq._.js.map +1 -0
  71. package/.next/server/chunks/ssr/_1487-zi23c5eb._.js +1 -1
  72. package/.next/server/chunks/ssr/_1487-zi23c5eb._.js.map +1 -1
  73. package/.next/server/chunks/ssr/_1vgwoe-shb9z7._.js +3 -0
  74. package/.next/server/chunks/ssr/_1vgwoe-shb9z7._.js.map +1 -0
  75. package/.next/server/chunks/ssr/_1zm4m-s8k7oe3._.js +3 -0
  76. package/.next/server/chunks/ssr/_1zm4m-s8k7oe3._.js.map +1 -0
  77. package/.next/server/chunks/ssr/_202tntue-jj6s._.js +3 -0
  78. package/.next/server/chunks/ssr/_202tntue-jj6s._.js.map +1 -0
  79. package/.next/server/chunks/ssr/{node_modules_1wlwrgnt65zus._.js → node_modules_00ebs67b4u61w._.js} +1 -1
  80. package/.next/server/chunks/ssr/{node_modules_0m3ihe65818y_._.js → node_modules_01p9ctt-n2dxp._.js} +1 -1
  81. package/.next/server/chunks/ssr/{node_modules_1kr1c-ncf8q9t._.js → node_modules_05i69rc9pwcdx._.js} +1 -1
  82. package/.next/server/chunks/ssr/{node_modules_02jwra-d9iqim._.js → node_modules_06mgkab1v5iox._.js} +2 -2
  83. package/.next/server/chunks/ssr/{node_modules_1dff7b_kvngr-._.js → node_modules_07bjxeq9dfgn1._.js} +2 -2
  84. package/.next/server/chunks/ssr/{node_modules_02vtgweceovke._.js → node_modules_08q6a-f2itxyo._.js} +1 -1
  85. package/.next/server/chunks/ssr/{node_modules_13nsmuhey_ti_._.js → node_modules_09v49jhajmvl4._.js} +2 -2
  86. package/.next/server/chunks/ssr/{node_modules_0oukyh0iq21ow._.js → node_modules_0b8zi3pbl-y9n._.js} +2 -2
  87. package/.next/server/chunks/ssr/{node_modules_061uaylfjwqk7._.js → node_modules_0d2ios01ot1in._.js} +1 -1
  88. package/.next/server/chunks/ssr/{node_modules_0b8ndnuql44z1._.js → node_modules_0dw0vozejrnml._.js} +2 -2
  89. package/.next/server/chunks/ssr/{node_modules_05w7qhtrzvnk6._.js → node_modules_0e3njj436xau-._.js} +1 -1
  90. package/.next/server/chunks/ssr/{node_modules_0z7rdbaf13024._.js → node_modules_0e6qoh__e4a69._.js} +1 -1
  91. package/.next/server/chunks/ssr/{node_modules_1ll-58c1c-qab._.js → node_modules_0hb0q0epwvp--._.js} +1 -1
  92. package/.next/server/chunks/ssr/{node_modules_0f773uqgzj7y7._.js → node_modules_0jla9ugf1y6rb._.js} +1 -1
  93. package/.next/server/chunks/ssr/{node_modules_0fd1swhk15cx3._.js → node_modules_0l-y0kqtu_r3o._.js} +1 -1
  94. package/.next/server/chunks/ssr/{node_modules_1zs2nou5uogby._.js → node_modules_0l814qpw677vm._.js} +1 -1
  95. package/.next/server/chunks/ssr/{node_modules_1c8i3jrmo4393._.js → node_modules_0lqovp8j8ld76._.js} +1 -1
  96. package/.next/server/chunks/ssr/{node_modules_0z3elum1675ve._.js → node_modules_0o63z1gd17rhb._.js} +1 -1
  97. package/.next/server/chunks/ssr/{node_modules_1xyxigbqzb8vs._.js → node_modules_0sjdrli5douui._.js} +1 -1
  98. package/.next/server/chunks/ssr/{node_modules_1iovyom0-y7o_._.js → node_modules_0xh8tnq1niblb._.js} +1 -1
  99. package/.next/server/chunks/ssr/{node_modules_0nde84kzuwv2n._.js → node_modules_0yayrqhzfk8wy._.js} +1 -1
  100. package/.next/server/chunks/ssr/{node_modules_0__m9_odts7_e._.js → node_modules_0z1e37smavebg._.js} +2 -2
  101. package/.next/server/chunks/ssr/{node_modules_0f4xh33v3iltc._.js → node_modules_0zb0i39mnjdf3._.js} +1 -1
  102. package/.next/server/chunks/ssr/{node_modules_02nv3yff2pqh8._.js → node_modules_10g1mmrf63d8a._.js} +2 -2
  103. package/.next/server/chunks/ssr/{node_modules_0-6sb1gkbjo93._.js → node_modules_152txg4c7ose3._.js} +2 -2
  104. package/.next/server/chunks/ssr/{node_modules_12qn4bepdou5v._.js → node_modules_185fuy4cv7loa._.js} +2 -2
  105. package/.next/server/chunks/ssr/{node_modules_0dq0dsblt-q0g._.js → node_modules_1aqaelh-8fme6._.js} +1 -1
  106. package/.next/server/chunks/ssr/{node_modules_1-iyhsn_1p9nx._.js → node_modules_1d4sreyq0ubqg._.js} +2 -2
  107. package/.next/server/chunks/ssr/{node_modules_0hqa9oxz17hip._.js → node_modules_1e_nc2eyg4djz._.js} +1 -1
  108. package/.next/server/chunks/ssr/{node_modules_1rlnehdn16ay-._.js → node_modules_1hd7j-tdb8drq._.js} +1 -1
  109. package/.next/server/chunks/ssr/{node_modules_12qw2ucebdvol._.js → node_modules_1i3x2csuq_-jt._.js} +1 -1
  110. package/.next/server/chunks/ssr/{node_modules_0zc49fdcopqu9._.js → node_modules_1l2g7btuh3e4s._.js} +2 -2
  111. package/.next/server/chunks/ssr/{node_modules_1-sz_-qddwilq._.js → node_modules_1l46or7mgko0z._.js} +1 -1
  112. package/.next/server/chunks/ssr/{node_modules_0fs8mckuwk2tj._.js → node_modules_1ltys5mwtcv-n._.js} +1 -1
  113. package/.next/server/chunks/ssr/{node_modules_0vn0kjn_84lmn._.js → node_modules_1nz3ckv6tu_66._.js} +1 -1
  114. package/.next/server/chunks/ssr/{node_modules_0t4h1rucl35hl._.js → node_modules_1pquu5wprusnc._.js} +2 -2
  115. package/.next/server/chunks/ssr/{node_modules_0-nvg0c4pgfb8._.js → node_modules_1qnypguag6s_l._.js} +1 -1
  116. package/.next/server/chunks/ssr/{node_modules_1v4lexrfhnlhs._.js → node_modules_1r6w-jlme6d10._.js} +1 -1
  117. package/.next/server/chunks/ssr/{node_modules_1f4geuvkvlxj1._.js → node_modules_1st9dwe66yx93._.js} +1 -1
  118. package/.next/server/chunks/ssr/{node_modules_0kovk4b6czb22._.js → node_modules_1tskcaktx6ods._.js} +1 -1
  119. package/.next/server/chunks/ssr/{node_modules_07maxxr-t28ql._.js → node_modules_1wew4nn7i1uup._.js} +1 -1
  120. package/.next/server/chunks/ssr/{node_modules_1216007ogd5om._.js → node_modules_1zbmc81s-4zsm._.js} +1 -1
  121. package/.next/server/chunks/ssr/{node_modules_1kv6lsckqs-m0._.js → node_modules_1zii7uk468cay._.js} +2 -2
  122. package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0bmuudv_6eypr._.js → node_modules_katex_dist_katex_mjs_0kqo9zl9cgwbo._.js} +1 -1
  123. package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0qyy6pq9uzpk0._.js → node_modules_katex_dist_katex_mjs_1604s1ky8db8u._.js} +1 -1
  124. package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_1d8fezw1qsiob._.js → node_modules_lucide-react_dist_esm_0-5bcc79665lq._.js} +2 -2
  125. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0-5bcc79665lq._.js.map +1 -0
  126. package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_0pezg1352q13j._.js → node_modules_lucide-react_dist_esm_0axoa1eg51x1-._.js} +2 -2
  127. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0axoa1eg51x1-._.js.map +1 -0
  128. package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_131i-tjzse3ye._.js → node_modules_lucide-react_dist_esm_18ei1-na3kusb._.js} +2 -2
  129. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_18ei1-na3kusb._.js.map +1 -0
  130. package/.next/server/chunks/ssr/{node_modules_lucide-react_dist_esm_1to-9cv1ysvs6._.js → node_modules_lucide-react_dist_esm_1tx493x2_auzs._.js} +2 -2
  131. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1tx493x2_auzs._.js.map +1 -0
  132. package/.next/server/chunks/ssr/node_modules_mermaid_dist_mermaid_core_mjs_06it7ktosm1dr._.js +3 -0
  133. package/.next/server/chunks/ssr/node_modules_mermaid_dist_mermaid_core_mjs_06it7ktosm1dr._.js.map +1 -0
  134. package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js +1 -1
  135. package/.next/server/chunks/ssr/src_app_page_1vqfk0-j72fp6.js.map +1 -1
  136. package/.next/server/chunks/ssr/src_components_reports_TokenReportView_jsx_1g3p_enbbsadt._.js +1 -1
  137. package/.next/server/chunks/ssr/src_components_reports_TokenReportView_jsx_1g3p_enbbsadt._.js.map +1 -1
  138. package/.next/server/middleware-build-manifest.js +3 -3
  139. package/.next/server/pages/404.html +1 -1
  140. package/.next/server/pages/500.html +1 -1
  141. package/.next/server/preview-props.json +3 -3
  142. package/.next/server/server-reference-manifest.js +1 -1
  143. package/.next/server/server-reference-manifest.json +1 -1
  144. package/.next/static/chunks/0r9apkv3exqv-.js +1 -0
  145. package/.next/static/chunks/17jorrh_pfel_.js +1 -0
  146. package/.next/static/chunks/1n_lb7wmn81jj.js +1 -0
  147. package/.next/static/chunks/2-w116ewoshm1.js +1 -0
  148. package/.next/static/chunks/23uup1e8841av.js +1 -0
  149. package/.next/static/chunks/25l0z48vlvdu4.css +1 -0
  150. package/.next/static/chunks/2rx7xvi55ohln.js +1 -0
  151. package/.next/static/chunks/3og0e9qcff393.js +425 -0
  152. package/.next/static/chunks/3rtpnpqd981z9.js +1 -0
  153. package/.next/trace +1 -1
  154. package/.next/trace-build +1 -1
  155. package/bin/cli.js +12 -0
  156. package/package.json +1 -1
  157. package/src/app/chat/page.js +14 -14
  158. package/src/app/globals.css +128 -0
  159. package/src/app/layout.js +6 -1
  160. package/src/app/page.js +1 -1
  161. package/src/components/chat/ChatMessageItem.js +12 -12
  162. package/src/components/chat/CodeBlock.js +5 -5
  163. package/src/components/chat/DiffViewer.js +27 -27
  164. package/src/components/chat/MarkdownRenderer.js +19 -19
  165. package/src/components/chat/SessionChatView.js +41 -41
  166. package/src/components/chat/SessionSearch.js +8 -8
  167. package/src/components/chat/ThinkingAccordion.js +3 -3
  168. package/src/components/chat/ToolCallCard.js +6 -6
  169. package/src/components/chat/ToolOutputView.js +19 -19
  170. package/src/components/factory/office-canvas.js +134 -3
  171. package/src/components/factory/scene/characters.js +267 -32
  172. package/src/components/layout/CommandPalette.jsx +12 -0
  173. package/src/components/layout/EditorTabs.jsx +17 -0
  174. package/src/components/layout/LayoutToggles.jsx +31 -2
  175. package/src/components/layout/LeftSidebar.jsx +27 -3
  176. package/src/components/layout/RightSidebar.jsx +8 -8
  177. package/src/components/layout/TitleBar.jsx +5 -1
  178. package/src/components/layout/VSCodeWorkbench.jsx +78 -14
  179. package/src/components/store/Item3DRenderer.jsx +602 -48
  180. package/src/components/store/LiveFittingRoom.jsx +55 -791
  181. package/src/components/store/LiveReactAgent.jsx +1637 -0
  182. package/src/components/store/SupporterStoreModal.jsx +3 -2
  183. package/src/components/store/SupporterStoreView.jsx +94 -34
  184. package/src/components/theme/ThemeSettingsModal.jsx +40 -40
  185. package/src/components/ui/Button.jsx +4 -4
  186. package/src/components/ui/Input.jsx +1 -1
  187. package/src/components/ui/Modal.jsx +6 -6
  188. package/src/components/ui/Select.jsx +3 -3
  189. package/src/lib/catalog/auras.js +226 -1199
  190. package/src/lib/catalog/index.js +60 -1
  191. package/src/lib/catalog/pets.js +291 -2398
  192. package/src/lib/catalog/props.js +488 -4199
  193. package/src/lib/catalog/skins.js +773 -3249
  194. package/src/lib/catalog/trophies.js +226 -1199
  195. package/src/lib/mockTraces.js +15 -15
  196. package/src/lib/supporterStore.js +1 -1
  197. package/src/lib/traceContract.js +1 -1
  198. package/src/lib/watchers/claudeWatcher.js +24 -19
  199. package/.next/server/chunks/ssr/[root-of-the-server]__19s2v5rryc14o._.js +0 -3
  200. package/.next/server/chunks/ssr/[root-of-the-server]__19s2v5rryc14o._.js.map +0 -1
  201. package/.next/server/chunks/ssr/[root-of-the-server]__1_jerxrctq6ev._.js +0 -427
  202. package/.next/server/chunks/ssr/[root-of-the-server]__1_jerxrctq6ev._.js.map +0 -1
  203. package/.next/server/chunks/ssr/[root-of-the-server]__1pvso-uyf--97._.js +0 -427
  204. package/.next/server/chunks/ssr/[root-of-the-server]__1pvso-uyf--97._.js.map +0 -1
  205. package/.next/server/chunks/ssr/[root-of-the-server]__1y78dc7oiz7ks._.js +0 -3
  206. package/.next/server/chunks/ssr/[root-of-the-server]__1y78dc7oiz7ks._.js.map +0 -1
  207. package/.next/server/chunks/ssr/_0ozao7omdwbvd._.js +0 -3
  208. package/.next/server/chunks/ssr/_0ozao7omdwbvd._.js.map +0 -1
  209. package/.next/server/chunks/ssr/_0rcmpdyxc1qwj._.js +0 -3
  210. package/.next/server/chunks/ssr/_0rcmpdyxc1qwj._.js.map +0 -1
  211. package/.next/server/chunks/ssr/_0wv0xnhun3mk7._.js +0 -3
  212. package/.next/server/chunks/ssr/_0wv0xnhun3mk7._.js.map +0 -1
  213. package/.next/server/chunks/ssr/_17rmaft1zusua._.js +0 -3
  214. package/.next/server/chunks/ssr/_17rmaft1zusua._.js.map +0 -1
  215. package/.next/server/chunks/ssr/_1e-d4pcj59a7a._.js +0 -3
  216. package/.next/server/chunks/ssr/_1e-d4pcj59a7a._.js.map +0 -1
  217. package/.next/server/chunks/ssr/_1qr5gnh64z8pg._.js +0 -3
  218. package/.next/server/chunks/ssr/_1qr5gnh64z8pg._.js.map +0 -1
  219. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_0pezg1352q13j._.js.map +0 -1
  220. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_131i-tjzse3ye._.js.map +0 -1
  221. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1d8fezw1qsiob._.js.map +0 -1
  222. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_1to-9cv1ysvs6._.js.map +0 -1
  223. package/.next/static/chunks/0_3s_e4gd9xl0.js +0 -1
  224. package/.next/static/chunks/0i4kx4yl-dwfg.js +0 -425
  225. package/.next/static/chunks/0z0jbobmmvqoc.js +0 -1
  226. package/.next/static/chunks/1_a_gmob5qzho.js +0 -1
  227. package/.next/static/chunks/1ifqr4qo4697b.js +0 -1
  228. package/.next/static/chunks/2ccq9i8ev4dsx.js +0 -1
  229. package/.next/static/chunks/2mif7onk_9jy-.css +0 -1
  230. package/.next/static/chunks/40wyf-mv0tiu3.js +0 -1
  231. /package/.next/server/chunks/ssr/{node_modules_1c8i3jrmo4393._.js.map → node_modules_00ebs67b4u61w._.js.map} +0 -0
  232. /package/.next/server/chunks/ssr/{node_modules_02vtgweceovke._.js.map → node_modules_01p9ctt-n2dxp._.js.map} +0 -0
  233. /package/.next/server/chunks/ssr/{node_modules_1kr1c-ncf8q9t._.js.map → node_modules_05i69rc9pwcdx._.js.map} +0 -0
  234. /package/.next/server/chunks/ssr/{node_modules_02jwra-d9iqim._.js.map → node_modules_06mgkab1v5iox._.js.map} +0 -0
  235. /package/.next/server/chunks/ssr/{node_modules_1dff7b_kvngr-._.js.map → node_modules_07bjxeq9dfgn1._.js.map} +0 -0
  236. /package/.next/server/chunks/ssr/{node_modules_0m3ihe65818y_._.js.map → node_modules_08q6a-f2itxyo._.js.map} +0 -0
  237. /package/.next/server/chunks/ssr/{node_modules_0-6sb1gkbjo93._.js.map → node_modules_09v49jhajmvl4._.js.map} +0 -0
  238. /package/.next/server/chunks/ssr/{node_modules_0oukyh0iq21ow._.js.map → node_modules_0b8zi3pbl-y9n._.js.map} +0 -0
  239. /package/.next/server/chunks/ssr/{node_modules_061uaylfjwqk7._.js.map → node_modules_0d2ios01ot1in._.js.map} +0 -0
  240. /package/.next/server/chunks/ssr/{node_modules_02nv3yff2pqh8._.js.map → node_modules_0dw0vozejrnml._.js.map} +0 -0
  241. /package/.next/server/chunks/ssr/{node_modules_0-nvg0c4pgfb8._.js.map → node_modules_0e3njj436xau-._.js.map} +0 -0
  242. /package/.next/server/chunks/ssr/{node_modules_0fs8mckuwk2tj._.js.map → node_modules_0e6qoh__e4a69._.js.map} +0 -0
  243. /package/.next/server/chunks/ssr/{node_modules_0t4h1rucl35hl._.js.map → node_modules_0hb0q0epwvp--._.js.map} +0 -0
  244. /package/.next/server/chunks/ssr/{node_modules_0f773uqgzj7y7._.js.map → node_modules_0jla9ugf1y6rb._.js.map} +0 -0
  245. /package/.next/server/chunks/ssr/{node_modules_0dq0dsblt-q0g._.js.map → node_modules_0l-y0kqtu_r3o._.js.map} +0 -0
  246. /package/.next/server/chunks/ssr/{node_modules_0zc49fdcopqu9._.js.map → node_modules_0l814qpw677vm._.js.map} +0 -0
  247. /package/.next/server/chunks/ssr/{node_modules_1wlwrgnt65zus._.js.map → node_modules_0lqovp8j8ld76._.js.map} +0 -0
  248. /package/.next/server/chunks/ssr/{node_modules_0z3elum1675ve._.js.map → node_modules_0o63z1gd17rhb._.js.map} +0 -0
  249. /package/.next/server/chunks/ssr/{node_modules_1xyxigbqzb8vs._.js.map → node_modules_0sjdrli5douui._.js.map} +0 -0
  250. /package/.next/server/chunks/ssr/{node_modules_1-iyhsn_1p9nx._.js.map → node_modules_0xh8tnq1niblb._.js.map} +0 -0
  251. /package/.next/server/chunks/ssr/{node_modules_0nde84kzuwv2n._.js.map → node_modules_0yayrqhzfk8wy._.js.map} +0 -0
  252. /package/.next/server/chunks/ssr/{node_modules_0__m9_odts7_e._.js.map → node_modules_0z1e37smavebg._.js.map} +0 -0
  253. /package/.next/server/chunks/ssr/{node_modules_0f4xh33v3iltc._.js.map → node_modules_0zb0i39mnjdf3._.js.map} +0 -0
  254. /package/.next/server/chunks/ssr/{node_modules_0b8ndnuql44z1._.js.map → node_modules_10g1mmrf63d8a._.js.map} +0 -0
  255. /package/.next/server/chunks/ssr/{node_modules_1-sz_-qddwilq._.js.map → node_modules_152txg4c7ose3._.js.map} +0 -0
  256. /package/.next/server/chunks/ssr/{node_modules_12qn4bepdou5v._.js.map → node_modules_185fuy4cv7loa._.js.map} +0 -0
  257. /package/.next/server/chunks/ssr/{node_modules_0fd1swhk15cx3._.js.map → node_modules_1aqaelh-8fme6._.js.map} +0 -0
  258. /package/.next/server/chunks/ssr/{node_modules_13nsmuhey_ti_._.js.map → node_modules_1d4sreyq0ubqg._.js.map} +0 -0
  259. /package/.next/server/chunks/ssr/{node_modules_0hqa9oxz17hip._.js.map → node_modules_1e_nc2eyg4djz._.js.map} +0 -0
  260. /package/.next/server/chunks/ssr/{node_modules_1rlnehdn16ay-._.js.map → node_modules_1hd7j-tdb8drq._.js.map} +0 -0
  261. /package/.next/server/chunks/ssr/{node_modules_07maxxr-t28ql._.js.map → node_modules_1i3x2csuq_-jt._.js.map} +0 -0
  262. /package/.next/server/chunks/ssr/{node_modules_1iovyom0-y7o_._.js.map → node_modules_1l2g7btuh3e4s._.js.map} +0 -0
  263. /package/.next/server/chunks/ssr/{node_modules_1ll-58c1c-qab._.js.map → node_modules_1l46or7mgko0z._.js.map} +0 -0
  264. /package/.next/server/chunks/ssr/{node_modules_0z7rdbaf13024._.js.map → node_modules_1ltys5mwtcv-n._.js.map} +0 -0
  265. /package/.next/server/chunks/ssr/{node_modules_0vn0kjn_84lmn._.js.map → node_modules_1nz3ckv6tu_66._.js.map} +0 -0
  266. /package/.next/server/chunks/ssr/{node_modules_1zs2nou5uogby._.js.map → node_modules_1pquu5wprusnc._.js.map} +0 -0
  267. /package/.next/server/chunks/ssr/{node_modules_05w7qhtrzvnk6._.js.map → node_modules_1qnypguag6s_l._.js.map} +0 -0
  268. /package/.next/server/chunks/ssr/{node_modules_1v4lexrfhnlhs._.js.map → node_modules_1r6w-jlme6d10._.js.map} +0 -0
  269. /package/.next/server/chunks/ssr/{node_modules_1f4geuvkvlxj1._.js.map → node_modules_1st9dwe66yx93._.js.map} +0 -0
  270. /package/.next/server/chunks/ssr/{node_modules_0kovk4b6czb22._.js.map → node_modules_1tskcaktx6ods._.js.map} +0 -0
  271. /package/.next/server/chunks/ssr/{node_modules_12qw2ucebdvol._.js.map → node_modules_1wew4nn7i1uup._.js.map} +0 -0
  272. /package/.next/server/chunks/ssr/{node_modules_1216007ogd5om._.js.map → node_modules_1zbmc81s-4zsm._.js.map} +0 -0
  273. /package/.next/server/chunks/ssr/{node_modules_1kv6lsckqs-m0._.js.map → node_modules_1zii7uk468cay._.js.map} +0 -0
  274. /package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0bmuudv_6eypr._.js.map → node_modules_katex_dist_katex_mjs_0kqo9zl9cgwbo._.js.map} +0 -0
  275. /package/.next/server/chunks/ssr/{node_modules_katex_dist_katex_mjs_0qyy6pq9uzpk0._.js.map → node_modules_katex_dist_katex_mjs_1604s1ky8db8u._.js.map} +0 -0
  276. /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → 1y6Da0YgnPr2_6ncpWrbV}/_buildManifest.js +0 -0
  277. /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → 1y6Da0YgnPr2_6ncpWrbV}/_clientMiddlewareManifest.js +0 -0
  278. /package/.next/static/{sQnXeiP8rV6y2v0az_xw3 → 1y6Da0YgnPr2_6ncpWrbV}/_ssgManifest.js +0 -0
@@ -0,0 +1,1637 @@
1
+ "use client";
2
+
3
+ import React, { useRef, useEffect, useMemo } from "react";
4
+ import { getItemById, COSMETIC_CATALOG } from "@/lib/catalog/index.js";
5
+
6
+ // Floor theme color palettes
7
+ const THEME_STYLES = {
8
+ theme_default: { name: "Classic Charcoal Slate", base: "#14161a", tile: "#1e222b", grid: "#2d3548", glow: "#38bdf8" },
9
+ theme_cyberpunk: { name: "Cyberpunk Neon Night", base: "#0d0819", tile: "#1c0d33", grid: "#ff2a85", glow: "#00f0ff" },
10
+ theme_matrix: { name: "Phosphor Matrix Terminal", base: "#020d05", tile: "#051f0b", grid: "#00ff66", glow: "#10b981" },
11
+ theme_wood: { name: "Cozy Scandinavian Loft", base: "#1f1610", tile: "#2c2017", grid: "#451a03", glow: "#f59e0b" },
12
+ theme_space: { name: "Deep Space Void", base: "#030712", tile: "#0b1329", grid: "#1e1b4b", glow: "#6366f1" },
13
+ theme_blueprint: { name: "Blueprint CAD Grid", base: "#0b1a30", tile: "#1e3a8a", grid: "#1d4ed8", glow: "#38bdf8" },
14
+ theme_synthwave: { name: "Retro Synthwave 80s", base: "#1a052e", tile: "#3b0764", grid: "#d946ef", glow: "#ec4899" },
15
+ theme_sakura_cyber: { name: "Sakura Cyber Garden", base: "#1c0e18", tile: "#2e1022", grid: "#f43f5e", glow: "#fb7185" },
16
+ theme_nordic_ice: { name: "Minimalist Nordic Ice", base: "#0f172a", tile: "#1e293b", grid: "#38bdf8", glow: "#e2e8f0" },
17
+ theme_industrial: { name: "High-Voltage Industrial", base: "#18181b", tile: "#27272a", grid: "#eab308", glow: "#f59e0b" },
18
+ };
19
+
20
+ /**
21
+ * 50 Curated High-Fidelity Silhouette & Accessory Variations
22
+ */
23
+ function RenderSkinAccessories({ variant, archetype, color, secondaryColor, accentColor }) {
24
+ // 1. CYBER SUIT VARIANTS (10)
25
+ if (variant === "tactical_visor") {
26
+ return (
27
+ <g>
28
+ <polygon points="-26,-66 -34,-76 -26,-72" fill={color} />
29
+ <polygon points="26,-66 34,-76 26,-72" fill={color} />
30
+ <rect x="-24" y="-66" width="48" height="6" rx="2" fill={color} />
31
+ <circle cx="0" cy="-63" r="2.5" fill={accentColor} />
32
+ </g>
33
+ );
34
+ }
35
+ if (variant === "laser_scout") {
36
+ return (
37
+ <g>
38
+ <circle cx="8" cy="-57" r="7" fill="none" stroke={color} strokeWidth="1.8" />
39
+ <line x1="8" y1="-66" x2="8" y2="-48" stroke={color} strokeWidth="1" strokeDasharray="1 2" />
40
+ <line x1="-1" y1="-57" x2="17" y2="-57" stroke={color} strokeWidth="1" strokeDasharray="1 2" />
41
+ <circle cx="8" cy="-57" r="2" fill="#ff0000" />
42
+ </g>
43
+ );
44
+ }
45
+ if (variant === "riot_shield") {
46
+ return (
47
+ <g>
48
+ <rect x="-25" y="-68" width="50" height="9" rx="3" fill="#1e2430" stroke={color} strokeWidth="1.8" />
49
+ <rect x="-20" y="-34" width="40" height="6" rx="2" fill={color} />
50
+ <circle cx="-16" cy="-64" r="2.5" fill={accentColor} />
51
+ <circle cx="16" cy="-64" r="2.5" fill={accentColor} />
52
+ </g>
53
+ );
54
+ }
55
+ if (variant === "cyber_horns") {
56
+ return (
57
+ <g>
58
+ <polygon points="-20,-70 -30,-88 -14,-76" fill={color} stroke={secondaryColor} strokeWidth="1" />
59
+ <polygon points="20,-70 30,-88 14,-76" fill={color} stroke={secondaryColor} strokeWidth="1" />
60
+ <line x1="-17" y1="-73" x2="-25" y2="-82" stroke={accentColor} strokeWidth="1.5" />
61
+ <line x1="17" y1="-73" x2="25" y2="-82" stroke={accentColor} strokeWidth="1.5" />
62
+ </g>
63
+ );
64
+ }
65
+ if (variant === "crown_radiator") {
66
+ return (
67
+ <g fill={color}>
68
+ <polygon points="-16,-72 -14,-86 -8,-74" />
69
+ <polygon points="-4,-74 0,-92 4,-74" />
70
+ <polygon points="8,-74 14,-86 16,-72" />
71
+ <circle cx="0" cy="-70" r="3" fill={accentColor} />
72
+ </g>
73
+ );
74
+ }
75
+ if (variant === "gas_respirator") {
76
+ return (
77
+ <g>
78
+ <circle cx="-14" cy="-44" r="6" fill="#1e2430" stroke={color} strokeWidth="1.5" />
79
+ <circle cx="14" cy="-44" r="6" fill="#1e2430" stroke={color} strokeWidth="1.5" />
80
+ <circle cx="-14" cy="-44" r="3" fill={color} />
81
+ <circle cx="14" cy="-44" r="3" fill={color} />
82
+ <rect x="-8" y="-46" width="16" height="5" fill="#111827" stroke={color} strokeWidth="1" />
83
+ </g>
84
+ );
85
+ }
86
+ if (variant === "prism_goggles") {
87
+ return (
88
+ <g>
89
+ <polygon points="-16,-62 -8,-66 -2,-62 -2,-52 -8,-48 -16,-52" fill="#0c4a6e" stroke={color} strokeWidth="1.6" />
90
+ <polygon points="2,-62 8,-66 16,-62 16,-52 8,-48 2,-52" fill="#0c4a6e" stroke={color} strokeWidth="1.6" />
91
+ <circle cx="-9" cy="-57" r="2.5" fill={accentColor} />
92
+ <circle cx="9" cy="-57" r="2.5" fill={accentColor} />
93
+ </g>
94
+ );
95
+ }
96
+ if (variant === "samurai_crest") {
97
+ return (
98
+ <g>
99
+ <path d="M -22 -72 Q 0 -92 22 -72 Q 0 -84 -22 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
100
+ <circle cx="0" cy="-78" r="3" fill={accentColor} />
101
+ </g>
102
+ );
103
+ }
104
+ if (variant === "overdrive_vents") {
105
+ return (
106
+ <g strokeLinecap="round">
107
+ <line x1="-18" y1="-72" x2="-28" y2="-90" stroke={color} strokeWidth="3" />
108
+ <line x1="18" y1="-72" x2="28" y2="-90" stroke={color} strokeWidth="3" />
109
+ <line x1="-12" y1="-70" x2="-20" y2="-84" stroke={accentColor} strokeWidth="2" />
110
+ <line x1="12" y1="-70" x2="20" y2="-84" stroke={accentColor} strokeWidth="2" />
111
+ </g>
112
+ );
113
+ }
114
+ if (variant === "holo_shroud") {
115
+ return (
116
+ <g>
117
+ <ellipse cx="0" cy="-66" rx="28" ry="12" fill="none" stroke={color} strokeWidth="1.8" strokeDasharray="4 2" />
118
+ <circle cx="0" cy="-78" r="4" fill={accentColor} />
119
+ </g>
120
+ );
121
+ }
122
+
123
+ // 2. MECHA PILOT VARIANTS (10)
124
+ if (variant === "v_fin") {
125
+ return (
126
+ <g>
127
+ <polygon points="-24,-88 -18,-92 0,-76 18,-92 24,-88 0,-72" fill={color} stroke={secondaryColor} strokeWidth="1" />
128
+ <polygon points="-4,-72 0,-78 4,-72 0,-68" fill="#ef4444" />
129
+ </g>
130
+ );
131
+ }
132
+ if (variant === "blast_shield") {
133
+ return (
134
+ <g>
135
+ <rect x="-24" y="-68" width="48" height="14" rx="3" fill="#0f172a" stroke={color} strokeWidth="2" />
136
+ <circle cx="-18" cy="-80" r="3.5" fill="#fde047" stroke={color} strokeWidth="1" />
137
+ <circle cx="18" cy="-80" r="3.5" fill="#fde047" stroke={color} strokeWidth="1" />
138
+ </g>
139
+ );
140
+ }
141
+ if (variant === "eva_horn") {
142
+ return (
143
+ <g>
144
+ <polygon points="-3,-74 0,-98 3,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
145
+ <rect x="-28" y="-48" width="5" height="18" rx="2" fill={color} stroke={secondaryColor} strokeWidth="1" />
146
+ <rect x="23" y="-48" width="5" height="18" rx="2" fill={color} stroke={secondaryColor} strokeWidth="1" />
147
+ </g>
148
+ );
149
+ }
150
+ if (variant === "cage_grille") {
151
+ return (
152
+ <g>
153
+ <rect x="-16" y="-52" width="32" height="14" rx="2" fill="#18181b" stroke={color} strokeWidth="1.6" />
154
+ <line x1="-10" y1="-52" x2="-10" y2="-38" stroke={color} strokeWidth="1.2" />
155
+ <line x1="-4" y1="-52" x2="-4" y2="-38" stroke={color} strokeWidth="1.2" />
156
+ <line x1="4" y1="-52" x2="4" y2="-38" stroke={color} strokeWidth="1.2" />
157
+ <line x1="10" y1="-52" x2="10" y2="-38" stroke={color} strokeWidth="1.2" />
158
+ <rect x="-22" y="-86" width="4" height="16" fill="#27272a" stroke={color} strokeWidth="1" />
159
+ <rect x="18" y="-86" width="4" height="16" fill="#27272a" stroke={color} strokeWidth="1" />
160
+ </g>
161
+ );
162
+ }
163
+ if (variant === "missile_pod") {
164
+ return (
165
+ <g>
166
+ <rect x="-30" y="-42" width="8" height="12" rx="2" fill="#1c1917" stroke={color} strokeWidth="1.5" />
167
+ <circle cx="-26" cy="-38" r="1.5" fill="#ef4444" />
168
+ <circle cx="-26" cy="-34" r="1.5" fill="#ef4444" />
169
+ <rect x="22" y="-42" width="8" height="12" rx="2" fill="#1c1917" stroke={color} strokeWidth="1.5" />
170
+ <circle cx="26" cy="-38" r="1.5" fill="#ef4444" />
171
+ <circle cx="26" cy="-34" r="1.5" fill="#ef4444" />
172
+ </g>
173
+ );
174
+ }
175
+ if (variant === "quad_array") {
176
+ return (
177
+ <g stroke={color} strokeWidth="1.8">
178
+ <line x1="-22" y1="-72" x2="-26" y2="-90" />
179
+ <line x1="-12" y1="-76" x2="-14" y2="-94" />
180
+ <line x1="12" y1="-76" x2="14" y2="-94" />
181
+ <line x1="22" y1="-72" x2="26" y2="-90" />
182
+ <circle cx="-26" cy="-90" r="2" fill={accentColor} stroke="none" />
183
+ <circle cx="-14" cy="-94" r="2" fill={accentColor} stroke="none" />
184
+ <circle cx="14" cy="-94" r="2" fill={accentColor} stroke="none" />
185
+ <circle cx="26" cy="-90" r="2" fill={accentColor} stroke="none" />
186
+ </g>
187
+ );
188
+ }
189
+ if (variant === "halo_shield") {
190
+ return (
191
+ <g>
192
+ <polygon points="-32,-42 -26,-46 -20,-42 -20,-34 -26,-30 -32,-34" fill="#064e3b" stroke={color} strokeWidth="1.5" />
193
+ <polygon points="20,-42 26,-46 32,-42 32,-34 26,-30 20,-34" fill="#064e3b" stroke={color} strokeWidth="1.5" />
194
+ </g>
195
+ );
196
+ }
197
+ if (variant === "ram_horns") {
198
+ return (
199
+ <g>
200
+ <path d="M -18 -72 C -34 -82, -32 -96, -18 -92 C -24 -88, -24 -78, -14 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
201
+ <path d="M 18 -72 C 34 -82, 32 -96, 18 -92 C 24 -88, 24 -78, 14 -72 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
202
+ </g>
203
+ );
204
+ }
205
+ if (variant === "radar_dish") {
206
+ return (
207
+ <g>
208
+ <ellipse cx="-24" cy="-84" rx="7" ry="12" fill="#18181b" stroke={color} strokeWidth="1.5" transform="rotate(-25 -24 -84)" />
209
+ <circle cx="-24" cy="-84" r="2" fill={accentColor} />
210
+ </g>
211
+ );
212
+ }
213
+ if (variant === "hyper_wings") {
214
+ return (
215
+ <g>
216
+ <polygon points="-26,-46 -44,-64 -34,-40" fill={color} stroke={secondaryColor} strokeWidth="1.2" />
217
+ <polygon points="26,-46 44,-64 34,-40" fill={color} stroke={secondaryColor} strokeWidth="1.2" />
218
+ </g>
219
+ );
220
+ }
221
+
222
+ // 3. STEALTH NINJA VARIANTS (10)
223
+ if (variant === "flowing_headband") {
224
+ return (
225
+ <g>
226
+ <rect x="-24" y="-66" width="48" height="8" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.5" />
227
+ <circle cx="0" cy="-62" r="3" fill="#38bdf8" />
228
+ <path d="M 24 -62 Q 38 -56 46 -46 Q 36 -48 24 -56" fill={color} />
229
+ </g>
230
+ );
231
+ }
232
+ if (variant === "tactical_cowl") {
233
+ return (
234
+ <g>
235
+ <path d="M -24 -68 Q 0 -76 24 -68 L 22 -44 Q 0 -38 -22 -44 Z" fill="#0f172a" stroke={color} strokeWidth="1.4" opacity="0.8" />
236
+ <circle cx="6" cy="-57" r="4.5" fill="none" stroke="#22c55e" strokeWidth="1.8" />
237
+ <circle cx="6" cy="-57" r="1.5" fill="#22c55e" />
238
+ </g>
239
+ );
240
+ }
241
+ if (variant === "oni_mask") {
242
+ return (
243
+ <g>
244
+ <polygon points="-16,-72 -24,-88 -12,-76" fill="#ef4444" stroke="#450a0a" strokeWidth="1" />
245
+ <polygon points="16,-72 24,-88 12,-76" fill="#ef4444" stroke="#450a0a" strokeWidth="1" />
246
+ <path d="M -16 -46 L -10 -40 L -6 -46 L 0 -42 L 6 -46 L 10 -40 L 16 -46 L 12 -36 L -12 -36 Z" fill="#ffffff" stroke={color} strokeWidth="1" />
247
+ </g>
248
+ );
249
+ }
250
+ if (variant === "kitsune_ears") {
251
+ return (
252
+ <g>
253
+ <polygon points="-22,-72 -14,-88 -6,-76" fill="#1e2430" />
254
+ <polygon points="-20,-73 -14,-85 -8,-76" fill={color} />
255
+ <polygon points="6,-76 14,-88 22,-72" fill="#1e2430" />
256
+ <polygon points="8,-76 14,-85 20,-73" fill={color} />
257
+ <line x1="-12" y1="-46" x2="-22" y2="-48" stroke={color} strokeWidth="1.2" />
258
+ <line x1="12" y1="-46" x2="22" y2="-48" stroke={color} strokeWidth="1.2" />
259
+ </g>
260
+ );
261
+ }
262
+ if (variant === "conical_kasa") {
263
+ return (
264
+ <g>
265
+ <polygon points="-36,-72 0,-92 36,-72" fill="#18181b" stroke={color} strokeWidth="1.6" />
266
+ <line x1="-36" y1="-72" x2="36" y2="-72" stroke={accentColor} strokeWidth="2.4" />
267
+ </g>
268
+ );
269
+ }
270
+ if (variant === "twin_katanas") {
271
+ return (
272
+ <g strokeLinecap="round">
273
+ <line x1="-24" y1="-32" x2="28" y2="-88" stroke="#475569" strokeWidth="3" />
274
+ <line x1="-22" y1="-34" x2="26" y2="-86" stroke={color} strokeWidth="1.6" />
275
+ <line x1="24" y1="-32" x2="-28" y2="-88" stroke="#475569" strokeWidth="3" />
276
+ <line x1="22" y1="-34" x2="-26" y2="-86" stroke={color} strokeWidth="1.6" />
277
+ </g>
278
+ );
279
+ }
280
+ if (variant === "tengu_beak") {
281
+ return (
282
+ <g>
283
+ <polygon points="-12,-48 0,-34 12,-48 0,-44" fill="#0f172a" stroke={color} strokeWidth="1.5" />
284
+ </g>
285
+ );
286
+ }
287
+ if (variant === "veil_shroud") {
288
+ return (
289
+ <g>
290
+ <path d="M -22 -62 Q 0 -70 22 -62 L 20 -36 Q 0 -30 -20 -36 Z" fill="#0f172a" opacity="0.85" stroke={color} strokeWidth="1.2" strokeDasharray="3 2" />
291
+ </g>
292
+ );
293
+ }
294
+ if (variant === "scythe_crest") {
295
+ return (
296
+ <g>
297
+ <path d="M 0 -88 C -14 -88, -20 -76, -14 -66 C -20 -72, -14 -84, 0 -84 C 14 -84, 20 -72, 14 -66 C 20 -76, 14 -88, 0 -88 Z" fill={color} stroke={secondaryColor} strokeWidth="1" />
298
+ </g>
299
+ );
300
+ }
301
+ if (variant === "void_mask") {
302
+ return (
303
+ <g>
304
+ <rect x="-18" y="-62" width="36" height="20" rx="4" fill="#000000" stroke={color} strokeWidth="1.8" />
305
+ <text x="0" y="-48" fill={color} fontSize="10" fontFamily="monospace" textAnchor="middle" fontWeight="bold">零</text>
306
+ </g>
307
+ );
308
+ }
309
+
310
+ // 4. MATRIX HACKER VARIANTS (10)
311
+ if (variant === "hoodie_cowl") {
312
+ return (
313
+ <g>
314
+ <path d="M -28 -74 Q 0 -92 28 -74 Q 28 -34 20 -32 Q 0 -28 -20 -32 Q -28 -34 -28 -74 Z" fill="#051f0b" stroke={color} strokeWidth="1.8" opacity="0.9" />
315
+ <text x="-12" y="-72" fill={color} fontSize="6" fontFamily="monospace" opacity="0.7">101</text>
316
+ <text x="4" y="-72" fill={color} fontSize="6" fontFamily="monospace" opacity="0.7">010</text>
317
+ </g>
318
+ );
319
+ }
320
+ if (variant === "vr_goggles") {
321
+ return (
322
+ <g>
323
+ <rect x="-22" y="-64" width="44" height="15" rx="3" fill="#083344" stroke={color} strokeWidth="1.8" />
324
+ <line x1="-12" y1="-64" x2="-16" y2="-82" stroke={color} strokeWidth="1.6" />
325
+ <circle cx="-16" cy="-82" r="2.5" fill={accentColor} />
326
+ <line x1="-14" y1="-56" x2="14" y2="-56" stroke={accentColor} strokeWidth="1.4" />
327
+ </g>
328
+ );
329
+ }
330
+ if (variant === "daemon_horns") {
331
+ return (
332
+ <g>
333
+ <path d="M -24 -70 Q 0 -82 24 -70" stroke={color} strokeWidth="3" fill="none" />
334
+ <polygon points="-16,-70 -22,-86 -10,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
335
+ <polygon points="16,-70 22,-86 10,-74" fill={color} stroke={secondaryColor} strokeWidth="1" />
336
+ </g>
337
+ );
338
+ }
339
+ if (variant === "glitch_halo") {
340
+ return (
341
+ <g>
342
+ <rect x="-28" y="-76" width="56" height="42" fill="none" stroke={color} strokeWidth="1.5" strokeDasharray="6 3 2 4" />
343
+ <rect x="-18" y="-82" width="12" height="6" fill={color} opacity="0.7" />
344
+ <rect x="12" y="-50" width="10" height="4" fill={color} opacity="0.7" />
345
+ </g>
346
+ );
347
+ }
348
+ if (variant === "floating_hud") {
349
+ return (
350
+ <g>
351
+ <rect x="24" y="-78" width="34" height="18" rx="2" fill="#09090b" stroke={color} strokeWidth="1" />
352
+ <text x="27" y="-66" fill={color} fontSize="6" fontFamily="monospace">root#_</text>
353
+ </g>
354
+ );
355
+ }
356
+ if (variant === "respirator_eq") {
357
+ return (
358
+ <g strokeWidth="2">
359
+ <rect x="-18" y="-46" width="36" height="10" rx="3" fill="#0f172a" stroke={color} strokeWidth="1.2" />
360
+ <line x1="-12" y1="-40" x2="-12" y2="-45" stroke="#22c55e" />
361
+ <line x1="-6" y1="-38" x2="-6" y2="-45" stroke="#eab308" />
362
+ <line x1="0" y1="-37" x2="0" y2="-45" stroke="#ef4444" />
363
+ <line x1="6" y1="-39" x2="6" y2="-45" stroke="#eab308" />
364
+ <line x1="12" y1="-41" x2="12" y2="-45" stroke="#22c55e" />
365
+ </g>
366
+ );
367
+ }
368
+ if (variant === "heatsink_fins") {
369
+ return (
370
+ <g fill="#ea580c" stroke="#fed7aa" strokeWidth="1">
371
+ <rect x="-18" y="-84" width="4" height="14" rx="1" />
372
+ <rect x="-10" y="-88" width="4" height="18" rx="1" />
373
+ <rect x="-2" y="-90" width="4" height="20" rx="1" />
374
+ <rect x="6" y="-88" width="4" height="18" rx="1" />
375
+ <rect x="14" y="-84" width="4" height="14" rx="1" />
376
+ </g>
377
+ );
378
+ }
379
+ if (variant === "cable_dreads") {
380
+ return (
381
+ <g fill="none" strokeLinecap="round">
382
+ <path d="M -22 -62 C -32 -48, -30 -24, -28 -12" stroke={color} strokeWidth="2.5" />
383
+ <path d="M -16 -64 C -22 -44, -20 -20, -18 -8" stroke={accentColor} strokeWidth="2" />
384
+ <path d="M 16 -64 C 22 -44, 20 -20, 18 -8" stroke={accentColor} strokeWidth="2" />
385
+ <path d="M 22 -62 C 32 -48, 30 -24, 28 -12" stroke={color} strokeWidth="2.5" />
386
+ </g>
387
+ );
388
+ }
389
+ if (variant === "cyber_skull") {
390
+ return (
391
+ <g>
392
+ <ellipse cx="-7" cy="-55" rx="5" ry="4" fill="#000000" stroke={color} strokeWidth="1.5" />
393
+ <ellipse cx="7" cy="-55" rx="5" ry="4" fill="#000000" stroke={color} strokeWidth="1.5" />
394
+ <polygon points="-2,-46 0,-43 2,-46" fill={color} />
395
+ <line x1="-8" y1="-40" x2="8" y2="-40" stroke={color} strokeWidth="1.8" />
396
+ <line x1="-6" y1="-43" x2="-6" y2="-37" stroke={color} strokeWidth="1.4" />
397
+ <line x1="0" y1="-43" x2="0" y2="-37" stroke={color} strokeWidth="1.4" />
398
+ <line x1="6" y1="-43" x2="6" y2="-37" stroke={color} strokeWidth="1.4" />
399
+ </g>
400
+ );
401
+ }
402
+ if (variant === "wireframe_cube") {
403
+ return (
404
+ <g stroke={color}>
405
+ <rect x="-24" y="-76" width="48" height="42" rx="4" fill="none" strokeWidth="1.6" />
406
+ <rect x="-16" y="-68" width="32" height="26" rx="2" fill="none" stroke={accentColor} strokeWidth="1.2" strokeDasharray="3 2" />
407
+ <line x1="-24" y1="-76" x2="-16" y2="-68" strokeWidth="1.2" />
408
+ <line x1="24" y1="-76" x2="16" y2="-68" strokeWidth="1.2" />
409
+ <line x1="-24" y1="-34" x2="-16" y2="-42" strokeWidth="1.2" />
410
+ <line x1="24" y1="-34" x2="16" y2="-42" strokeWidth="1.2" />
411
+ </g>
412
+ );
413
+ }
414
+
415
+ // 5. CELESTIAL ASTRO VARIANTS (10)
416
+ if (variant === "bubble_dome") {
417
+ return (
418
+ <g>
419
+ <circle cx="0" cy="-56" r="28" fill="none" stroke={color} strokeWidth="2.5" opacity="0.9" />
420
+ <circle cx="0" cy="-84" r="3.5" fill="#fef08a" stroke={color} strokeWidth="1.2" />
421
+ <path d="M -14 -72 Q 0 -80 14 -72" stroke="#ffffff" strokeWidth="2" fill="none" opacity="0.6" strokeLinecap="round" />
422
+ </g>
423
+ );
424
+ }
425
+ if (variant === "lunar_pack") {
426
+ return (
427
+ <g>
428
+ <rect x="-20" y="-86" width="2" height="18" fill={color} />
429
+ <circle cx="-19" cy="-86" r="2" fill="#ffffff" />
430
+ <ellipse cx="0" cy="-54" rx="24" ry="18" fill="none" stroke="#e2e8f0" strokeWidth="2" />
431
+ </g>
432
+ );
433
+ }
434
+ if (variant === "sunburst_halo") {
435
+ return (
436
+ <g stroke={color} strokeWidth="1.8" opacity="0.85">
437
+ <line x1="0" y1="-86" x2="0" y2="-98" />
438
+ <line x1="22" y1="-78" x2="32" y2="-88" />
439
+ <line x1="30" y1="-56" x2="42" y2="-56" />
440
+ <line x1="22" y1="-34" x2="32" y2="-24" />
441
+ <line x1="0" y1="-26" x2="0" y2="-14" />
442
+ <line x1="-22" y1="-34" x2="-32" y2="-24" />
443
+ <line x1="-30" y1="-56" x2="-42" y2="-56" />
444
+ <line x1="-22" y1="-78" x2="-32" y2="-88" />
445
+ </g>
446
+ );
447
+ }
448
+ if (variant === "saturn_ring") {
449
+ return (
450
+ <g>
451
+ <ellipse cx="0" cy="-56" rx="36" ry="10" fill="none" stroke={color} strokeWidth="2.2" transform="rotate(-15 0 -56)" />
452
+ <circle cx="28" cy="-62" r="3" fill={accentColor} />
453
+ </g>
454
+ );
455
+ }
456
+ if (variant === "star_crown") {
457
+ return (
458
+ <g fill={color}>
459
+ <polygon points="-16,-74 -12,-86 -8,-76" />
460
+ <polygon points="-6,-76 0,-92 6,-76" />
461
+ <polygon points="8,-76 12,-86 16,-74" />
462
+ <circle cx="0" cy="-74" r="2.5" fill="#ffffff" />
463
+ </g>
464
+ );
465
+ }
466
+ if (variant === "eclipse_corona") {
467
+ return (
468
+ <g>
469
+ <ellipse cx="0" cy="-56" rx="32" ry="18" fill="none" stroke={color} strokeWidth="3" opacity="0.6" strokeDasharray="8 4" />
470
+ <circle cx="0" cy="-56" r="22" fill="#000000" stroke={color} strokeWidth="1.5" />
471
+ </g>
472
+ );
473
+ }
474
+ if (variant === "pulsar_spires") {
475
+ return (
476
+ <g stroke={color} strokeWidth="2.8" strokeLinecap="round">
477
+ <line x1="0" y1="-78" x2="0" y2="-98" />
478
+ <circle cx="0" cy="-98" r="3" fill="#ffffff" stroke="none" />
479
+ <line x1="0" y1="-34" x2="0" y2="-18" />
480
+ <circle cx="0" cy="-18" r="3" fill="#ffffff" stroke="none" />
481
+ </g>
482
+ );
483
+ }
484
+ if (variant === "aurora_ribbons") {
485
+ return (
486
+ <g fill="none" strokeLinecap="round">
487
+ <path d="M -30 -82 Q -15 -96 0 -84 T 30 -88" stroke={color} strokeWidth="3" opacity="0.75" />
488
+ <path d="M -26 -88 Q -10 -100 6 -88 T 26 -92" stroke={accentColor} strokeWidth="2" opacity="0.6" />
489
+ </g>
490
+ );
491
+ }
492
+ if (variant === "angel_wings") {
493
+ return (
494
+ <g>
495
+ <polygon points="-26,-46 -48,-78 -32,-38" fill={color} stroke={secondaryColor} strokeWidth="1.2" opacity="0.85" />
496
+ <polygon points="26,-46 48,-78 32,-38" fill={color} stroke={secondaryColor} strokeWidth="1.2" opacity="0.85" />
497
+ <ellipse cx="0" cy="-80" rx="16" ry="5" fill="none" stroke={accentColor} strokeWidth="1.6" />
498
+ </g>
499
+ );
500
+ }
501
+ if (variant === "singularity_core") {
502
+ return (
503
+ <g>
504
+ <ellipse cx="0" cy="-56" rx="30" ry="26" fill="none" stroke="#ffffff" strokeWidth="2" opacity="0.9" />
505
+ <circle cx="-22" cy="-70" r="2.5" fill={accentColor} />
506
+ <circle cx="22" cy="-42" r="2.5" fill={accentColor} />
507
+ </g>
508
+ );
509
+ }
510
+
511
+ // Archetype Fallbacks
512
+ if (archetype === "stealth_ninja") {
513
+ return (
514
+ <g>
515
+ <rect x="-24" y="-66" width="48" height="8" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.5" />
516
+ <circle cx="0" cy="-62" r="3" fill="#38bdf8" />
517
+ </g>
518
+ );
519
+ }
520
+ if (archetype === "mecha_pilot") {
521
+ return (
522
+ <g fill={color}>
523
+ <rect x="-20" y="-88" width="3" height="20" rx="1" />
524
+ <rect x="17" y="-88" width="3" height="20" rx="1" />
525
+ <circle cx="-18.5" cy="-88" r="3" fill="#ffffff" />
526
+ <circle cx="18.5" cy="-88" r="3" fill="#ffffff" />
527
+ </g>
528
+ );
529
+ }
530
+ if (archetype === "celestial_astro") {
531
+ return (
532
+ <ellipse cx="0" cy="-64" rx="30" ry="8" fill="none" stroke={color} strokeWidth="2" opacity="0.9" />
533
+ );
534
+ }
535
+ if (archetype === "matrix_hacker") {
536
+ return (
537
+ <rect x="-26" y="-76" width="52" height="44" rx="12" fill="none" stroke={color} strokeWidth="1.8" />
538
+ );
539
+ }
540
+ // Default Cyber Suit
541
+ return (
542
+ <rect x="-24" y="-66" width="48" height="6" rx="2" fill={color} />
543
+ );
544
+ }
545
+
546
+ /**
547
+ * 5 Distinct Staff Uniform & Torso Silhouettes for Employee Roles:
548
+ * - cyber_suit: Corporate Tech Field Ops / Executive blazer with security ID badge lanyard & lapels
549
+ * - mecha_pilot: Heavy Industrial DevOps / Hardware engineer with hazard chevrons, shoulder pauldrons & harness
550
+ * - stealth_ninja: Security Auditor Shinobi with crossed gi collar, diagonal tactical sash, kunai strap & obi
551
+ * - matrix_hacker: Streetwear Netrunner with oversized slouchy techwear cowl-hoodie, drawstrings & kangaroo pocket
552
+ * - celestial_astro: Aerospace Scientist flight uniform with gold command epaulets, hermetic neck seal & pressure dials
553
+ */
554
+ export function RenderStaffTorso({ archetype, color, secondaryColor, accentColor, idPrefix, trimColor }) {
555
+ if (archetype === "cyber_suit") {
556
+ return (
557
+ <g id="staff-torso-cyber-suit">
558
+ {/* Tailored Corporate Blazer / Suit Jacket */}
559
+ <polygon points="-18,-30 18,-30 15,-6 -15,-6" fill={`url(#${idPrefix}_bodyGradient)`} stroke={color} strokeWidth="1.2" />
560
+ {/* Crisp Dark Lapels */}
561
+ <polygon points="-17,-30 -7,-14 -13,-14" fill="#0d1117" stroke={color} strokeWidth="0.8" />
562
+ <polygon points="17,-30 7,-14 13,-14" fill="#0d1117" stroke={color} strokeWidth="0.8" />
563
+ {/* Center Zipper / Placket */}
564
+ <line x1="0" y1="-30" x2="0" y2="-10" stroke={color} strokeWidth="1.4" />
565
+ {/* Dual Chest Pocket Slits */}
566
+ <rect x="-14" y="-22" width="5" height="3" rx="1" fill="#1f2937" stroke={color} strokeWidth="0.6" />
567
+ <rect x="9" y="-22" width="5" height="3" rx="1" fill="#1f2937" stroke={color} strokeWidth="0.6" />
568
+ {/* Executive Security ID Lanyard & Hanging Badge */}
569
+ <path d="M -5 -30 Q 0 -18 5 -30" stroke={accentColor} strokeWidth="1.2" fill="none" opacity="0.85" />
570
+ <rect x="-4.5" y="-19" width="9" height="12" rx="1.5" fill="#090d16" stroke={color} strokeWidth="1" />
571
+ <rect x="-3" y="-17.5" width="6" height="4.5" rx="0.5" fill={color} />
572
+ <line x1="-3" y1="-11" x2="3" y2="-11" stroke="#ffffff" strokeWidth="0.8" />
573
+ <line x1="-3" y1="-9" x2="1" y2="-9" stroke="#ffffff" strokeWidth="0.8" />
574
+ {/* Polished Belt & Buckle */}
575
+ <rect x="-15" y="-10" width="30" height="4" fill="#020617" />
576
+ <rect x="-3.5" y="-11" width="7" height="6" rx="1" fill="#1e293b" stroke={color} strokeWidth="1" />
577
+ </g>
578
+ );
579
+ }
580
+
581
+ if (archetype === "mecha_pilot") {
582
+ return (
583
+ <g id="staff-torso-mecha-pilot">
584
+ {/* Broad Reinforced Heavy Armored Chest Rig */}
585
+ <polygon points="-22,-30 22,-30 18,-6 -18,-6" fill="#18181b" stroke={color} strokeWidth="1.6" />
586
+ {/* Armored Shoulder Pauldrons */}
587
+ <polygon points="-27,-29 -20,-33 -17,-25 -25,-20" fill="#27272a" stroke={color} strokeWidth="1.2" />
588
+ <polygon points="27,-29 20,-33 17,-25 25,-20" fill="#27272a" stroke={color} strokeWidth="1.2" />
589
+ {/* Heavy Industrial Hazard Chevrons (Yellow/Black) */}
590
+ <polygon points="-12,-26 -7,-26 -3,-20 -8,-20" fill="#eab308" />
591
+ <polygon points="-5,-26 0,-26 4,-20 -1,-20" fill="#18181b" />
592
+ <polygon points="2,-26 7,-26 11,-20 6,-20" fill="#eab308" />
593
+ <polygon points="9,-26 13,-26 17,-20 13,-20" fill="#18181b" />
594
+ {/* Heavy Duty Tactical Harness Straps with Carabiners */}
595
+ <line x1="-13" y1="-30" x2="-11" y2="-6" stroke={color} strokeWidth="1.8" />
596
+ <line x1="13" y1="-30" x2="11" y2="-6" stroke={color} strokeWidth="1.8" />
597
+ <circle cx="-12" cy="-10" r="1.8" fill="none" stroke="#e2e8f0" strokeWidth="1" />
598
+ <circle cx="12" cy="-10" r="1.8" fill="none" stroke="#e2e8f0" strokeWidth="1" />
599
+ {/* Central Reinforced Fusion Reactor with Protective Cage */}
600
+ <circle cx="0" cy="-14" r="5.5" fill="#09090b" stroke={color} strokeWidth="1.5" />
601
+ <circle cx="0" cy="-14" r="3.2" fill={color} />
602
+ <line x1="-5" y1="-14" x2="5" y2="-14" stroke="#ffffff" strokeWidth="1" />
603
+ <line x1="0" y1="-19" x2="0" y2="-9" stroke="#ffffff" strokeWidth="1" />
604
+ {/* Tool Carabiner Pouch */}
605
+ <rect x="-16" y="-9" width="7" height="4" rx="1" fill="#3f3f46" stroke="#71717a" strokeWidth="0.8" />
606
+ <rect x="9" y="-9" width="7" height="4" rx="1" fill="#3f3f46" stroke="#71717a" strokeWidth="0.8" />
607
+ </g>
608
+ );
609
+ }
610
+
611
+ if (archetype === "stealth_ninja") {
612
+ return (
613
+ <g id="staff-torso-stealth-ninja">
614
+ {/* Sleek Form-Fitting Shinobi Gi / Wrapped Tunic */}
615
+ <polygon points="-16,-30 16,-30 13,-6 -13,-6" fill="#090d16" stroke={color} strokeWidth="1.4" />
616
+ {/* Crossed Kimono / Gi Lapels */}
617
+ <line x1="-16" y1="-30" x2="5" y2="-14" stroke={color} strokeWidth="2.2" strokeLinecap="round" />
618
+ <line x1="16" y1="-30" x2="-3" y2="-14" stroke={color} strokeWidth="1.6" strokeLinecap="round" opacity="0.6" />
619
+ {/* Prominent Diagonal Tactical Sash (Torso cross-strap) */}
620
+ <polygon points="-16,-28 -11,-30 14,-9 9,-7" fill={color} opacity="0.9" />
621
+ {/* Attached Stealth Kunai / Scroll Sheath */}
622
+ <rect x="-3" y="-21" width="11" height="4" rx="1.5" fill="#1e293b" stroke="#ffffff" strokeWidth="0.8" transform="rotate(-35 2 -19)" />
623
+ {/* Tied Fabric Obi Waist Sash with Hanging Knot Tails */}
624
+ <rect x="-14" y="-12" width="28" height="6" rx="2" fill="#1e1b4b" stroke={color} strokeWidth="1.2" />
625
+ <path d="M 3 -7 Q 6 1 4 6 Q 1 1 3 -7" fill={color} />
626
+ <path d="M 5 -7 Q 9 0 8 5 Q 4 0 5 -7" fill={accentColor} opacity="0.85" />
627
+ {/* Forearm Binding Accents */}
628
+ <line x1="-24" y1="-22" x2="-18" y2="-20" stroke={color} strokeWidth="1.2" />
629
+ <line x1="24" y1="-22" x2="18" y2="-20" stroke={color} strokeWidth="1.2" />
630
+ </g>
631
+ );
632
+ }
633
+
634
+ if (archetype === "matrix_hacker") {
635
+ return (
636
+ <g id="staff-torso-matrix-hacker">
637
+ {/* Loose Oversized Slouchy Techwear Hoodie Body */}
638
+ <rect x="-21" y="-30" width="42" height="25" rx="8" fill="#121217" stroke={color} strokeWidth="1.6" />
639
+ {/* Crumpled Fabric Cowl Collar draped around neck */}
640
+ <path d="M -18 -32 Q 0 -26 18 -32 Q 13 -22 0 -22 Q -13 -22 -18 -32 Z" fill="#1f1f28" stroke={color} strokeWidth="1.2" />
641
+ {/* Hanging Dual Drawstring Cords with Metal Aglets */}
642
+ <path d="M -7 -23 Q -9 -14 -6 -7" stroke="#ffffff" strokeWidth="1.4" fill="none" strokeLinecap="round" />
643
+ <rect x="-7.5" y="-7" width="3" height="4" rx="0.8" fill={color} />
644
+ <path d="M 7 -23 Q 9 -13 6 -6" stroke="#ffffff" strokeWidth="1.4" fill="none" strokeLinecap="round" />
645
+ <rect x="4.5" y="-6" width="3" height="4" rx="0.8" fill={color} />
646
+ {/* Front Kangaroo Pouch Pocket */}
647
+ <path d="M -15 -14 L 15 -14 L 13 -6 L -13 -6 Z" fill="#09090d" stroke="#27272a" strokeWidth="1" />
648
+ <line x1="-14" y1="-14" x2="-11" y2="-8" stroke={color} strokeWidth="1.2" />
649
+ <line x1="14" y1="-14" x2="11" y2="-8" stroke={color} strokeWidth="1.2" />
650
+ {/* Cyber Holographic Glitch Patch on Chest */}
651
+ <g transform="translate(6, -21)">
652
+ <rect x="0" y="0" width="9" height="5" fill="#000000" stroke={accentColor} strokeWidth="0.8" />
653
+ <line x1="2" y1="1" x2="2" y2="4" stroke={color} strokeWidth="0.8" />
654
+ <line x1="4" y1="1" x2="4" y2="4" stroke={color} strokeWidth="1.2" />
655
+ <line x1="6.5" y1="1" x2="6.5" y2="4" stroke={color} strokeWidth="0.8" />
656
+ </g>
657
+ </g>
658
+ );
659
+ }
660
+
661
+ if (archetype === "celestial_astro") {
662
+ return (
663
+ <g id="staff-torso-celestial-astro">
664
+ {/* Pressurized Flight Suit Body */}
665
+ <polygon points="-18,-30 18,-30 16,-6 -16,-6" fill="#f1f5f9" stroke={color} strokeWidth="1.4" />
666
+ {/* Hermetic Helmet Seal Ring */}
667
+ <rect x="-14" y="-33" width="28" height="5" rx="2" fill="#334155" stroke={color} strokeWidth="1.2" />
668
+ {/* Gold Command Rank Epaulets on Shoulders */}
669
+ <rect x="-24" y="-31" width="8" height="4.5" rx="1" fill="#f59e0b" stroke="#78350f" strokeWidth="0.8" />
670
+ <line x1="-22" y1="-30" x2="-22" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
671
+ <line x1="-19" y1="-30" x2="-19" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
672
+ <rect x="16" y="-31" width="8" height="4.5" rx="1" fill="#f59e0b" stroke="#78350f" strokeWidth="0.8" />
673
+ <line x1="19" y1="-30" x2="19" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
674
+ <line x1="22" y1="-30" x2="22" y2="-28" stroke="#ffffff" strokeWidth="0.8" />
675
+ {/* Dual Atmospheric Pressure Regulator Dials with Connecting Glowing Tubing */}
676
+ <circle cx="-7" cy="-17" r="3.5" fill="#0f172a" stroke={color} strokeWidth="1.2" />
677
+ <circle cx="-7" cy="-17" r="1.5" fill="#22c55e" />
678
+ <circle cx="7" cy="-17" r="3.5" fill="#0f172a" stroke={color} strokeWidth="1.2" />
679
+ <circle cx="7" cy="-17" r="1.5" fill="#38bdf8" />
680
+ <path d="M -3.5 -17 Q 0 -13 3.5 -17" fill="none" stroke={color} strokeWidth="1.6" />
681
+ {/* Planetary Mission Patch Insignia on Left Chest */}
682
+ <polygon points="-12,-26 -6,-26 -9,-21" fill={color} stroke="#ffffff" strokeWidth="0.8" />
683
+ <ellipse cx="-9" cy="-24" rx="4" ry="1.5" fill="none" stroke="#f59e0b" strokeWidth="0.8" transform="rotate(-20 -9 -24)" />
684
+ {/* Aerodynamic Thermal Seams */}
685
+ <line x1="-12" y1="-14" x2="-10" y2="-6" stroke="#94a3b8" strokeWidth="1" />
686
+ <line x1="12" y1="-14" x2="10" y2="-6" stroke="#94a3b8" strokeWidth="1" />
687
+ </g>
688
+ );
689
+ }
690
+
691
+ // Fallback default
692
+ return (
693
+ <g>
694
+ <rect x="-17" y="-30" width="34" height="22" rx="11" fill={`url(#${idPrefix}_bodyGradient)`} />
695
+ <rect x="-14" y="-12" width="28" height="6" fill={trimColor} />
696
+ <circle cx="0" cy="-18" r="4.5" fill="#0f172a" stroke={color} strokeWidth="1.4" />
697
+ <circle cx="0" cy="-18" r="2.2" fill={color} />
698
+ </g>
699
+ );
700
+ }
701
+
702
+ export function RenderStaffArms({ archetype, color, armLRef, armRRef }) {
703
+ let sleeveL = null;
704
+ let sleeveR = null;
705
+
706
+ if (archetype === "mecha_pilot") {
707
+ sleeveL = (
708
+ <>
709
+ <rect x="-27" y="-26" width="9" height="24" rx="3" fill="#27272a" stroke={color} strokeWidth="1" />
710
+ <rect x="-28" y="-16" width="11" height="8" rx="2" fill="#3f3f46" stroke="#eab308" strokeWidth="1" />
711
+ </>
712
+ );
713
+ sleeveR = (
714
+ <>
715
+ <rect x="18" y="-26" width="9" height="24" rx="3" fill="#27272a" stroke={color} strokeWidth="1" />
716
+ <rect x="17" y="-16" width="11" height="8" rx="2" fill="#3f3f46" stroke="#eab308" strokeWidth="1" />
717
+ </>
718
+ );
719
+ } else if (archetype === "stealth_ninja") {
720
+ sleeveL = (
721
+ <>
722
+ <rect x="-26" y="-26" width="8" height="24" rx="4" fill="#0f172a" />
723
+ <line x1="-26" y1="-18" x2="-18" y2="-16" stroke={color} strokeWidth="1.2" />
724
+ <line x1="-26" y1="-12" x2="-18" y2="-10" stroke={color} strokeWidth="1.2" />
725
+ </>
726
+ );
727
+ sleeveR = (
728
+ <>
729
+ <rect x="18" y="-26" width="8" height="24" rx="4" fill="#0f172a" />
730
+ <line x1="18" y1="-18" x2="26" y2="-16" stroke={color} strokeWidth="1.2" />
731
+ <line x1="18" y1="-12" x2="26" y2="-10" stroke={color} strokeWidth="1.2" />
732
+ </>
733
+ );
734
+ } else if (archetype === "matrix_hacker") {
735
+ sleeveL = (
736
+ <>
737
+ <rect x="-28" y="-26" width="11" height="24" rx="5" fill="#18181b" stroke={color} strokeWidth="1" />
738
+ <rect x="-27" y="-5" width="9" height="3" rx="1" fill="#27272a" />
739
+ </>
740
+ );
741
+ sleeveR = (
742
+ <>
743
+ <rect x="17" y="-26" width="11" height="24" rx="5" fill="#18181b" stroke={color} strokeWidth="1" />
744
+ <rect x="18" y="-5" width="9" height="3" rx="1" fill="#27272a" />
745
+ </>
746
+ );
747
+ } else if (archetype === "celestial_astro") {
748
+ sleeveL = (
749
+ <>
750
+ <rect x="-26" y="-26" width="8" height="24" rx="4" fill="#f1f5f9" stroke="#94a3b8" strokeWidth="0.8" />
751
+ <polygon points="-26,-15 -18,-15 -22,-11" fill={color} />
752
+ </>
753
+ );
754
+ sleeveR = (
755
+ <>
756
+ <rect x="18" y="-26" width="8" height="24" rx="4" fill="#f1f5f9" stroke="#94a3b8" strokeWidth="0.8" />
757
+ <polygon points="18,-15 26,-15 22,-11" fill={color} />
758
+ </>
759
+ );
760
+ } else {
761
+ // Default cyber suit tailored sleeve
762
+ sleeveL = (
763
+ <>
764
+ <rect x="-26" y="-26" width="8" height="24" rx="4" fill="#1e2430" stroke={color} strokeWidth="0.8" />
765
+ <line x1="-25" y1="-6" x2="-19" y2="-6" stroke={color} strokeWidth="1" />
766
+ </>
767
+ );
768
+ sleeveR = (
769
+ <>
770
+ <rect x="18" y="-26" width="8" height="24" rx="4" fill="#1e2430" stroke={color} strokeWidth="0.8" />
771
+ <line x1="19" y1="-6" x2="25" y2="-6" stroke={color} strokeWidth="1" />
772
+ </>
773
+ );
774
+ }
775
+
776
+ return (
777
+ <>
778
+ <g ref={armLRef}>{sleeveL}</g>
779
+ <g ref={armRRef}>{sleeveR}</g>
780
+ </>
781
+ );
782
+ }
783
+
784
+ /**
785
+ * Pure Declarative React SVG Animated Character & Workstation Engine.
786
+ * Supports:
787
+ * - 6 Actions: streaming, happy, sleeping, error, looping, pending
788
+ * - Live mixing of 810 catalog items (Skins, Props, Pets, Auras, Themes)
789
+ * - Pure SVG rendering (zero canvas dependency) with 60 FPS hardware-accelerated transforms
790
+ * - Zero raw emojis, 100% vector scalability
791
+ */
792
+ export function LiveReactAgent({
793
+ mode = "streaming",
794
+ intensity = 0.75,
795
+ skinId = "skin_0",
796
+ skinItem: propSkinItem = null,
797
+ petId = "pet_0",
798
+ petItem: propPetItem = null,
799
+ propsList = [],
800
+ auraId = "aura_0",
801
+ auraItem: propAuraItem = null,
802
+ themeId = "theme_default",
803
+ themeItem: propThemeItem = null,
804
+ clientType = "cli",
805
+ interactive = true,
806
+ isPlaying = true,
807
+ showDesk = true,
808
+ showFloor = true,
809
+ className = "",
810
+ style = {},
811
+ onTelemetry = null,
812
+ }) {
813
+ const rawId = React.useId();
814
+ const idPrefix = useMemo(() => "lra_" + rawId.replace(/[^a-zA-Z0-9]/g, "_"), [rawId]);
815
+ // Resolve item objects from catalog or props
816
+ const skin = useMemo(() => {
817
+ return propSkinItem || getItemById(skinId) || (COSMETIC_CATALOG.skins || [])[0];
818
+ }, [propSkinItem, skinId]);
819
+
820
+ const pet = useMemo(() => {
821
+ return propPetItem || getItemById(petId) || (COSMETIC_CATALOG.pets || [])[0];
822
+ }, [propPetItem, petId]);
823
+
824
+ const aura = useMemo(() => {
825
+ return propAuraItem || getItemById(auraId) || (COSMETIC_CATALOG.auras || [])[0];
826
+ }, [propAuraItem, auraId]);
827
+
828
+ const theme = useMemo(() => {
829
+ return propThemeItem || getItemById(themeId) || (COSMETIC_CATALOG.officeThemes || [])[0];
830
+ }, [propThemeItem, themeId]);
831
+
832
+ const themeStyle = THEME_STYLES[theme?.id] || THEME_STYLES.theme_default;
833
+ const skinColor = skin?.color || "#00f0ff";
834
+ const skinSecColor = skin?.secondaryColor || "#111827";
835
+ const skinAccColor = skin?.accentColor || "#ffffff";
836
+ const skinVariant = skin?.variant || "tactical_visor";
837
+ const skinArch = skin?.archetype || "cyber_suit";
838
+ const petColor = pet?.color || "#00f0ff";
839
+ const petArch = pet?.archetype || "none";
840
+ const auraColor = aura?.color || "#00f0ff";
841
+ const auraArch = aura?.archetype || "none";
842
+ const trimColor = clientType === "app" ? "#8b5cf6" : "#10b981";
843
+
844
+ // SVG Animation Refs for zero-rerender 60 FPS animation
845
+ const rootGRef = useRef(null);
846
+ const bodyGRef = useRef(null);
847
+ const armLRef = useRef(null);
848
+ const armRRef = useRef(null);
849
+ const eyeLRef = useRef(null);
850
+ const eyeRRef = useRef(null);
851
+ const mouthRef = useRef(null);
852
+ const auraRef = useRef(null);
853
+ const petGRef = useRef(null);
854
+ const holoCubeRef = useRef(null);
855
+ const steamRef = useRef(null);
856
+ const serverLedsRef = useRef([]);
857
+ const oscWaveRef = useRef(null);
858
+ const fxGroupRef = useRef(null);
859
+ const auraParticlesRef = useRef(null);
860
+ const monitorScanlineRef = useRef(null);
861
+
862
+ // Animation Loop Effect
863
+ useEffect(() => {
864
+ if (!interactive) return;
865
+
866
+ let animId;
867
+ let lastTime = performance.now();
868
+ let frameCount = 0;
869
+ let fpsTimer = 0;
870
+
871
+ const tick = (now) => {
872
+ const dt = now - lastTime;
873
+ lastTime = now;
874
+ const t = isPlaying ? now : 0;
875
+
876
+ frameCount++;
877
+ fpsTimer += dt;
878
+
879
+ // 1. Body Bob, Shake & Tilt
880
+ let bob = Math.sin(t * 0.004) * (0.8 + intensity * 1.4);
881
+ let shake = 0;
882
+ let tilt = 0;
883
+
884
+ if (mode === "happy") bob = -Math.abs(Math.sin(t * 0.005)) * 4.2;
885
+ if (mode === "sleeping") {
886
+ bob = Math.sin(t * 0.0016) * 1.1 + 2.2;
887
+ tilt = (0.12 + Math.sin(t * 0.0016) * 0.02) * (180 / Math.PI);
888
+ }
889
+ if (mode === "error") shake = Math.sin(t * 0.09) * 2.2;
890
+ if (mode === "looping") {
891
+ shake = Math.sin(t * 0.08) * 2.5;
892
+ bob = Math.sin(t * 0.015) * 1.8;
893
+ tilt = Math.sin(t * 0.02) * 10;
894
+ }
895
+
896
+ if (bodyGRef.current) {
897
+ bodyGRef.current.setAttribute("transform", `translate(${shake.toFixed(2)}, ${bob.toFixed(2)}) rotate(${tilt.toFixed(2)})`);
898
+ }
899
+
900
+ // 2. Arms (Shoulder Pivot at (-22, -26) and (22, -26))
901
+ const phase = t * 0.012;
902
+ let rotL = 0;
903
+ let rotR = 0;
904
+
905
+ if (mode === "streaming") {
906
+ rotL = Math.sin(phase) * 0.14 * (0.3 + intensity) * (180 / Math.PI);
907
+ rotR = -Math.sin(phase + 1.3) * 0.14 * (0.3 + intensity) * (180 / Math.PI);
908
+ } else if (mode === "pending") {
909
+ rotL = (2.5 + Math.sin(t * 0.012) * 0.35) * (180 / Math.PI);
910
+ rotR = -Math.sin(phase + 1.3) * 0.06 * (180 / Math.PI);
911
+ } else if (mode === "happy") {
912
+ rotL = (2.2 + Math.sin(t * 0.01) * 0.2) * (180 / Math.PI);
913
+ rotR = (-2.2 - Math.sin(t * 0.01 + 1) * 0.2) * (180 / Math.PI);
914
+ } else if (mode === "error") {
915
+ rotL = (2.7 + Math.sin(t * 0.08) * 0.1) * (180 / Math.PI);
916
+ rotR = (-2.7 - Math.sin(t * 0.08) * 0.1) * (180 / Math.PI);
917
+ } else if (mode === "looping") {
918
+ rotL = (2.4 + Math.sin(t * 0.02) * 0.4) * (180 / Math.PI);
919
+ rotR = (-2.4 - Math.sin(t * 0.02 + 1) * 0.4) * (180 / Math.PI);
920
+ }
921
+
922
+ if (armLRef.current) armLRef.current.setAttribute("transform", `rotate(${rotL.toFixed(2)}, -22, -26)`);
923
+ if (armRRef.current) armRRef.current.setAttribute("transform", `rotate(${rotR.toFixed(2)}, 22, -26)`);
924
+
925
+ // 3. Eyes (Blink & CRT Flicker)
926
+ const blinking = Math.sin(t * 0.0013) > 0.985;
927
+ const flicker = (0.85 + Math.sin(t * 0.01) * 0.15).toFixed(2);
928
+
929
+ if (eyeLRef.current) {
930
+ eyeLRef.current.setAttribute("opacity", flicker);
931
+ if (mode === "streaming") {
932
+ eyeLRef.current.setAttribute("ry", blinking ? "0.8" : "4.4");
933
+ }
934
+ }
935
+ if (eyeRRef.current) {
936
+ eyeRRef.current.setAttribute("opacity", flicker);
937
+ if (mode === "streaming") {
938
+ eyeRRef.current.setAttribute("ry", blinking ? "0.8" : "4.4");
939
+ }
940
+ }
941
+
942
+ // Telemetry callback
943
+ if (fpsTimer >= 400 && onTelemetry) {
944
+ onTelemetry({
945
+ fps: Math.round((frameCount * 1000) / fpsTimer),
946
+ bob,
947
+ shake,
948
+ rotL,
949
+ rotR,
950
+ blink: blinking,
951
+ });
952
+ frameCount = 0;
953
+ fpsTimer = 0;
954
+ }
955
+
956
+ // 4. Aura & Ambient VFX Animation
957
+ if (auraRef.current && auraArch !== "none") {
958
+ const pulse = 1 + Math.sin(t * 0.006) * 0.12;
959
+ auraRef.current.setAttribute("transform", `scale(${pulse.toFixed(3)})`);
960
+
961
+ if (auraParticlesRef.current) {
962
+ if (auraArch === "matrix_rain") {
963
+ let mHtml = "";
964
+ const cols = [-40, -28, -16, -4, 8, 20, 32, 44];
965
+ const glyphs = ["0", "1", "λ", "§", "#", "*", ">", "Ψ", "Δ", "01"];
966
+ cols.forEach((colX, cIdx) => {
967
+ const speed = 0.05 + (cIdx % 3) * 0.02;
968
+ const dropY = -45 + ((t * speed + cIdx * 18) % 75);
969
+ mHtml += `<line x1="${colX}" y1="-45" x2="${colX}" y2="${dropY.toFixed(1)}" stroke="${auraColor}" stroke-width="1.2" stroke-dasharray="2 3" opacity="0.35" />`;
970
+ const glyph = glyphs[(Math.floor(t * 0.003 + cIdx * 3)) % glyphs.length];
971
+ mHtml += `<text x="${colX - 3}" y="${dropY.toFixed(1)}" fill="${auraColor}" font-size="7" font-family="monospace" font-weight="bold" opacity="0.9">${glyph}</text>`;
972
+ mHtml += `<circle cx="${colX}" cy="${(dropY + 2).toFixed(1)}" r="1.6" fill="#ffffff" />`;
973
+ });
974
+ auraParticlesRef.current.innerHTML = mHtml;
975
+ } else if (auraArch === "quantum_mist") {
976
+ let qHtml = "";
977
+ const rAng = (t * 0.02) % 360;
978
+ qHtml += `<ellipse cx="0" cy="0" rx="46" ry="18" fill="none" stroke="${auraColor}" stroke-width="1.4" opacity="0.5" transform="rotate(${rAng.toFixed(1)})" />`;
979
+ qHtml += `<ellipse cx="0" cy="0" rx="40" ry="15" fill="none" stroke="#ffffff" stroke-width="1" opacity="0.4" transform="rotate(${(-rAng * 0.7).toFixed(1)})" />`;
980
+ for (let i = 0; i < 6; i++) {
981
+ const orbAng = t * 0.0025 + (i * Math.PI * 2) / 6;
982
+ const ox = Math.cos(orbAng) * 44;
983
+ const oy = Math.sin(orbAng) * 18;
984
+ const zScale = 0.7 + Math.sin(orbAng) * 0.3;
985
+ const alpha = (0.4 + Math.sin(orbAng) * 0.5).toFixed(2);
986
+ qHtml += `<circle cx="${ox.toFixed(1)}" cy="${oy.toFixed(1)}" r="${(2.5 * zScale).toFixed(1)}" fill="${auraColor}" opacity="${alpha}" />`;
987
+ qHtml += `<circle cx="${ox.toFixed(1)}" cy="${oy.toFixed(1)}" r="${(1.2 * zScale).toFixed(1)}" fill="#ffffff" opacity="${alpha}" />`;
988
+ }
989
+ auraParticlesRef.current.innerHTML = qHtml;
990
+ } else if (auraArch === "glitch_halo") {
991
+ let gHtml = "";
992
+ const isGlitch = Math.sin(t * 0.04) > 0.65;
993
+ const jitterX = isGlitch ? Math.sin(t * 0.3) * 6 : 0;
994
+ const jitterY = isGlitch ? Math.cos(t * 0.4) * 3 : 0;
995
+ gHtml += `<rect x="${(-38 + jitterX).toFixed(1)}" y="${(-26 + jitterY).toFixed(1)}" width="76" height="34" rx="4" fill="none" stroke="#00f0ff" stroke-width="1.8" opacity="0.75" />`;
996
+ gHtml += `<rect x="${(-38 - jitterX * 0.8).toFixed(1)}" y="${(-26 - jitterY * 0.8).toFixed(1)}" width="76" height="34" rx="4" fill="none" stroke="#ff007f" stroke-width="1.8" opacity="0.75" />`;
997
+ gHtml += `<rect x="-38" y="-26" width="76" height="34" rx="4" fill="none" stroke="${auraColor}" stroke-width="2.2" opacity="0.9" />`;
998
+ for (let sl = -20; sl <= 20; sl += 10) {
999
+ const sOff = isGlitch ? Math.sin(t * 0.2 + sl) * 8 : 0;
1000
+ gHtml += `<line x1="${(-38 + sOff).toFixed(1)}" y1="${sl}" x2="${(38 + sOff).toFixed(1)}" y2="${sl}" stroke="#ffffff" stroke-width="0.8" opacity="0.5" />`;
1001
+ }
1002
+ auraParticlesRef.current.innerHTML = gHtml;
1003
+ } else {
1004
+ // Plasma Ring & Other Auras
1005
+ let pHtml = "";
1006
+ const rot1 = (t * 0.03) % 360;
1007
+ const rot2 = (-t * 0.045) % 360;
1008
+ pHtml += `<ellipse cx="0" cy="0" rx="46" ry="18" fill="none" stroke="${auraColor}" stroke-width="2.5" opacity="0.8" transform="rotate(${rot1.toFixed(1)})" />`;
1009
+ pHtml += `<ellipse cx="0" cy="0" rx="42" ry="14" fill="none" stroke="#ffffff" stroke-width="1.2" opacity="0.6" transform="rotate(${rot2.toFixed(1)})" />`;
1010
+ for (let i = 0; i < 8; i++) {
1011
+ const fAng = (t * 0.002 + (i * Math.PI * 2) / 8);
1012
+ const fx = Math.cos(fAng) * 44;
1013
+ const fy = Math.sin(fAng) * 16;
1014
+ pHtml += `<circle cx="${fx.toFixed(1)}" cy="${fy.toFixed(1)}" r="2" fill="${auraColor}" opacity="0.8" />`;
1015
+ }
1016
+ auraParticlesRef.current.innerHTML = pHtml;
1017
+ }
1018
+ }
1019
+ }
1020
+
1021
+ // 5. Props & Desk Animation
1022
+ if (holoCubeRef.current) {
1023
+ const ang = (t * 0.1) % 360;
1024
+ holoCubeRef.current.setAttribute("transform", `translate(65, -15) rotate(${ang.toFixed(1)})`);
1025
+ }
1026
+
1027
+ if (serverLedsRef.current.length > 0) {
1028
+ const ledCols = ["#22c55e", "#00f0ff", "#f59e0b", "#ec4899"];
1029
+ serverLedsRef.current.forEach((led, idx) => {
1030
+ if (!led) return;
1031
+ const on = Math.sin(t * 0.008 + idx * 1.6) > 0;
1032
+ led.setAttribute("fill", on ? ledCols[idx] : "#0f172a");
1033
+ });
1034
+ }
1035
+
1036
+ if (oscWaveRef.current) {
1037
+ let d = "M 57 21";
1038
+ for (let ox = 57; ox <= 85; ox += 3) {
1039
+ const oy = 21 + Math.sin(t * 0.01 + ox * 0.8) * 4;
1040
+ d += ` L ${ox} ${oy.toFixed(1)}`;
1041
+ }
1042
+ oscWaveRef.current.setAttribute("d", d);
1043
+ }
1044
+
1045
+ if (steamRef.current) {
1046
+ let sHtml = "";
1047
+ for (let i = 0; i < 3; i++) {
1048
+ const p = ((t * 0.0008 + i / 3) % 1);
1049
+ const sy = 8 - p * 22;
1050
+ const sx = -73 + Math.sin(p * 5 + i * 2) * 4;
1051
+ const alpha = (0.55 * (1 - p)).toFixed(2);
1052
+ const r = 1 + p * 2.5;
1053
+ sHtml += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${r.toFixed(1)}" fill="#ffffff" opacity="${alpha}" />`;
1054
+ }
1055
+ steamRef.current.innerHTML = sHtml;
1056
+ }
1057
+
1058
+ if (monitorScanlineRef.current) {
1059
+ const sY = -42 + ((t * 0.035) % 42);
1060
+ monitorScanlineRef.current.setAttribute("y1", sY.toFixed(1));
1061
+ monitorScanlineRef.current.setAttribute("y2", sY.toFixed(1));
1062
+ }
1063
+
1064
+ // 6. Pet Animation
1065
+ if (petGRef.current && petArch !== "none") {
1066
+ if (petArch === "hover_drone") {
1067
+ const droneY = -25 + Math.sin(t * 0.005) * 5;
1068
+ petGRef.current.setAttribute("transform", `translate(80, ${droneY.toFixed(2)})`);
1069
+ } else if (mode === "happy") {
1070
+ const jumpY = -Math.abs(Math.sin(t * 0.008)) * 8;
1071
+ const squash = 1 + Math.abs(Math.sin(t * 0.008)) * 0.15;
1072
+ petGRef.current.setAttribute("transform", `translate(80, ${jumpY.toFixed(2)}) scale(1, ${squash.toFixed(2)})`);
1073
+ } else if (mode === "sleeping") {
1074
+ const breathe = 1 + Math.sin(t * 0.0016) * 0.04;
1075
+ petGRef.current.setAttribute("transform", `translate(80, 0) scale(1, ${breathe.toFixed(2)})`);
1076
+ } else if (mode === "error") {
1077
+ const petShake = Math.sin(t * 0.08) * 2;
1078
+ petGRef.current.setAttribute("transform", `translate(${(80 + petShake).toFixed(2)}, 0)`);
1079
+ } else if (mode === "looping") {
1080
+ const petTilt = Math.sin(t * 0.04) * 8;
1081
+ petGRef.current.setAttribute("transform", `translate(80, 0) rotate(${petTilt.toFixed(1)})`);
1082
+ } else {
1083
+ petGRef.current.setAttribute("transform", "translate(80, 0)");
1084
+ }
1085
+ }
1086
+
1087
+ // 7. Dynamic Workstation & Action Particle Effects
1088
+ if (fxGroupRef.current) {
1089
+ if (mode === "streaming" || mode === "pending") {
1090
+ // Keystroke sparks & floating code bits shooting up from keyboard
1091
+ let inner = "";
1092
+ const numParticles = Math.min(8, Math.round(3 + intensity * 6));
1093
+ const codeTokens = ["✦", "01", "</>", "{ }", "++", "=>", "•", "λ", "=="];
1094
+ for (let k = 0; k < numParticles; k++) {
1095
+ const p = ((t * (0.0006 + intensity * 0.0006) + k / numParticles) % 1);
1096
+ const sx = 20 - p * 30 + Math.sin(p * 6 + k) * 6;
1097
+ const sy = 25 - p * 42;
1098
+ const alpha = (Math.sin(p * Math.PI) * (0.4 + intensity * 0.6)).toFixed(2);
1099
+ const token = codeTokens[k % codeTokens.length];
1100
+ if (k % 2 === 0) {
1101
+ inner += `<text x="${sx.toFixed(1)}" y="${sy.toFixed(1)}" fill="${skinColor}" font-size="5.5" font-family="monospace" font-weight="bold" opacity="${alpha}">${token}</text>`;
1102
+ } else {
1103
+ inner += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${(1 + p * 1.5).toFixed(1)}" fill="#00f0ff" opacity="${alpha}" />`;
1104
+ }
1105
+ }
1106
+ fxGroupRef.current.innerHTML = inner;
1107
+ } else if (mode === "happy") {
1108
+ // Celebration Confetti & Sparkles
1109
+ let inner = "";
1110
+ const colors = ["#fbbf24", "#00f0ff", "#f43f5e", "#10b981", "#a855f7", "#ffffff"];
1111
+ const shapes = ["✦", "★", "✧", "•"];
1112
+ for (let k = 0; k < 10; k++) {
1113
+ const p = ((t * 0.0007 + k / 10) % 1);
1114
+ const ang = (k / 10) * Math.PI * 2;
1115
+ const dist = 18 + p * 45;
1116
+ const cx = Math.cos(ang) * dist;
1117
+ const cy = -50 + Math.sin(ang) * (dist * 0.7) - p * 15;
1118
+ const alpha = ((1 - p) * 0.9).toFixed(2);
1119
+ const col = colors[k % colors.length];
1120
+ const sym = shapes[k % shapes.length];
1121
+ inner += `<text x="${cx.toFixed(1)}" y="${cy.toFixed(1)}" fill="${col}" font-size="7" font-weight="bold" opacity="${alpha}">${sym}</text>`;
1122
+ }
1123
+ fxGroupRef.current.innerHTML = inner;
1124
+ } else if (mode === "sleeping") {
1125
+ // Floating Sleep Z Letters & Bubbles
1126
+ let inner = "";
1127
+ for (let k = 0; k < 4; k++) {
1128
+ const p = ((t * 0.0004 + k / 4) % 1);
1129
+ const zx = 18 + p * 20;
1130
+ const zy = -78 - p * 34;
1131
+ const s = 3 + p * 4;
1132
+ const alpha = (1 - p).toFixed(2);
1133
+ inner += `<path d="M ${zx} ${zy} L ${zx + s} ${zy} L ${zx} ${zy + s} L ${zx + s} ${zy + s}" stroke="#93c5fd" stroke-width="1.8" fill="none" opacity="${alpha}" />`;
1134
+ inner += `<circle cx="${(zx - 6).toFixed(1)}" cy="${(zy + 8).toFixed(1)}" r="${(1.5 + p * 3).toFixed(1)}" fill="none" stroke="#60a5fa" stroke-width="0.8" opacity="${(alpha * 0.6).toFixed(2)}" />`;
1135
+ }
1136
+ fxGroupRef.current.innerHTML = inner;
1137
+ } else if (mode === "error" || mode === "looping") {
1138
+ // Billowing Smoke & Electric Arc Sparks
1139
+ let inner = "";
1140
+ for (let k = 0; k < 5; k++) {
1141
+ const p = ((t * 0.0008 + k / 5) % 1);
1142
+ const sx = Math.sin(p * 8 + k * 1.3) * 8 + (k - 2) * 4;
1143
+ const sy = -76 - p * 42;
1144
+ const r = 2.5 + p * 8;
1145
+ const alpha = (0.65 * (1 - p)).toFixed(2);
1146
+ inner += `<circle cx="${sx.toFixed(1)}" cy="${sy.toFixed(1)}" r="${r.toFixed(1)}" fill="#4b5563" opacity="${alpha}" />`;
1147
+ }
1148
+ if (Math.sin(t * 0.05) > 0.6) {
1149
+ inner += `<path d="M -26 -65 L -34 -72 L -28 -74 L -36 -82" stroke="#f43f5e" stroke-width="1.5" fill="none" />`;
1150
+ inner += `<path d="M 26 -65 L 34 -72 L 28 -74 L 36 -82" stroke="#facc15" stroke-width="1.5" fill="none" />`;
1151
+ }
1152
+ fxGroupRef.current.innerHTML = inner;
1153
+ } else {
1154
+ fxGroupRef.current.innerHTML = "";
1155
+ }
1156
+ }
1157
+
1158
+ if (isPlaying) {
1159
+ animId = requestAnimationFrame(tick);
1160
+ }
1161
+ };
1162
+
1163
+ animId = requestAnimationFrame(tick);
1164
+ return () => cancelAnimationFrame(animId);
1165
+ }, [interactive, mode, intensity, petArch, isPlaying]);
1166
+
1167
+ // Prop helpers & resolved list
1168
+ const resolvedProps = useMemo(() => {
1169
+ if (!propsList || propsList.length === 0) return [];
1170
+ return propsList
1171
+ .map((p) => (typeof p === "object" && p !== null ? p : getItemById(p) || null))
1172
+ .filter(Boolean);
1173
+ }, [propsList]);
1174
+
1175
+ const hasProp = (keyword) => {
1176
+ const kw = String(keyword).toLowerCase();
1177
+ return (
1178
+ (propsList || []).some((p) => String(p).toLowerCase().includes(kw)) ||
1179
+ resolvedProps.some((p) => (p.archetype && p.archetype.includes(kw)) || (p.name && p.name.toLowerCase().includes(kw)))
1180
+ );
1181
+ };
1182
+
1183
+ const getProp = (arch) => {
1184
+ const kw = String(arch).toLowerCase();
1185
+ return resolvedProps.find((p) => (p.archetype && p.archetype.includes(kw)) || (p.name && p.name.toLowerCase().includes(kw)) || String(p.id).includes(kw));
1186
+ };
1187
+
1188
+ return (
1189
+ <div
1190
+ className={`relative select-none flex items-center justify-center overflow-hidden ${className}`}
1191
+ style={style}
1192
+ >
1193
+ <svg
1194
+ ref={rootGRef}
1195
+ viewBox={showDesk || showFloor ? "-170 -160 340 300" : "-65 -95 130 130"}
1196
+ className="w-full h-full block"
1197
+ style={{ filter: "drop-shadow(0 12px 24px rgba(0,0,0,0.5))" }}
1198
+ >
1199
+ <defs>
1200
+ {/* Radial Ambient Glow */}
1201
+ <radialGradient id={`${idPrefix}_ambientGlow`} cx="50%" cy="50%" r="50%">
1202
+ <stop offset="0%" stopColor={themeStyle.glow} stopOpacity="0.25" />
1203
+ <stop offset="70%" stopColor={themeStyle.base} stopOpacity="0.05" />
1204
+ <stop offset="100%" stopColor="transparent" stopOpacity="0" />
1205
+ </radialGradient>
1206
+
1207
+ {/* Torso & Head Shading Gradients */}
1208
+ <linearGradient id={`${idPrefix}_bodyGradient`} x1="0" y1="0" x2="0" y2="1">
1209
+ <stop offset="0%" stopColor="#ffffff" />
1210
+ <stop offset="50%" stopColor="#1e2430" />
1211
+ <stop offset="100%" stopColor="#111622" />
1212
+ </linearGradient>
1213
+
1214
+ <linearGradient id={`${idPrefix}_headGradient`} x1="0" y1="0" x2="0" y2="1">
1215
+ <stop offset="0%" stopColor="#2d3748" />
1216
+ <stop offset="60%" stopColor="#1e2430" />
1217
+ <stop offset="100%" stopColor="#111622" />
1218
+ </linearGradient>
1219
+
1220
+ <linearGradient id={`${idPrefix}_deskGradient`} x1="0" y1="0" x2="0" y2="1">
1221
+ <stop offset="0%" stopColor="#2b3443" />
1222
+ <stop offset="100%" stopColor="#181d26" />
1223
+ </linearGradient>
1224
+
1225
+ <linearGradient id={`${idPrefix}_floorGradient`} x1="0" y1="0" x2="0" y2="1">
1226
+ <stop offset="0%" stopColor={themeStyle.tile} />
1227
+ <stop offset="100%" stopColor={themeStyle.base} />
1228
+ </linearGradient>
1229
+ </defs>
1230
+
1231
+ {/* 1. FLOOR THEME ISOMETRIC ENVIRONMENT */}
1232
+ {showFloor && (
1233
+ <g transform="translate(0, 50)">
1234
+ {/* Ambient Radial Spotlight */}
1235
+ <circle cx="0" cy="-30" r="140" fill={`url(#${idPrefix}_ambientGlow)`} />
1236
+
1237
+ {/* Floor Cast Shadow */}
1238
+ <ellipse cx="0" cy="18" rx="145" ry="46" fill="#000000" opacity="0.55" />
1239
+
1240
+ {/* Isometric Floor Rhombus */}
1241
+ <polygon
1242
+ points="0,-68 150,0 0,68 -150,0"
1243
+ fill={`url(#${idPrefix}_floorGradient)`}
1244
+ stroke={themeStyle.grid}
1245
+ strokeWidth="1.8"
1246
+ />
1247
+
1248
+ {/* Floor Bevel Extrusion Rim */}
1249
+ <polygon points="-150,0 0,68 0,76 -150,8" fill="#090a0f" opacity="0.6" />
1250
+ <polygon points="150,0 0,68 0,76 150,8" fill="#050608" opacity="0.8" />
1251
+
1252
+ {/* Floor Gridlines */}
1253
+ <g stroke={themeStyle.grid} strokeWidth="1" opacity="0.45">
1254
+ <line x1="-75" y1="-34" x2="75" y2="34" />
1255
+ <line x1="-112" y1="-17" x2="38" y2="51" />
1256
+ <line x1="-38" y1="-51" x2="112" y2="17" />
1257
+ <line x1="75" y1="-34" x2="-75" y2="34" />
1258
+ <line x1="112" y1="-17" x2="-38" y2="51" />
1259
+ <line x1="38" y1="-51" x2="-112" y2="17" />
1260
+ </g>
1261
+
1262
+ {/* Neon Corner Brackets */}
1263
+ <g stroke={themeStyle.glow} strokeWidth="2" fill="none">
1264
+ <path d="M -130,-4 L -145,0 L -130,4" />
1265
+ <path d="M 130,-4 L 145,0 L 130,4" />
1266
+ </g>
1267
+ </g>
1268
+ )}
1269
+
1270
+ {/* 2. DYNAMIC AURA & ATMOSPHERE EFFECTS LAYER (Behind Character) */}
1271
+ {auraArch !== "none" && (
1272
+ <g transform="translate(0, -42)">
1273
+ <g ref={auraRef}>
1274
+ <g ref={auraParticlesRef} />
1275
+ </g>
1276
+ </g>
1277
+ )}
1278
+
1279
+ {/* 3. AGENT BODY & HEAD (Positioned behind desk) */}
1280
+ <g id="agent-root" transform="translate(0, -50)">
1281
+ <g ref={bodyGRef}>
1282
+ {/* Distinct Staff Torso & Uniform Silhouette */}
1283
+ <RenderStaffTorso
1284
+ archetype={skinArch}
1285
+ color={skinColor}
1286
+ secondaryColor={skinSecColor}
1287
+ accentColor={skinAccColor}
1288
+ idPrefix={idPrefix}
1289
+ trimColor={trimColor}
1290
+ />
1291
+
1292
+ {/* Distinct Staff Arms with Archetype Sleeves */}
1293
+ <RenderStaffArms
1294
+ archetype={skinArch}
1295
+ color={skinColor}
1296
+ armLRef={armLRef}
1297
+ armRRef={armRRef}
1298
+ />
1299
+
1300
+ {/* Comm Pods */}
1301
+ <circle cx="-27" cy="-56" r="8" fill={skinColor} />
1302
+ <circle cx="27" cy="-56" r="8" fill={skinColor} />
1303
+
1304
+ {/* Helmet Sphere */}
1305
+ <ellipse
1306
+ cx="0"
1307
+ cy="-56"
1308
+ rx="26"
1309
+ ry="24"
1310
+ fill={`url(#${idPrefix}_headGradient)`}
1311
+ stroke={skinColor}
1312
+ strokeWidth="2.2"
1313
+ />
1314
+
1315
+ {/* Visor Cavity */}
1316
+ <ellipse cx="0" cy="-53" rx="20" ry="15.5" fill="#0f141c" />
1317
+
1318
+ {/* Custom 50 Curated Skin Accessories */}
1319
+ <RenderSkinAccessories
1320
+ variant={skinVariant}
1321
+ archetype={skinArch}
1322
+ color={skinColor}
1323
+ secondaryColor={skinSecColor}
1324
+ accentColor={skinAccColor}
1325
+ />
1326
+
1327
+ {/* CRT Visor Eyes */}
1328
+ {mode === "happy" ? (
1329
+ <g stroke={skinColor} strokeWidth="2.2" fill="none">
1330
+ <path d="M -12.6 -55 A 4.6 4.6 0 0 1 -3.4 -55" />
1331
+ <path d="M 3.4 -55 A 4.6 4.6 0 0 1 12.6 -55" />
1332
+ </g>
1333
+ ) : mode === "sleeping" ? (
1334
+ <g stroke={skinColor} strokeWidth="2.2" fill="none">
1335
+ <path d="M -12.6 -57 A 4.6 4.6 0 0 0 -3.4 -57" />
1336
+ <path d="M 3.4 -57 A 4.6 4.6 0 0 0 12.6 -57" />
1337
+ </g>
1338
+ ) : mode === "error" ? (
1339
+ <g stroke={skinColor} strokeWidth="2.2">
1340
+ <line x1="-12" y1="-61" x2="-4" y2="-53" />
1341
+ <line x1="-4" y1="-61" x2="-12" y2="-53" />
1342
+ <line x1="4" y1="-61" x2="12" y2="-53" />
1343
+ <line x1="12" y1="-61" x2="4" y2="-53" />
1344
+ </g>
1345
+ ) : mode === "looping" ? (
1346
+ <g stroke={skinColor} strokeWidth="1.6" fill="none">
1347
+ <circle cx="-8" cy="-57" r="4.2" />
1348
+ <circle cx="-8" cy="-57" r="2.0" />
1349
+ <circle cx="8" cy="-57" r="4.2" />
1350
+ <circle cx="8" cy="-57" r="2.0" />
1351
+ </g>
1352
+ ) : (
1353
+ <g>
1354
+ <ellipse ref={eyeLRef} cx="-8" cy="-57" rx="4.8" ry="4.4" fill={skinColor} />
1355
+ <ellipse ref={eyeRRef} cx="8" cy="-57" rx="4.8" ry="4.4" fill={skinColor} />
1356
+ </g>
1357
+ )}
1358
+
1359
+ {/* Mouth */}
1360
+ {mode === "happy" ? (
1361
+ <path d="M -6 -48 A 6 6 0 0 0 6 -48" stroke={skinColor} strokeWidth="2.2" fill="none" />
1362
+ ) : mode === "sleeping" ? (
1363
+ <circle cx="0" cy="-45" r="1.8" fill="none" stroke={skinColor} strokeWidth="1.6" />
1364
+ ) : mode === "error" ? (
1365
+ <path d="M -7 -45 L -3.5 -48 L 0 -45 L 3.5 -48 L 7 -45" stroke={skinColor} strokeWidth="2" fill="none" />
1366
+ ) : mode === "looping" ? (
1367
+ <circle cx="0" cy="-46" r="3.2" fill="none" stroke={skinColor} strokeWidth="2" />
1368
+ ) : (
1369
+ <ellipse ref={mouthRef} cx="0" cy="-46" rx={5 + intensity * 3} ry={2.4 + intensity * 1.2} fill={skinColor} />
1370
+ )}
1371
+
1372
+ {/* Particle Effects Group (Z's or Smoke) */}
1373
+ <g ref={fxGroupRef} />
1374
+ </g>
1375
+ </g>
1376
+
1377
+ {/* 4. WORKSTATION DESK & PROPS (In front of Character) */}
1378
+ {showDesk && (
1379
+ <g id="desk-root" transform="translate(0, 0)">
1380
+ {/* Ground Contact Shadow */}
1381
+ <ellipse cx="0" cy="65" rx="110" ry="14" fill="#000000" opacity="0.4" />
1382
+
1383
+ {/* Desk Surface & Base */}
1384
+ <rect x="-105" y="0" width="210" height="120" rx="10" fill={`url(#${idPrefix}_deskGradient)`} stroke="#475569" strokeWidth="1.5" />
1385
+
1386
+ {/* Desk Lip Highlight */}
1387
+ <rect x="-105" y="0" width="210" height="4" fill="#ffffff" opacity="0.15" />
1388
+
1389
+ {/* Latency / Elapsed Progress Bar */}
1390
+ <rect x="-85" y="106" width="170" height="6" rx="3" fill="#0f141c" />
1391
+ <rect
1392
+ x="-85"
1393
+ y="106"
1394
+ width={170 * (0.3 + intensity * 0.7)}
1395
+ height="6"
1396
+ rx="3"
1397
+ fill={mode === "error" ? "#f43f5e" : intensity > 0.8 ? "#f59e0b" : "#10b981"}
1398
+ />
1399
+
1400
+ {/* Center Monitor Screen */}
1401
+ <rect x="-45" y="-45" width="90" height="48" rx="4" fill="#0b0e13" />
1402
+ <rect
1403
+ x="-42"
1404
+ y="-42"
1405
+ width="84"
1406
+ height="42"
1407
+ rx="3"
1408
+ fill={mode === "error" ? "rgba(244,63,94,0.3)" : "rgba(0,240,255,0.25)"}
1409
+ />
1410
+
1411
+ {/* CRT Active Scanline Beam */}
1412
+ <line
1413
+ ref={monitorScanlineRef}
1414
+ x1="-42"
1415
+ y1="-42"
1416
+ x2="42"
1417
+ y2="-42"
1418
+ stroke={mode === "error" ? "#f43f5e" : "#00f0ff"}
1419
+ strokeWidth="1.6"
1420
+ opacity="0.65"
1421
+ />
1422
+
1423
+ {/* Screen Code Lines */}
1424
+ <g fill="#ffffff" opacity="0.5">
1425
+ <rect x="-38" y="-38" width="24" height="3" rx="1" />
1426
+ <rect x="-38" y="-29" width="42" height="3" rx="1" />
1427
+ <rect x="-38" y="-20" width="30" height="3" rx="1" />
1428
+ <rect x="-38" y="-11" width="36" height="3" rx="1" />
1429
+ </g>
1430
+
1431
+ {/* Monitor Client Badge */}
1432
+ <rect x="-42" y="-42" width="28" height="12" rx="2" fill={clientType === "app" ? "#3b0764" : "#064e3b"} />
1433
+ <text x="-38" y="-33" fontFamily="monospace" fontSize="8" fontWeight="bold" fill={clientType === "app" ? "#d8b4fe" : "#6ee7b7"}>
1434
+ {clientType.toUpperCase()}
1435
+ </text>
1436
+
1437
+ {/* ----------------- EQUIPPED PROPS (7 DISTINCT ARCHETYPES) ----------------- */}
1438
+
1439
+ {/* 1. SUPERCOMPUTER / SERVER TOWER */}
1440
+ {(hasProp("supercomputer") || hasProp("server") || hasProp("tower") || (resolvedProps.length === 0 && hasProp("prop_1"))) && (() => {
1441
+ const p = getProp("supercomputer") || { color: "#00f0ff", secondaryColor: "#003b46" };
1442
+ return (
1443
+ <g id="prop-supercomputer" transform="translate(-98, -26)">
1444
+ <rect x="0" y="0" width="16" height="42" rx="3" fill="#121824" stroke={p.color} strokeWidth="1.2" />
1445
+ {/* Drive bays */}
1446
+ <line x1="3" y1="8" x2="13" y2="8" stroke="#334155" strokeWidth="1.5" />
1447
+ <line x1="3" y1="14" x2="13" y2="14" stroke="#334155" strokeWidth="1.5" />
1448
+ <line x1="3" y1="20" x2="13" y2="20" stroke="#334155" strokeWidth="1.5" />
1449
+ {/* Blinking LEDs */}
1450
+ {[0, 1, 2, 3].map((idx) => (
1451
+ <circle
1452
+ key={`server-led-${idx}`}
1453
+ ref={(el) => (serverLedsRef.current[idx] = el)}
1454
+ cx="5"
1455
+ cy={26 + idx * 4}
1456
+ r="1.4"
1457
+ fill={p.color}
1458
+ />
1459
+ ))}
1460
+ {/* Ventilation Grill */}
1461
+ <line x1="9" y1="26" x2="13" y2="26" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
1462
+ <line x1="9" y1="30" x2="13" y2="30" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
1463
+ <line x1="9" y1="34" x2="13" y2="34" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
1464
+ <line x1="9" y1="38" x2="13" y2="38" stroke={p.color} strokeWidth="0.8" opacity="0.6" />
1465
+ </g>
1466
+ );
1467
+ })()}
1468
+
1469
+ {/* 2. ESPRESSO STATION */}
1470
+ {(hasProp("espresso_station") || hasProp("espresso") || hasProp("coffee") || (resolvedProps.length === 0)) && (() => {
1471
+ const p = getProp("espresso_station") || { color: "#e2e8f0", secondaryColor: "#1e293b" };
1472
+ return (
1473
+ <g id="prop-espresso">
1474
+ {/* Steaming Coffee Cup */}
1475
+ <rect x="-80" y="10" width="14" height="16" rx="2" fill={p.color || "#e2e8f0"} stroke="#475569" strokeWidth="1" />
1476
+ <path d="M -66 14 C -62 14, -62 22, -66 22" stroke={p.color || "#e2e8f0"} strokeWidth="2" fill="none" />
1477
+ <g ref={steamRef} />
1478
+ {/* Machine Body (if explicitly an espresso station) */}
1479
+ {(hasProp("espresso_station") || hasProp("espresso")) && (
1480
+ <g transform="translate(-84, -14)">
1481
+ <rect x="0" y="0" width="18" height="24" rx="2" fill="#1e293b" stroke={p.color} strokeWidth="1" />
1482
+ <circle cx="9" cy="8" r="4" fill="#0f172a" stroke={p.color} strokeWidth="0.8" />
1483
+ <line x1="9" y1="8" x2="11" y2="6" stroke="#ef4444" strokeWidth="0.8" />
1484
+ <rect x="6" y="14" width="6" height="3" fill="#64748b" />
1485
+ </g>
1486
+ )}
1487
+ </g>
1488
+ );
1489
+ })()}
1490
+
1491
+ {/* 3. ARCADE CABINET */}
1492
+ {(hasProp("arcade_cabinet") || hasProp("arcade")) && (() => {
1493
+ const p = getProp("arcade_cabinet") || { color: "#f43f5e", secondaryColor: "#881337" };
1494
+ return (
1495
+ <g id="prop-arcade" transform="translate(-96, -24)">
1496
+ {/* Cabinet Body */}
1497
+ <polygon points="0,42 0,6 4,0 16,0 18,6 18,42" fill="#18181b" stroke={p.color} strokeWidth="1.2" />
1498
+ {/* Marquee Banner */}
1499
+ <rect x="3" y="2" width="12" height="6" rx="1" fill={p.color} />
1500
+ <text x="9" y="7" fill="#ffffff" fontSize="4" fontWeight="bold" textAnchor="middle" fontFamily="monospace">PLAY</text>
1501
+ {/* Screen Bezel & Screen */}
1502
+ <polygon points="2,11 16,11 15,24 3,24" fill="#09090b" stroke="#27272a" strokeWidth="0.8" />
1503
+ <polygon points="3,12 15,12 14,23 4,23" fill={p.secondaryColor || "#09090b"} />
1504
+ {/* 8-bit Pixel Sprite on Screen */}
1505
+ <rect x="7" y="15" width="4" height="4" fill={p.color} />
1506
+ {/* Control Panel: Joystick & Buttons */}
1507
+ <polygon points="2,25 16,25 17,31 1,31" fill="#27272a" stroke={p.color} strokeWidth="0.8" />
1508
+ <circle cx="5" cy="27.5" r="1.6" fill="#ef4444" />
1509
+ <line x1="5" y1="27.5" x2="5" y2="30" stroke="#ffffff" strokeWidth="0.8" />
1510
+ <circle cx="11" cy="28" r="1.2" fill={p.color} />
1511
+ <circle cx="14" cy="27" r="1.2" fill="#eab308" />
1512
+ {/* Coin Door */}
1513
+ <rect x="6" y="34" width="6" height="6" rx="1" fill="#09090b" stroke="#3f3f46" strokeWidth="0.6" />
1514
+ <rect x="8.5" y="35" width="1" height="3" fill="#eab308" />
1515
+ </g>
1516
+ );
1517
+ })()}
1518
+
1519
+ {/* 4. TERRARIUM BONSAI */}
1520
+ {(hasProp("terrarium_bonsai") || hasProp("bonsai") || hasProp("plant")) && (() => {
1521
+ const p = getProp("terrarium_bonsai") || { color: "#10b981", secondaryColor: "#064e3b" };
1522
+ return (
1523
+ <g id="prop-bonsai" transform="translate(-84, 4)">
1524
+ {/* Hexagonal Ceramic Planter */}
1525
+ <polygon points="2,14 16,14 14,20 4,20" fill="#78350f" stroke="#b45309" strokeWidth="1" />
1526
+ {/* Gnarled Bonsai Trunk */}
1527
+ <path d="M 9 14 Q 8 8 5 5 Q 12 2 10 -4" stroke="#92400e" strokeWidth="2.4" fill="none" strokeLinecap="round" />
1528
+ {/* Glowing Foliage / Sakura Clouds */}
1529
+ <ellipse cx="5" cy="2" rx="6.5" ry="4" fill={p.color} opacity="0.9" />
1530
+ <ellipse cx="12" cy="-2" rx="6" ry="3.8" fill={p.color} opacity="0.95" />
1531
+ <ellipse cx="8" cy="6" rx="4.5" ry="3" fill={p.secondaryColor || "#059669"} opacity="0.85" />
1532
+ <circle cx="5" cy="2" r="1.2" fill="#ffffff" />
1533
+ <circle cx="12" cy="-2" r="1.2" fill="#ffffff" />
1534
+ </g>
1535
+ );
1536
+ })()}
1537
+
1538
+ {/* 5. DUAL MONITOR */}
1539
+ {(hasProp("dual_monitor") || hasProp("monitor") || hasProp("screen")) && (() => {
1540
+ const p = getProp("dual_monitor") || { color: "#06b6d4", secondaryColor: "#083344" };
1541
+ return (
1542
+ <g id="prop-dual-monitor" transform="translate(50, -36)">
1543
+ {/* Articulated Gas-Spring Mount Arm */}
1544
+ <line x1="22" y1="28" x2="22" y2="46" stroke="#475569" strokeWidth="2.4" />
1545
+ <ellipse cx="22" cy="46" rx="7" ry="2.5" fill="#334155" />
1546
+ {/* Secondary Angled Screen */}
1547
+ <rect x="2" y="0" width="40" height="30" rx="3" fill="#090d16" stroke={p.color} strokeWidth="1.2" />
1548
+ {/* Screen Content: Mini Syntax Code Lines & Status Bar */}
1549
+ <rect x="5" y="4" width="22" height="2" rx="0.5" fill={p.color} opacity="0.8" />
1550
+ <rect x="5" y="8" width="16" height="2" rx="0.5" fill="#ffffff" opacity="0.5" />
1551
+ <rect x="5" y="12" width="28" height="2" rx="0.5" fill="#ffffff" opacity="0.4" />
1552
+ <rect x="5" y="16" width="20" height="2" rx="0.5" fill={p.color} opacity="0.7" />
1553
+ {/* Telemetry Bar Chart on Right */}
1554
+ <rect x="30" y="20" width="2" height="6" fill="#10b981" />
1555
+ <rect x="33" y="16" width="2" height="10" fill={p.color} />
1556
+ <rect x="36" y="12" width="2" height="14" fill="#f59e0b" />
1557
+ </g>
1558
+ );
1559
+ })()}
1560
+
1561
+ {/* 6. HOLOGRAM EMITTER */}
1562
+ {(hasProp("hologram_emitter") || hasProp("holo") || hasProp("cube")) && (() => {
1563
+ const p = getProp("hologram_emitter") || { color: skinColor, secondaryColor: "#1e1b4b" };
1564
+ return (
1565
+ <g id="prop-hologram">
1566
+ {/* Hexagonal Emitter Pad */}
1567
+ <ellipse cx="65" cy="14" rx="14" ry="5" fill="#1e293b" stroke={p.color} strokeWidth="1.2" />
1568
+ <ellipse cx="65" cy="13" rx="9" ry="3" fill="#0f172a" stroke={p.color} strokeWidth="0.8" />
1569
+ {/* Upward Volumetric Hologram Cone */}
1570
+ <polygon points="65,13 46,-16 84,-16" fill={p.color} opacity="0.16" />
1571
+ <line x1="46" y1="-16" x2="84" y2="-16" stroke={p.color} strokeWidth="1" opacity="0.4" strokeDasharray="2 2" />
1572
+ {/* Floating Rotating Hologram Core */}
1573
+ <g ref={holoCubeRef}>
1574
+ <rect x="-10" y="-10" width="20" height="20" fill="none" stroke={p.color} strokeWidth="1.4" opacity="0.9" />
1575
+ <line x1="-10" y1="-10" x2="10" y2="10" stroke={p.color} strokeWidth="0.8" opacity="0.5" />
1576
+ <circle cx="0" cy="0" r="2.5" fill={p.color} />
1577
+ </g>
1578
+ </g>
1579
+ );
1580
+ })()}
1581
+
1582
+ {/* 7. LAB OSCILLOSCOPE */}
1583
+ {(hasProp("lab_oscilloscope") || hasProp("osc") || hasProp("scope") || hasProp("wave")) && (() => {
1584
+ const p = getProp("lab_oscilloscope") || { color: "#10b981", secondaryColor: "#064e3b" };
1585
+ return (
1586
+ <g id="prop-oscilloscope" transform="translate(56, 8)">
1587
+ {/* Instrument Enclosure */}
1588
+ <rect x="0" y="0" width="34" height="24" rx="3" fill="#111827" stroke="#374151" strokeWidth="1.2" />
1589
+ {/* Phosphor CRT Display */}
1590
+ <rect x="3" y="3" width="20" height="18" rx="2" fill="#051b14" stroke={p.color} strokeWidth="0.8" />
1591
+ {/* Screen Grid Reticle */}
1592
+ <line x1="13" y1="3" x2="13" y2="21" stroke={p.color} strokeWidth="0.4" opacity="0.4" strokeDasharray="1 1" />
1593
+ <line x1="3" y1="12" x2="23" y2="12" stroke={p.color} strokeWidth="0.4" opacity="0.4" strokeDasharray="1 1" />
1594
+ {/* Live Animated Waveform */}
1595
+ <path ref={oscWaveRef} d="M 4 12 L 22 12" stroke={p.color} strokeWidth="1.4" fill="none" />
1596
+ {/* Control Knobs & BNC Jacks */}
1597
+ <circle cx="28" cy="7" r="2.4" fill="#374151" stroke="#9ca3af" strokeWidth="0.6" />
1598
+ <circle cx="28" cy="14" r="2.4" fill="#374151" stroke="#9ca3af" strokeWidth="0.6" />
1599
+ <circle cx="28" cy="19.5" r="1.5" fill={p.color} />
1600
+ </g>
1601
+ );
1602
+ })()}
1603
+
1604
+ {/* Mechanical Keyboard */}
1605
+ <g id="prop-keyboard">
1606
+ <rect x="15" y="27" width="34" height="8" rx="2" fill="#232a35" stroke="#3b4554" strokeWidth="1" />
1607
+ </g>
1608
+
1609
+ {/* ----------------- COMPANION PET ----------------- */}
1610
+ {petArch !== "none" && (
1611
+ <g ref={petGRef} id="companion-pet">
1612
+ {petArch === "hover_drone" ? (
1613
+ <g>
1614
+ <ellipse cx="0" cy="0" rx="14" ry="8" fill="#0f172a" stroke={petColor} strokeWidth="1.5" />
1615
+ <ellipse cx="0" cy="-6" rx="16" ry="3" fill="none" stroke="#ffffff" strokeWidth="1" />
1616
+ <circle cx="0" cy="0" r="2.5" fill={petColor} />
1617
+ </g>
1618
+ ) : (
1619
+ <g>
1620
+ <rect x="-10" y="-14" width="20" height="16" rx="5" fill="#1e293b" stroke={petColor} strokeWidth="1.4" />
1621
+ {/* Ears */}
1622
+ <polygon points="-8,-14 -4,-20 -1,-14" fill={petColor} />
1623
+ <polygon points="1,-14 4,-20 8,-14" fill={petColor} />
1624
+ {/* Eyes */}
1625
+ <circle cx="-4" cy="-8" r="1.5" fill="#ffffff" />
1626
+ <circle cx="4" cy="-8" r="1.5" fill="#ffffff" />
1627
+ </g>
1628
+ )}
1629
+ </g>
1630
+ )}
1631
+ </g>
1632
+ )}
1633
+ </svg>
1634
+ </div>
1635
+ );
1636
+ }
1637
+ export default LiveReactAgent;