@xopcai/xopc 0.0.8 → 0.0.11

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 (242) hide show
  1. package/dist/extensions/telegram/src/plugin.js +1 -1
  2. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  3. package/dist/extensions/weixin/src/plugin.js +1 -1
  4. package/dist/gateway/static/root/assets/{agents-BSNzJWbQ.js → agents-BdC4Y-HX.js} +2 -2
  5. package/dist/gateway/static/root/assets/agents-BdC4Y-HX.js.map +1 -0
  6. package/dist/gateway/static/root/assets/{apps-page-BKk9SB4D.js → apps-page-C-oaSHkm.js} +2 -2
  7. package/dist/gateway/static/root/assets/{apps-page-BKk9SB4D.js.map → apps-page-C-oaSHkm.js.map} +1 -1
  8. package/dist/gateway/static/root/assets/attachment-load-BDDlItdE.js +1 -0
  9. package/dist/gateway/static/root/assets/{channels-settings-_J6cQN6G.js → channels-settings-BqEUppPO.js} +2 -2
  10. package/dist/gateway/static/root/assets/{channels-settings-_J6cQN6G.js.map → channels-settings-BqEUppPO.js.map} +1 -1
  11. package/dist/gateway/static/root/assets/{chat-agents-api-DPb_0O8M.js → chat-agents-api-BhqjQ7iL.js} +2 -2
  12. package/dist/gateway/static/root/assets/{chat-agents-api-DPb_0O8M.js.map → chat-agents-api-BhqjQ7iL.js.map} +1 -1
  13. package/dist/gateway/static/root/assets/{cron-page-BUJOuuKX.js → cron-page-Cli49RKR.js} +2 -2
  14. package/dist/gateway/static/root/assets/{cron-page-BUJOuuKX.js.map → cron-page-Cli49RKR.js.map} +1 -1
  15. package/dist/gateway/static/root/assets/{cron-utils-Cn0YVg8x.js → cron-utils-Dkj-Ldpf.js} +2 -2
  16. package/dist/gateway/static/root/assets/{cron-utils-Cn0YVg8x.js.map → cron-utils-Dkj-Ldpf.js.map} +1 -1
  17. package/dist/gateway/static/root/assets/{electron-env-D9bm1FIu.js → electron-env-BDtJw9AY.js} +2 -2
  18. package/dist/gateway/static/root/assets/{electron-env-D9bm1FIu.js.map → electron-env-BDtJw9AY.js.map} +1 -1
  19. package/dist/gateway/static/root/assets/{extension-debug-page-DTz4O5Ua.js → extension-debug-page-BMcZlaxF.js} +2 -2
  20. package/dist/gateway/static/root/assets/{extension-debug-page-DTz4O5Ua.js.map → extension-debug-page-BMcZlaxF.js.map} +1 -1
  21. package/dist/gateway/static/root/assets/{extension-iframe-host-Cs1Kde9o.js → extension-iframe-host-D5HEF0KR.js} +2 -2
  22. package/dist/gateway/static/root/assets/{extension-iframe-host-Cs1Kde9o.js.map → extension-iframe-host-D5HEF0KR.js.map} +1 -1
  23. package/dist/gateway/static/root/assets/{extension-page-G52iX0Bo.js → extension-page-CXdCSSPl.js} +2 -2
  24. package/dist/gateway/static/root/assets/{extension-page-G52iX0Bo.js.map → extension-page-CXdCSSPl.js.map} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-provider-CO2jxBA9.js → extension-provider-DZCZgQE2.js} +2 -2
  26. package/dist/gateway/static/root/assets/{extension-provider-CO2jxBA9.js.map → extension-provider-DZCZgQE2.js.map} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D9Ul8uSt.js → extension-settings-page-CX6STpx3.js} +2 -2
  28. package/dist/gateway/static/root/assets/{extension-settings-page-D9Ul8uSt.js.map → extension-settings-page-CX6STpx3.js.map} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-config-swr-Bc8SVD15.js → gateway-config-swr-Cph02QZn.js} +2 -2
  30. package/dist/gateway/static/root/assets/{gateway-config-swr-Bc8SVD15.js.map → gateway-config-swr-Cph02QZn.js.map} +1 -1
  31. package/dist/gateway/static/root/assets/index-Bty3m0mS.css +2 -0
  32. package/dist/gateway/static/root/assets/{index-BXUJbteW.js → index-iTUyfzNr.js} +10 -10
  33. package/dist/gateway/static/root/assets/index-iTUyfzNr.js.map +1 -0
  34. package/dist/gateway/static/root/assets/{logs-page-5V25JkQY.js → logs-page-B9O5l3I8.js} +2 -2
  35. package/dist/gateway/static/root/assets/{logs-page-5V25JkQY.js.map → logs-page-B9O5l3I8.js.map} +1 -1
  36. package/dist/gateway/static/root/assets/{model-selector-he3aQfme.js → model-selector-BLiY_O25.js} +2 -2
  37. package/dist/gateway/static/root/assets/{model-selector-he3aQfme.js.map → model-selector-BLiY_O25.js.map} +1 -1
  38. package/dist/gateway/static/root/assets/page-header-store-BFpnFTed.js +2 -0
  39. package/dist/gateway/static/root/assets/{page-header-store-DJHD9Ean.js.map → page-header-store-BFpnFTed.js.map} +1 -1
  40. package/dist/gateway/static/root/assets/{session-api-n-4O5d9U.js → session-api-DEhQXWJg.js} +2 -2
  41. package/dist/gateway/static/root/assets/{session-api-n-4O5d9U.js.map → session-api-DEhQXWJg.js.map} +1 -1
  42. package/dist/gateway/static/root/assets/{session-working-directory-control-B6dHLvbr.js → session-working-directory-control-DKOtWs3-.js} +2 -2
  43. package/dist/gateway/static/root/assets/{session-working-directory-control-B6dHLvbr.js.map → session-working-directory-control-DKOtWs3-.js.map} +1 -1
  44. package/dist/gateway/static/root/assets/{sessions-page-rBUfTdm3.js → sessions-page-BYlWP1ep.js} +2 -2
  45. package/dist/gateway/static/root/assets/{sessions-page-rBUfTdm3.js.map → sessions-page-BYlWP1ep.js.map} +1 -1
  46. package/dist/gateway/static/root/assets/{settings-page-B3QrJm-E.js → settings-page-oCnIavdg.js} +2 -2
  47. package/dist/gateway/static/root/assets/settings-page-oCnIavdg.js.map +1 -0
  48. package/dist/gateway/static/root/assets/{skill-api-vxtE8kI6.js → skill-api-DWrn8Az0.js} +2 -2
  49. package/dist/gateway/static/root/assets/{skill-api-vxtE8kI6.js.map → skill-api-DWrn8Az0.js.map} +1 -1
  50. package/dist/gateway/static/root/assets/{skills-page-D36_O2Ub.js → skills-page-C59WQpM1.js} +2 -2
  51. package/dist/gateway/static/root/assets/{skills-page-D36_O2Ub.js.map → skills-page-C59WQpM1.js.map} +1 -1
  52. package/dist/gateway/static/root/assets/{theme-store-CmiSsYBd.js → theme-store-CywXkKml.js} +2 -2
  53. package/dist/gateway/static/root/assets/{theme-store-CmiSsYBd.js.map → theme-store-CywXkKml.js.map} +1 -1
  54. package/dist/gateway/static/root/assets/url-D7yWllI8.js +2 -0
  55. package/dist/gateway/static/root/assets/url-D7yWllI8.js.map +1 -0
  56. package/dist/gateway/static/root/assets/{useTranslation-DYORQ7x6.js → useTranslation-CACj0DBJ.js} +2 -2
  57. package/dist/gateway/static/root/assets/{useTranslation-DYORQ7x6.js.map → useTranslation-CACj0DBJ.js.map} +1 -1
  58. package/dist/gateway/static/root/index.html +15 -15
  59. package/dist/package.js +1 -1
  60. package/dist/src/agent/agent-manager.d.ts +1 -0
  61. package/dist/src/agent/agent-manager.js +20 -12
  62. package/dist/src/agent/agent-manager.js.map +1 -1
  63. package/dist/src/agent/background-review/run-background-review.js +2 -0
  64. package/dist/src/agent/background-review/run-background-review.js.map +1 -1
  65. package/dist/src/agent/child-agent-factory.js +2 -0
  66. package/dist/src/agent/child-agent-factory.js.map +1 -1
  67. package/dist/src/agent/context/expand-at-file-mentions.d.ts +4 -0
  68. package/dist/src/agent/context/expand-at-file-mentions.js +69 -0
  69. package/dist/src/agent/context/expand-at-file-mentions.js.map +1 -0
  70. package/dist/src/agent/context/workspace-seed.js +1 -1
  71. package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
  72. package/dist/src/agent/ipc/bus.js +1 -1
  73. package/dist/src/agent/ipc/inbox.js +1 -1
  74. package/dist/src/agent/ipc/socket.js +1 -1
  75. package/dist/src/agent/memory/compaction.d.ts +1 -1
  76. package/dist/src/agent/memory/compaction.js +38 -11
  77. package/dist/src/agent/memory/compaction.js.map +1 -1
  78. package/dist/src/agent/messaging/command-handler.d.ts +13 -0
  79. package/dist/src/agent/messaging/command-handler.js +14 -2
  80. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  81. package/dist/src/agent/models/manager.js +1 -1
  82. package/dist/src/agent/orchestration/agent-orchestrator.js +6 -1
  83. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  84. package/dist/src/agent/prompt/service-prompt-builder.js +1 -1
  85. package/dist/src/agent/service.d.ts +16 -1
  86. package/dist/src/agent/service.js +178 -20
  87. package/dist/src/agent/service.js.map +1 -1
  88. package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
  89. package/dist/src/agent/skills/index.js +1 -1
  90. package/dist/src/agent/skills/scanner.js +1 -1
  91. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  92. package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
  93. package/dist/src/agent/skills/skill-manager.js +1 -1
  94. package/dist/src/agent/tools/browser/tools.js.map +1 -1
  95. package/dist/src/agent/tools/factory.js +1 -1
  96. package/dist/src/agent/tools/image-tool.js.map +1 -1
  97. package/dist/src/agent/tools/send-media.js +1 -1
  98. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  99. package/dist/src/agent/tools/write.js +1 -1
  100. package/dist/src/auth/credentials.js +2 -2
  101. package/dist/src/auth/sync-provider-auth.js +1 -1
  102. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  103. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  104. package/dist/src/channels/index.d.ts +1 -1
  105. package/dist/src/channels/index.js +2 -2
  106. package/dist/src/channels/pipeline.d.ts +8 -1
  107. package/dist/src/channels/pipeline.js +49 -4
  108. package/dist/src/channels/pipeline.js.map +1 -1
  109. package/dist/src/chat-commands/builtins/config.d.ts +4 -0
  110. package/dist/src/chat-commands/builtins/config.js +197 -0
  111. package/dist/src/chat-commands/builtins/config.js.map +1 -0
  112. package/dist/src/chat-commands/builtins/context.d.ts +4 -0
  113. package/dist/src/chat-commands/builtins/context.js +44 -0
  114. package/dist/src/chat-commands/builtins/context.js.map +1 -0
  115. package/dist/src/chat-commands/builtins/session.js +111 -0
  116. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  117. package/dist/src/chat-commands/builtins/thinking.js +49 -21
  118. package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
  119. package/dist/src/chat-commands/config-paths.d.ts +10 -0
  120. package/dist/src/chat-commands/config-paths.js +45 -0
  121. package/dist/src/chat-commands/config-paths.js.map +1 -0
  122. package/dist/src/chat-commands/config-value.d.ts +12 -0
  123. package/dist/src/chat-commands/config-value.js +53 -0
  124. package/dist/src/chat-commands/config-value.js.map +1 -0
  125. package/dist/src/chat-commands/context.d.ts +24 -1
  126. package/dist/src/chat-commands/context.js +41 -0
  127. package/dist/src/chat-commands/context.js.map +1 -1
  128. package/dist/src/chat-commands/index.d.ts +2 -0
  129. package/dist/src/chat-commands/index.js +5 -1
  130. package/dist/src/chat-commands/index.js.map +1 -1
  131. package/dist/src/chat-commands/types.d.ts +33 -1
  132. package/dist/src/cli/commands/agent/interactive.js +1 -1
  133. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  134. package/dist/src/cli/commands/agent.js +22 -10
  135. package/dist/src/cli/commands/agent.js.map +1 -1
  136. package/dist/src/cli/commands/auth.js.map +1 -1
  137. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  138. package/dist/src/cli/commands/extension.js +10 -0
  139. package/dist/src/cli/commands/extension.js.map +1 -1
  140. package/dist/src/cli/commands/init.js +3 -4
  141. package/dist/src/cli/commands/init.js.map +1 -1
  142. package/dist/src/cli/commands/session/utils.js.map +1 -1
  143. package/dist/src/cli/commands/update.d.ts +1 -0
  144. package/dist/src/cli/commands/update.js +171 -0
  145. package/dist/src/cli/commands/update.js.map +1 -0
  146. package/dist/src/cli/index.d.ts +1 -1
  147. package/dist/src/cli/index.js +3 -1
  148. package/dist/src/cli/index.js.map +1 -1
  149. package/dist/src/config/index.d.ts +1 -0
  150. package/dist/src/config/index.js +5 -4
  151. package/dist/src/config/index.js.map +1 -1
  152. package/dist/src/config/loader.js +1 -1
  153. package/dist/src/config/models-json.js +1 -1
  154. package/dist/src/config/paths.js.map +1 -1
  155. package/dist/src/config/profile.js +2 -2
  156. package/dist/src/config/runtime-overrides.d.ts +8 -0
  157. package/dist/src/config/runtime-overrides.js +40 -0
  158. package/dist/src/config/runtime-overrides.js.map +1 -0
  159. package/dist/src/config/schema.d.ts +35 -0
  160. package/dist/src/config/schema.js +19 -3
  161. package/dist/src/config/schema.js.map +1 -1
  162. package/dist/src/cron/executor.js +2 -2
  163. package/dist/src/cron/persistence.js +1 -1
  164. package/dist/src/cron/run-log-store.js +1 -1
  165. package/dist/src/extensions/health.js +1 -1
  166. package/dist/src/extensions/loader.d.ts +1 -1
  167. package/dist/src/extensions/loader.js +6 -9
  168. package/dist/src/extensions/loader.js.map +1 -1
  169. package/dist/src/extensions/lockfile.js +1 -1
  170. package/dist/src/extensions/sdk/index.js +6 -1
  171. package/dist/src/extensions/sdk/index.js.map +1 -0
  172. package/dist/src/gateway/agents-admin.js +2 -2
  173. package/dist/src/gateway/agents-admin.js.map +1 -1
  174. package/dist/src/gateway/hono/oauth.js +1 -1
  175. package/dist/src/gateway/hono/routes/config.js +1 -1
  176. package/dist/src/gateway/hono/routes/index.js +2 -0
  177. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  178. package/dist/src/gateway/hono/routes/models.js +64 -11
  179. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  180. package/dist/src/gateway/hono/routes/public-gateway.js +10 -0
  181. package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
  182. package/dist/src/gateway/hono/routes/update.d.ts +3 -0
  183. package/dist/src/gateway/hono/routes/update.js +141 -0
  184. package/dist/src/gateway/hono/routes/update.js.map +1 -0
  185. package/dist/src/gateway/hono/routes/workspace.js +84 -4
  186. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  187. package/dist/src/gateway/hono/sse.js +2 -2
  188. package/dist/src/gateway/service.d.ts +1 -0
  189. package/dist/src/gateway/service.js +16 -4
  190. package/dist/src/gateway/service.js.map +1 -1
  191. package/dist/src/gateway/workspace-fs-file-list.d.ts +5 -0
  192. package/dist/src/gateway/workspace-fs-file-list.js +56 -0
  193. package/dist/src/gateway/workspace-fs-file-list.js.map +1 -0
  194. package/dist/src/gateway/workspace-heartbeat-path.js +1 -1
  195. package/dist/src/gateway/workspace-ripgrep.d.ts +5 -0
  196. package/dist/src/gateway/workspace-ripgrep.js +88 -4
  197. package/dist/src/gateway/workspace-ripgrep.js.map +1 -1
  198. package/dist/src/infra/update-channels.d.ts +14 -0
  199. package/dist/src/infra/update-channels.js +30 -0
  200. package/dist/src/infra/update-channels.js.map +1 -0
  201. package/dist/src/infra/update-check.d.ts +53 -0
  202. package/dist/src/infra/update-check.js +155 -0
  203. package/dist/src/infra/update-check.js.map +1 -0
  204. package/dist/src/infra/update-runner.d.ts +18 -0
  205. package/dist/src/infra/update-runner.js +112 -0
  206. package/dist/src/infra/update-runner.js.map +1 -0
  207. package/dist/src/infra/update-startup.d.ts +20 -0
  208. package/dist/src/infra/update-startup.js +246 -0
  209. package/dist/src/infra/update-startup.js.map +1 -0
  210. package/dist/src/providers/extension-stream-bridge.d.ts +3 -0
  211. package/dist/src/providers/extension-stream-bridge.js +239 -0
  212. package/dist/src/providers/extension-stream-bridge.js.map +1 -0
  213. package/dist/src/providers/index.d.ts +7 -2
  214. package/dist/src/providers/index.js +77 -14
  215. package/dist/src/providers/index.js.map +1 -1
  216. package/dist/src/providers/model-registry.js +1 -1
  217. package/dist/src/providers/plugin-registry.js +92 -87
  218. package/dist/src/providers/plugin-registry.js.map +1 -1
  219. package/dist/src/session/chat-export.d.ts +5 -0
  220. package/dist/src/session/chat-export.js +35 -0
  221. package/dist/src/session/chat-export.js.map +1 -0
  222. package/dist/src/session/config-store.js +1 -1
  223. package/dist/src/session/manager.d.ts +1 -1
  224. package/dist/src/session/manager.js +2 -2
  225. package/dist/src/session/manager.js.map +1 -1
  226. package/dist/src/session/session-title.js +1 -1
  227. package/dist/src/session/store.d.ts +1 -1
  228. package/dist/src/session/store.js +5 -5
  229. package/dist/src/session/store.js.map +1 -1
  230. package/dist/src/utils/logger/audit.js +1 -1
  231. package/dist/src/utils/logger/log-store.js +1 -1
  232. package/dist/src/utils/logger/rotation.js +1 -1
  233. package/dist/src/voice/tts/audio.js +1 -1
  234. package/package.json +2 -1
  235. package/dist/gateway/static/root/assets/agents-BSNzJWbQ.js.map +0 -1
  236. package/dist/gateway/static/root/assets/attachment-load-DXcJLSWT.js +0 -1
  237. package/dist/gateway/static/root/assets/index-BXUJbteW.js.map +0 -1
  238. package/dist/gateway/static/root/assets/index-CQLMxWSA.css +0 -2
  239. package/dist/gateway/static/root/assets/page-header-store-DJHD9Ean.js +0 -2
  240. package/dist/gateway/static/root/assets/settings-page-B3QrJm-E.js.map +0 -1
  241. package/dist/gateway/static/root/assets/url-CtSqjF9J.js +0 -2
  242. package/dist/gateway/static/root/assets/url-CtSqjF9J.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"extension-provider-CO2jxBA9.js","names":[],"sources":["../../../../../packages/extension-ui-sdk/src/types.ts","../../../../../web/src/features/extensions/theme-bridge.ts","../../../../../web/src/features/extensions/extension-message-router.ts","../../../../../web/src/features/extensions/extension-provider.tsx"],"sourcesContent":["export enum ExtensionErrorCode {\n PermissionDenied = 4001,\n InvalidRequest = 4002,\n MethodNotFound = 4003,\n InternalError = 4004,\n Timeout = 4005,\n ExtensionNotFound = 4006,\n RateLimited = 4007,\n}\n\nexport interface ThemeInfo {\n mode: 'light' | 'dark';\n tokens: Record<string, string>;\n fontFamily?: string;\n fontFamilyMono?: string;\n}\n\nexport interface ExtensionRequest {\n source: 'xopc-extension';\n extensionId: string;\n type: 'request';\n requestId: string;\n method: string;\n params?: unknown;\n}\n\nexport interface ExtensionEventMessage {\n source: 'xopc-extension';\n extensionId: string;\n type: 'event';\n event: string;\n data?: unknown;\n}\n\nexport interface HostInit {\n source: 'xopc-host';\n type: 'init';\n extensionId: string;\n permissions: string[];\n theme: ThemeInfo;\n locale: string;\n}\n\nexport interface HostResponse {\n source: 'xopc-host';\n type: 'response';\n requestId: string;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\nexport interface HostEventMessage {\n source: 'xopc-host';\n type: 'event';\n event: string;\n data?: unknown;\n}\n\nexport type HostToExtensionMessage = HostInit | HostResponse | HostEventMessage;\nexport type ExtensionToHostMessage = ExtensionRequest | ExtensionEventMessage;\n\nexport type StreamHandler = (payload: unknown) => void;\n\nexport interface ExtensionClient {\n whenReady(): Promise<void>;\n theme: {\n getTheme(): Promise<ThemeInfo>;\n onThemeChange(handler: (t: ThemeInfo) => void): () => void;\n };\n agent: {\n sendMessage(\n message: string,\n options?: { sessionKey?: string; newSession?: boolean },\n ): Promise<{ sessionKey: string }>;\n onStreamEvent(sessionKey: string, handler: StreamHandler): () => void;\n };\n session: {\n listSessions(): Promise<unknown[]>;\n navigateToSession(sessionKey: string): Promise<void>;\n };\n config: {\n getExtensionConfig<T = Record<string, unknown>>(): Promise<T>;\n setExtensionConfig(patch: Record<string, unknown>): Promise<void>;\n };\n storage: {\n get<T = unknown>(key: string): Promise<T | undefined>;\n set(key: string, value: unknown): Promise<void>;\n remove(key: string): Promise<void>;\n keys(): Promise<string[]>;\n };\n ui: {\n resize(height: number): void;\n showNotification(options: {\n type?: 'success' | 'error' | 'info';\n title: string;\n message?: string;\n }): Promise<void>;\n closePanel(): void;\n navigate(path: string): Promise<void>;\n /** Chat/tool widget iframe: host sends the tool result via `widget.data` after load. */\n onWidgetResult(handler: (data: unknown) => void): () => void;\n };\n events: {\n emit(event: string, data?: unknown): void;\n on(event: string, handler: (data: unknown) => void): () => void;\n };\n onDispose(handler: () => void): () => void;\n onDidChangeVisibility(handler: (visible: boolean) => void): () => void;\n}\n","import type { ThemeInfo } from '@xopcai/extension-ui-sdk';\n\nconst THEME_TOKEN_NAMES = [\n '--color-surface-base',\n '--color-surface-panel',\n '--color-surface-hover',\n '--color-fg',\n '--color-fg-muted',\n '--color-fg-subtle',\n '--color-accent',\n '--color-accent-hover',\n '--color-accent-soft',\n '--color-edge',\n '--color-edge-subtle',\n '--color-danger',\n '--color-success',\n '--color-warning',\n '--radius-sm',\n '--radius-lg',\n '--radius-xl',\n];\n\nexport function buildThemeInfo(mode: 'light' | 'dark'): ThemeInfo {\n const computedStyle = getComputedStyle(document.documentElement);\n const tokens: Record<string, string> = {};\n for (const name of THEME_TOKEN_NAMES) {\n const value = computedStyle.getPropertyValue(name).trim();\n if (value) tokens[name] = value;\n }\n return {\n mode,\n tokens,\n fontFamily: computedStyle.getPropertyValue('font-family').trim(),\n fontFamilyMono: computedStyle.getPropertyValue('--font-mono').trim(),\n };\n}\n","import { ExtensionErrorCode, type ThemeInfo } from '@xopcai/extension-ui-sdk';\n\nimport { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { buildThemeInfo } from './theme-bridge';\n\nexport type MethodHandler = (extensionId: string, params: unknown) => Promise<unknown>;\n\nconst METHOD_PERMISSION_MAP: Record<string, string | undefined> = {\n 'agent.sendMessage': 'agent.send',\n 'session.list': 'session.read',\n 'session.navigate': 'session.read',\n 'config.get': 'config.read',\n 'config.set': 'config.write',\n 'storage.get': 'storage',\n 'storage.set': 'storage',\n 'storage.remove': 'storage',\n 'storage.keys': 'storage',\n 'ui.notification': 'notification',\n 'ui.navigate': 'theme',\n 'theme.get': 'theme',\n};\n\ntype ExtensionHostMessage =\n | {\n source: 'xopc-extension';\n extensionId: string;\n type: 'request';\n requestId: string;\n method: string;\n params?: unknown;\n }\n | {\n source: 'xopc-extension';\n extensionId: string;\n type: 'event';\n event: string;\n data?: unknown;\n };\n\nexport class ExtensionMessageRouter {\n private iframes = new Map<string, HTMLIFrameElement>();\n /** Incoming iframe → extensionId (handles contentWindow ready after first register; also disambiguates identity). */\n private byContentWindow = new WeakMap<\n Window,\n { extensionId: string; iframe: HTMLIFrameElement }\n >();\n private handlers = new Map<string, MethodHandler>();\n private extensionPermissions = new Map<string, Set<string>>();\n private eventSubscribers = new Map<string, Set<(e: { event: string; data?: unknown }) => void>>();\n /** extensionId → sessionKeys subscribed for agent stream forwarding */\n private agentStreamSubscriptions = new Map<string, Set<string>>();\n private boundListener = (ev: MessageEvent) => {\n void this.onWindowMessage(ev);\n };\n\n constructor() {\n window.addEventListener('message', this.boundListener);\n }\n\n dispose(): void {\n window.removeEventListener('message', this.boundListener);\n this.iframes.clear();\n this.handlers.clear();\n this.extensionPermissions.clear();\n this.eventSubscribers.clear();\n this.agentStreamSubscriptions.clear();\n }\n\n registerIframe(extensionId: string, iframe: HTMLIFrameElement, permissions: string[]): void {\n const prev = this.iframes.get(extensionId);\n if (prev && prev !== iframe && prev.contentWindow) {\n this.byContentWindow.delete(prev.contentWindow);\n }\n this.iframes.set(extensionId, iframe);\n this.extensionPermissions.set(extensionId, new Set(permissions));\n this.rememberIframeWindow(extensionId, iframe);\n }\n\n unregisterIframe(extensionId: string): void {\n const iframe = this.iframes.get(extensionId);\n if (iframe?.contentWindow) {\n this.byContentWindow.delete(iframe.contentWindow);\n }\n this.iframes.delete(extensionId);\n this.extensionPermissions.delete(extensionId);\n this.agentStreamSubscriptions.delete(extensionId);\n }\n\n private rememberIframeWindow(extensionId: string, iframe: HTMLIFrameElement): void {\n const cw = iframe.contentWindow;\n if (cw) {\n this.byContentWindow.set(cw, { extensionId, iframe });\n }\n }\n\n subscribeAgentStream(extensionId: string, sessionKey: string): void {\n let sessions = this.agentStreamSubscriptions.get(extensionId);\n if (!sessions) {\n sessions = new Set();\n this.agentStreamSubscriptions.set(extensionId, sessions);\n }\n sessions.add(sessionKey);\n }\n\n unsubscribeAgentStream(extensionId: string, sessionKey: string): void {\n this.agentStreamSubscriptions.get(extensionId)?.delete(sessionKey);\n }\n\n forwardAgentStreamEvent(sessionKey: string, event: unknown): void {\n for (const [extensionId, sessions] of this.agentStreamSubscriptions) {\n if (sessions.has(sessionKey)) {\n this.sendEvent(extensionId, `agent.stream.${sessionKey}`, event);\n }\n }\n }\n\n /**\n * Broadcast a fire-and-forget event from one extension to all others (`ext.{name}` on the wire).\n */\n broadcastExtensionEvent(sourceExtensionId: string, bareName: string, data?: unknown): void {\n const outbound = bareName.startsWith('ext.') ? bareName : `ext.${bareName}`;\n for (const [extensionId] of this.iframes) {\n if (extensionId !== sourceExtensionId) {\n this.sendEvent(extensionId, outbound, data);\n }\n }\n }\n\n private handleExtensionEvent(extensionId: string, event: string, data: unknown): void {\n if (event.startsWith('ext.')) {\n const rest = event.slice(4);\n this.broadcastExtensionEvent(extensionId, rest, data);\n return;\n }\n if (event === 'agent.subscribe' || event === 'agent.unsubscribe') {\n const perms = this.extensionPermissions.get(extensionId) ?? new Set<string>();\n if (!perms.has('agent.subscribe')) return;\n const { sessionKey } = (data ?? {}) as { sessionKey?: string };\n if (typeof sessionKey !== 'string' || !sessionKey.trim()) return;\n const sk = sessionKey.trim();\n if (event === 'agent.subscribe') this.subscribeAgentStream(extensionId, sk);\n else this.unsubscribeAgentStream(extensionId, sk);\n }\n }\n\n registerMethod(method: string, handler: MethodHandler): void {\n this.handlers.set(method, handler);\n }\n\n subscribeExtensionEvents(\n extensionId: string,\n fn: (e: { event: string; data?: unknown }) => void,\n ): () => void {\n let subscribers = this.eventSubscribers.get(extensionId);\n if (!subscribers) {\n subscribers = new Set();\n this.eventSubscribers.set(extensionId, subscribers);\n }\n subscribers.add(fn);\n return () => {\n subscribers.delete(fn);\n if (subscribers.size === 0) {\n this.eventSubscribers.delete(extensionId);\n }\n };\n }\n\n sendInit(extensionId: string, theme: ThemeInfo, locale: string): void {\n const iframe = this.iframes.get(extensionId);\n if (!iframe?.contentWindow) return;\n this.rememberIframeWindow(extensionId, iframe);\n const permissions = [...(this.extensionPermissions.get(extensionId) ?? [])];\n iframe.contentWindow.postMessage(\n {\n source: 'xopc-host',\n type: 'init',\n extensionId,\n permissions,\n theme,\n locale,\n },\n '*',\n );\n }\n\n sendEvent(extensionId: string, event: string, data?: unknown): void {\n const iframe = this.iframes.get(extensionId);\n if (!iframe?.contentWindow) return;\n iframe.contentWindow.postMessage(\n {\n source: 'xopc-host',\n type: 'event',\n event,\n data,\n },\n '*',\n );\n }\n\n broadcastEvent(event: string, data?: unknown): void {\n for (const [, iframe] of this.iframes) {\n iframe.contentWindow?.postMessage(\n {\n source: 'xopc-host',\n type: 'event',\n event,\n data,\n },\n '*',\n );\n }\n }\n\n /** Prefer `iframe.contentWindow`; if null (rare), fall back to the request's `event.source`. */\n private postResponse(\n iframe: HTMLIFrameElement,\n event: MessageEvent | undefined,\n requestId: string,\n result?: unknown,\n error?: { code: number; message: string },\n ): void {\n const target =\n iframe.contentWindow ??\n (event?.source instanceof Window ? event.source : null);\n const payload = {\n source: 'xopc-host' as const,\n type: 'response' as const,\n requestId,\n result,\n error,\n };\n if (!target) {\n return;\n }\n target.postMessage(payload, '*');\n }\n\n private isTrustedExtensionSource(iframe: HTMLIFrameElement, ev: MessageEvent): boolean {\n if (ev.source === null) {\n // Sandboxed iframes (no allow-same-origin) may report a null source.\n return true;\n }\n const cw = iframe.contentWindow;\n if (ev.source === cw) {\n return true;\n }\n // Some environments do not keep `===` identity between postMessage `source`\n // and `iframe.contentWindow`; `frameElement` still ties the window to this iframe.\n if (cw && typeof Window !== 'undefined' && ev.source instanceof Window) {\n try {\n return ev.source.frameElement === iframe;\n } catch {\n /* cross-origin access */\n }\n }\n return false;\n }\n\n private async onWindowMessage(event: MessageEvent) {\n const msg = event.data as ExtensionHostMessage | undefined;\n if (!msg || msg.source !== 'xopc-extension') return;\n\n let iframe: HTMLIFrameElement | undefined;\n let effectiveExtensionId = msg.extensionId;\n\n if (event.source instanceof Window) {\n const reg = this.byContentWindow.get(event.source);\n if (reg) {\n iframe = reg.iframe;\n effectiveExtensionId = reg.extensionId;\n }\n }\n\n if (!iframe) {\n iframe = this.iframes.get(msg.extensionId);\n effectiveExtensionId = msg.extensionId;\n }\n\n if (!iframe) {\n return;\n }\n\n const trustedByWindow =\n event.source instanceof Window && this.byContentWindow.has(event.source);\n\n if (!trustedByWindow && !this.isTrustedExtensionSource(iframe, event)) {\n return;\n }\n\n if (msg.type === 'event') {\n this.handleExtensionEvent(effectiveExtensionId, msg.event, msg.data);\n const subs = this.eventSubscribers.get(effectiveExtensionId);\n if (subs) {\n const payload = { event: msg.event, data: msg.data };\n for (const fn of subs) {\n try {\n fn(payload);\n } catch {\n /* ignore */\n }\n }\n }\n return;\n }\n\n if (msg.type !== 'request') return;\n\n const { requestId, method, params } = msg;\n\n const handler = this.handlers.get(method);\n if (!handler) {\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.MethodNotFound,\n message: `Unknown method: ${method}`,\n });\n return;\n }\n\n const required = METHOD_PERMISSION_MAP[method];\n const perms = this.extensionPermissions.get(effectiveExtensionId) ?? new Set<string>();\n if (required && !perms.has(required)) {\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.PermissionDenied,\n message: `Missing permission: ${required}`,\n });\n return;\n }\n\n try {\n const result = await handler(effectiveExtensionId, params);\n this.postResponse(iframe, event, requestId, result);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.InternalError,\n message,\n });\n }\n }\n}\n\nexport function registerBuiltinMethods(router: ExtensionMessageRouter): void {\n router.registerMethod('theme.get', async () =>\n buildThemeInfo(useThemeStore.getState().resolved),\n );\n\n router.registerMethod('ui.navigate', async (_extensionId, params) => {\n const path =\n params && typeof params === 'object' && params !== null && 'path' in params\n ? String((params as { path?: string }).path ?? '')\n : '';\n if (path) {\n window.dispatchEvent(new CustomEvent('extension-navigate', { detail: { path } }));\n }\n });\n\n router.registerMethod('ui.notification', async (_extensionId, params) => {\n window.dispatchEvent(new CustomEvent('extension-notification', { detail: params }));\n });\n\n router.registerMethod('session.navigate', async (_extensionId, params) => {\n const sessionKey =\n params && typeof params === 'object' && params !== null && 'sessionKey' in params\n ? String((params as { sessionKey?: string }).sessionKey ?? '')\n : '';\n if (sessionKey) {\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey }, bubbles: true }),\n );\n }\n });\n\n router.registerMethod('session.list', async () => {\n const response = await apiFetch(apiUrl('/api/sessions'));\n if (!response.ok) throw new Error(`Failed to list sessions: ${response.status}`);\n const data = (await response.json()) as {\n items?: Array<{\n key: string;\n name?: string;\n updatedAt?: string;\n lastAccessedAt?: string;\n messageCount?: number;\n }>;\n };\n return (data.items ?? []).map((s) => ({\n sessionKey: s.key,\n title: s.name,\n lastMessageAt: s.updatedAt ?? s.lastAccessedAt,\n messageCount: s.messageCount,\n }));\n });\n\n router.registerMethod('agent.sendMessage', async (_extensionId, params) => {\n const { message, sessionKey, newSession } = params as {\n message: string;\n sessionKey?: string;\n newSession?: boolean;\n };\n const response = await apiFetch(apiUrl('/api/agent'), {\n method: 'POST',\n headers: { Accept: 'application/json' },\n body: JSON.stringify({\n message,\n channel: 'webchat',\n sessionKey: newSession ? undefined : sessionKey,\n newSession: Boolean(newSession),\n }),\n });\n if (!response.ok) throw new Error(`Agent request failed: ${response.status}`);\n const data = (await response.json()) as {\n payload?: { sessionKey?: string; key?: string };\n sessionKey?: string;\n };\n const fromPayload = data.payload?.sessionKey ?? data.payload?.key;\n return { sessionKey: fromPayload ?? data.sessionKey ?? sessionKey ?? '' };\n });\n\n router.registerMethod('config.get', async (extensionId) => {\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/config`));\n if (!response.ok) throw new Error(`Failed to get config: ${response.status}`);\n return response.json();\n });\n\n router.registerMethod('config.set', async (extensionId, params) => {\n const patch =\n params && typeof params === 'object' && params !== null && !Array.isArray(params)\n ? (params as Record<string, unknown>)\n : {};\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/config`), {\n method: 'PATCH',\n body: JSON.stringify(patch),\n });\n if (!response.ok) throw new Error(`Failed to set config: ${response.status}`);\n });\n\n router.registerMethod('storage.get', async (extensionId, params) => {\n const key =\n params && typeof params === 'object' && params !== null && 'key' in params\n ? String((params as { key?: string }).key ?? '')\n : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n );\n if (response.status === 404) return undefined;\n if (!response.ok) throw new Error(`Failed to get storage key: ${response.status}`);\n const data = (await response.json()) as { value: unknown };\n return data.value;\n });\n\n router.registerMethod('storage.set', async (extensionId, params) => {\n const raw = params as { key?: string; value?: unknown } | undefined;\n const key = raw && typeof raw.key === 'string' ? raw.key : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n { method: 'PUT', body: JSON.stringify({ value: raw?.value }) },\n );\n if (!response.ok) throw new Error(`Failed to set storage key: ${response.status}`);\n });\n\n router.registerMethod('storage.remove', async (extensionId, params) => {\n const key =\n params && typeof params === 'object' && params !== null && 'key' in params\n ? String((params as { key?: string }).key ?? '')\n : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n { method: 'DELETE' },\n );\n if (response.status === 404) return;\n if (!response.ok) throw new Error(`Failed to remove storage key: ${response.status}`);\n });\n\n router.registerMethod('storage.keys', async (extensionId) => {\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage`));\n if (!response.ok) throw new Error(`Failed to list storage keys: ${response.status}`);\n const data = (await response.json()) as { keys?: string[] };\n return data.keys ?? [];\n });\n}\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport useSWR from 'swr';\n\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { ExtensionMessageRouter, registerBuiltinMethods } from './extension-message-router';\nimport type { ExtensionApiRow, ExtensionsListResponse } from './types';\nimport { buildThemeInfo } from './theme-bridge';\n\ntype Ctx = {\n router: ExtensionMessageRouter;\n extensions: ExtensionApiRow[];\n loading: boolean;\n};\n\nconst ExtensionContext = createContext<Ctx | null>(null);\n\nexport function ExtensionProvider({ children }: { children: React.ReactNode }) {\n const routerRef = useRef<ExtensionMessageRouter | null>(null);\n if (!routerRef.current) {\n const newRouter = new ExtensionMessageRouter();\n registerBuiltinMethods(newRouter);\n routerRef.current = newRouter;\n }\n const router = routerRef.current;\n const hasToken = useGatewayStore((s) => Boolean(s.token));\n const { data, isLoading } = useSWR(\n hasToken ? 'gateway-extensions-list' : null,\n () => fetchJson<ExtensionsListResponse>(apiUrl('/api/extensions')),\n { revalidateOnFocus: false },\n );\n\n const extensions = data?.extensions ?? [];\n const resolved = useThemeStore((s) => s.resolved);\n\n const handleAgentStreamEvent = useCallback(\n (event: Event) => {\n const detail = (event as CustomEvent<{ sessionKey?: string; event?: unknown }>).detail;\n if (!detail?.sessionKey) return;\n router.forwardAgentStreamEvent(detail.sessionKey, detail.event ?? detail);\n },\n [router],\n );\n\n useEffect(() => {\n window.addEventListener('agent-stream-event', handleAgentStreamEvent as EventListener);\n return () => {\n window.removeEventListener('agent-stream-event', handleAgentStreamEvent as EventListener);\n };\n }, [handleAgentStreamEvent]);\n\n useEffect(() => {\n const theme = buildThemeInfo(resolved);\n router.broadcastEvent('theme.changed', theme);\n }, [resolved, router]);\n\n const routerForCleanupRef = useRef(router);\n routerForCleanupRef.current = router;\n useEffect(\n () => () => {\n routerForCleanupRef.current.dispose();\n // React StrictMode (dev) invokes this cleanup, then remounts. `useRef` survives,\n // so we must clear the ref or the next render would reuse a disposed router\n // (no `window` message listener — extension requests time out).\n routerRef.current = null;\n },\n [],\n );\n\n const value = useMemo(\n () => ({ router, extensions, loading: isLoading }),\n [router, extensions, isLoading],\n );\n\n return <ExtensionContext.Provider value={value}>{children}</ExtensionContext.Provider>;\n}\n\nexport function useExtensionRouter(): ExtensionMessageRouter {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensionRouter must be used within ExtensionProvider');\n }\n return ctx.router;\n}\n\nexport function useExtensions(): ExtensionApiRow[] {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensions must be used within ExtensionProvider');\n }\n return ctx.extensions;\n}\n\n/** Loaded in the gateway process (tools/hooks) or marked to load after restart. */\nfunction extensionUiUnlocked(e: ExtensionApiRow): boolean {\n return e.active || e.activationEligible === true;\n}\n\n/** Manifest declares iframe surfaces (served from disk); show nav/routes even when Node side is not active yet. */\nfunction manifestDeclaresGatewayContributions(e: ExtensionApiRow): boolean {\n const c = e.ui?.contributions;\n if (!c) return false;\n return (\n (Array.isArray(c.pages) && c.pages.length > 0) ||\n (Array.isArray(c.settingsPanels) && c.settingsPanels.length > 0) ||\n (Array.isArray(c.chatWidgets) && c.chatWidgets.length > 0)\n );\n}\n\n/** Used by Apps detail links and {@link useUiExtensions}. */\nexport function extensionExposesGatewayShellUi(e: ExtensionApiRow): boolean {\n if (!e.hasUi) return false;\n // Extension must be enabled (active or scheduled to activate after restart) before\n // its UI contributions appear in the shell. `manifestDeclaresGatewayContributions`\n // only determines whether the iframe surfaces are shown *while* the Node-side is still\n // starting up — it must not override a deliberate disable action by the user.\n if (!extensionUiUnlocked(e)) return false;\n return manifestDeclaresGatewayContributions(e);\n}\n\nexport function useUiExtensions(): ExtensionApiRow[] {\n const list = useExtensions();\n return useMemo(() => list.filter(extensionExposesGatewayShellUi), [list]);\n}\n\nexport function useExtensionsLoading(): boolean {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensionsLoading must be used within ExtensionProvider');\n }\n return ctx.loading;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extension-provider-DZCZgQE2.js","names":[],"sources":["../../../../../packages/extension-ui-sdk/src/types.ts","../../../../../web/src/features/extensions/theme-bridge.ts","../../../../../web/src/features/extensions/extension-message-router.ts","../../../../../web/src/features/extensions/extension-provider.tsx"],"sourcesContent":["export enum ExtensionErrorCode {\n PermissionDenied = 4001,\n InvalidRequest = 4002,\n MethodNotFound = 4003,\n InternalError = 4004,\n Timeout = 4005,\n ExtensionNotFound = 4006,\n RateLimited = 4007,\n}\n\nexport interface ThemeInfo {\n mode: 'light' | 'dark';\n tokens: Record<string, string>;\n fontFamily?: string;\n fontFamilyMono?: string;\n}\n\nexport interface ExtensionRequest {\n source: 'xopc-extension';\n extensionId: string;\n type: 'request';\n requestId: string;\n method: string;\n params?: unknown;\n}\n\nexport interface ExtensionEventMessage {\n source: 'xopc-extension';\n extensionId: string;\n type: 'event';\n event: string;\n data?: unknown;\n}\n\nexport interface HostInit {\n source: 'xopc-host';\n type: 'init';\n extensionId: string;\n permissions: string[];\n theme: ThemeInfo;\n locale: string;\n}\n\nexport interface HostResponse {\n source: 'xopc-host';\n type: 'response';\n requestId: string;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\nexport interface HostEventMessage {\n source: 'xopc-host';\n type: 'event';\n event: string;\n data?: unknown;\n}\n\nexport type HostToExtensionMessage = HostInit | HostResponse | HostEventMessage;\nexport type ExtensionToHostMessage = ExtensionRequest | ExtensionEventMessage;\n\nexport type StreamHandler = (payload: unknown) => void;\n\nexport interface ExtensionClient {\n whenReady(): Promise<void>;\n theme: {\n getTheme(): Promise<ThemeInfo>;\n onThemeChange(handler: (t: ThemeInfo) => void): () => void;\n };\n agent: {\n sendMessage(\n message: string,\n options?: { sessionKey?: string; newSession?: boolean },\n ): Promise<{ sessionKey: string }>;\n onStreamEvent(sessionKey: string, handler: StreamHandler): () => void;\n };\n session: {\n listSessions(): Promise<unknown[]>;\n navigateToSession(sessionKey: string): Promise<void>;\n };\n config: {\n getExtensionConfig<T = Record<string, unknown>>(): Promise<T>;\n setExtensionConfig(patch: Record<string, unknown>): Promise<void>;\n };\n storage: {\n get<T = unknown>(key: string): Promise<T | undefined>;\n set(key: string, value: unknown): Promise<void>;\n remove(key: string): Promise<void>;\n keys(): Promise<string[]>;\n };\n ui: {\n resize(height: number): void;\n showNotification(options: {\n type?: 'success' | 'error' | 'info';\n title: string;\n message?: string;\n }): Promise<void>;\n closePanel(): void;\n navigate(path: string): Promise<void>;\n /** Chat/tool widget iframe: host sends the tool result via `widget.data` after load. */\n onWidgetResult(handler: (data: unknown) => void): () => void;\n };\n events: {\n emit(event: string, data?: unknown): void;\n on(event: string, handler: (data: unknown) => void): () => void;\n };\n onDispose(handler: () => void): () => void;\n onDidChangeVisibility(handler: (visible: boolean) => void): () => void;\n}\n","import type { ThemeInfo } from '@xopcai/extension-ui-sdk';\n\nconst THEME_TOKEN_NAMES = [\n '--color-surface-base',\n '--color-surface-panel',\n '--color-surface-hover',\n '--color-fg',\n '--color-fg-muted',\n '--color-fg-subtle',\n '--color-accent',\n '--color-accent-hover',\n '--color-accent-soft',\n '--color-edge',\n '--color-edge-subtle',\n '--color-danger',\n '--color-success',\n '--color-warning',\n '--radius-sm',\n '--radius-lg',\n '--radius-xl',\n];\n\nexport function buildThemeInfo(mode: 'light' | 'dark'): ThemeInfo {\n const computedStyle = getComputedStyle(document.documentElement);\n const tokens: Record<string, string> = {};\n for (const name of THEME_TOKEN_NAMES) {\n const value = computedStyle.getPropertyValue(name).trim();\n if (value) tokens[name] = value;\n }\n return {\n mode,\n tokens,\n fontFamily: computedStyle.getPropertyValue('font-family').trim(),\n fontFamilyMono: computedStyle.getPropertyValue('--font-mono').trim(),\n };\n}\n","import { ExtensionErrorCode, type ThemeInfo } from '@xopcai/extension-ui-sdk';\n\nimport { apiFetch } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { buildThemeInfo } from './theme-bridge';\n\nexport type MethodHandler = (extensionId: string, params: unknown) => Promise<unknown>;\n\nconst METHOD_PERMISSION_MAP: Record<string, string | undefined> = {\n 'agent.sendMessage': 'agent.send',\n 'session.list': 'session.read',\n 'session.navigate': 'session.read',\n 'config.get': 'config.read',\n 'config.set': 'config.write',\n 'storage.get': 'storage',\n 'storage.set': 'storage',\n 'storage.remove': 'storage',\n 'storage.keys': 'storage',\n 'ui.notification': 'notification',\n 'ui.navigate': 'theme',\n 'theme.get': 'theme',\n};\n\ntype ExtensionHostMessage =\n | {\n source: 'xopc-extension';\n extensionId: string;\n type: 'request';\n requestId: string;\n method: string;\n params?: unknown;\n }\n | {\n source: 'xopc-extension';\n extensionId: string;\n type: 'event';\n event: string;\n data?: unknown;\n };\n\nexport class ExtensionMessageRouter {\n private iframes = new Map<string, HTMLIFrameElement>();\n /** Incoming iframe → extensionId (handles contentWindow ready after first register; also disambiguates identity). */\n private byContentWindow = new WeakMap<\n Window,\n { extensionId: string; iframe: HTMLIFrameElement }\n >();\n private handlers = new Map<string, MethodHandler>();\n private extensionPermissions = new Map<string, Set<string>>();\n private eventSubscribers = new Map<string, Set<(e: { event: string; data?: unknown }) => void>>();\n /** extensionId → sessionKeys subscribed for agent stream forwarding */\n private agentStreamSubscriptions = new Map<string, Set<string>>();\n private boundListener = (ev: MessageEvent) => {\n void this.onWindowMessage(ev);\n };\n\n constructor() {\n window.addEventListener('message', this.boundListener);\n }\n\n dispose(): void {\n window.removeEventListener('message', this.boundListener);\n this.iframes.clear();\n this.handlers.clear();\n this.extensionPermissions.clear();\n this.eventSubscribers.clear();\n this.agentStreamSubscriptions.clear();\n }\n\n registerIframe(extensionId: string, iframe: HTMLIFrameElement, permissions: string[]): void {\n const prev = this.iframes.get(extensionId);\n if (prev && prev !== iframe && prev.contentWindow) {\n this.byContentWindow.delete(prev.contentWindow);\n }\n this.iframes.set(extensionId, iframe);\n this.extensionPermissions.set(extensionId, new Set(permissions));\n this.rememberIframeWindow(extensionId, iframe);\n }\n\n unregisterIframe(extensionId: string): void {\n const iframe = this.iframes.get(extensionId);\n if (iframe?.contentWindow) {\n this.byContentWindow.delete(iframe.contentWindow);\n }\n this.iframes.delete(extensionId);\n this.extensionPermissions.delete(extensionId);\n this.agentStreamSubscriptions.delete(extensionId);\n }\n\n private rememberIframeWindow(extensionId: string, iframe: HTMLIFrameElement): void {\n const cw = iframe.contentWindow;\n if (cw) {\n this.byContentWindow.set(cw, { extensionId, iframe });\n }\n }\n\n subscribeAgentStream(extensionId: string, sessionKey: string): void {\n let sessions = this.agentStreamSubscriptions.get(extensionId);\n if (!sessions) {\n sessions = new Set();\n this.agentStreamSubscriptions.set(extensionId, sessions);\n }\n sessions.add(sessionKey);\n }\n\n unsubscribeAgentStream(extensionId: string, sessionKey: string): void {\n this.agentStreamSubscriptions.get(extensionId)?.delete(sessionKey);\n }\n\n forwardAgentStreamEvent(sessionKey: string, event: unknown): void {\n for (const [extensionId, sessions] of this.agentStreamSubscriptions) {\n if (sessions.has(sessionKey)) {\n this.sendEvent(extensionId, `agent.stream.${sessionKey}`, event);\n }\n }\n }\n\n /**\n * Broadcast a fire-and-forget event from one extension to all others (`ext.{name}` on the wire).\n */\n broadcastExtensionEvent(sourceExtensionId: string, bareName: string, data?: unknown): void {\n const outbound = bareName.startsWith('ext.') ? bareName : `ext.${bareName}`;\n for (const [extensionId] of this.iframes) {\n if (extensionId !== sourceExtensionId) {\n this.sendEvent(extensionId, outbound, data);\n }\n }\n }\n\n private handleExtensionEvent(extensionId: string, event: string, data: unknown): void {\n if (event.startsWith('ext.')) {\n const rest = event.slice(4);\n this.broadcastExtensionEvent(extensionId, rest, data);\n return;\n }\n if (event === 'agent.subscribe' || event === 'agent.unsubscribe') {\n const perms = this.extensionPermissions.get(extensionId) ?? new Set<string>();\n if (!perms.has('agent.subscribe')) return;\n const { sessionKey } = (data ?? {}) as { sessionKey?: string };\n if (typeof sessionKey !== 'string' || !sessionKey.trim()) return;\n const sk = sessionKey.trim();\n if (event === 'agent.subscribe') this.subscribeAgentStream(extensionId, sk);\n else this.unsubscribeAgentStream(extensionId, sk);\n }\n }\n\n registerMethod(method: string, handler: MethodHandler): void {\n this.handlers.set(method, handler);\n }\n\n subscribeExtensionEvents(\n extensionId: string,\n fn: (e: { event: string; data?: unknown }) => void,\n ): () => void {\n let subscribers = this.eventSubscribers.get(extensionId);\n if (!subscribers) {\n subscribers = new Set();\n this.eventSubscribers.set(extensionId, subscribers);\n }\n subscribers.add(fn);\n return () => {\n subscribers.delete(fn);\n if (subscribers.size === 0) {\n this.eventSubscribers.delete(extensionId);\n }\n };\n }\n\n sendInit(extensionId: string, theme: ThemeInfo, locale: string): void {\n const iframe = this.iframes.get(extensionId);\n if (!iframe?.contentWindow) return;\n this.rememberIframeWindow(extensionId, iframe);\n const permissions = [...(this.extensionPermissions.get(extensionId) ?? [])];\n iframe.contentWindow.postMessage(\n {\n source: 'xopc-host',\n type: 'init',\n extensionId,\n permissions,\n theme,\n locale,\n },\n '*',\n );\n }\n\n sendEvent(extensionId: string, event: string, data?: unknown): void {\n const iframe = this.iframes.get(extensionId);\n if (!iframe?.contentWindow) return;\n iframe.contentWindow.postMessage(\n {\n source: 'xopc-host',\n type: 'event',\n event,\n data,\n },\n '*',\n );\n }\n\n broadcastEvent(event: string, data?: unknown): void {\n for (const [, iframe] of this.iframes) {\n iframe.contentWindow?.postMessage(\n {\n source: 'xopc-host',\n type: 'event',\n event,\n data,\n },\n '*',\n );\n }\n }\n\n /** Prefer `iframe.contentWindow`; if null (rare), fall back to the request's `event.source`. */\n private postResponse(\n iframe: HTMLIFrameElement,\n event: MessageEvent | undefined,\n requestId: string,\n result?: unknown,\n error?: { code: number; message: string },\n ): void {\n const target =\n iframe.contentWindow ??\n (event?.source instanceof Window ? event.source : null);\n const payload = {\n source: 'xopc-host' as const,\n type: 'response' as const,\n requestId,\n result,\n error,\n };\n if (!target) {\n return;\n }\n target.postMessage(payload, '*');\n }\n\n private isTrustedExtensionSource(iframe: HTMLIFrameElement, ev: MessageEvent): boolean {\n if (ev.source === null) {\n // Sandboxed iframes (no allow-same-origin) may report a null source.\n return true;\n }\n const cw = iframe.contentWindow;\n if (ev.source === cw) {\n return true;\n }\n // Some environments do not keep `===` identity between postMessage `source`\n // and `iframe.contentWindow`; `frameElement` still ties the window to this iframe.\n if (cw && typeof Window !== 'undefined' && ev.source instanceof Window) {\n try {\n return ev.source.frameElement === iframe;\n } catch {\n /* cross-origin access */\n }\n }\n return false;\n }\n\n private async onWindowMessage(event: MessageEvent) {\n const msg = event.data as ExtensionHostMessage | undefined;\n if (!msg || msg.source !== 'xopc-extension') return;\n\n let iframe: HTMLIFrameElement | undefined;\n let effectiveExtensionId = msg.extensionId;\n\n if (event.source instanceof Window) {\n const reg = this.byContentWindow.get(event.source);\n if (reg) {\n iframe = reg.iframe;\n effectiveExtensionId = reg.extensionId;\n }\n }\n\n if (!iframe) {\n iframe = this.iframes.get(msg.extensionId);\n effectiveExtensionId = msg.extensionId;\n }\n\n if (!iframe) {\n return;\n }\n\n const trustedByWindow =\n event.source instanceof Window && this.byContentWindow.has(event.source);\n\n if (!trustedByWindow && !this.isTrustedExtensionSource(iframe, event)) {\n return;\n }\n\n if (msg.type === 'event') {\n this.handleExtensionEvent(effectiveExtensionId, msg.event, msg.data);\n const subs = this.eventSubscribers.get(effectiveExtensionId);\n if (subs) {\n const payload = { event: msg.event, data: msg.data };\n for (const fn of subs) {\n try {\n fn(payload);\n } catch {\n /* ignore */\n }\n }\n }\n return;\n }\n\n if (msg.type !== 'request') return;\n\n const { requestId, method, params } = msg;\n\n const handler = this.handlers.get(method);\n if (!handler) {\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.MethodNotFound,\n message: `Unknown method: ${method}`,\n });\n return;\n }\n\n const required = METHOD_PERMISSION_MAP[method];\n const perms = this.extensionPermissions.get(effectiveExtensionId) ?? new Set<string>();\n if (required && !perms.has(required)) {\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.PermissionDenied,\n message: `Missing permission: ${required}`,\n });\n return;\n }\n\n try {\n const result = await handler(effectiveExtensionId, params);\n this.postResponse(iframe, event, requestId, result);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n this.postResponse(iframe, event, requestId, undefined, {\n code: ExtensionErrorCode.InternalError,\n message,\n });\n }\n }\n}\n\nexport function registerBuiltinMethods(router: ExtensionMessageRouter): void {\n router.registerMethod('theme.get', async () =>\n buildThemeInfo(useThemeStore.getState().resolved),\n );\n\n router.registerMethod('ui.navigate', async (_extensionId, params) => {\n const path =\n params && typeof params === 'object' && params !== null && 'path' in params\n ? String((params as { path?: string }).path ?? '')\n : '';\n if (path) {\n window.dispatchEvent(new CustomEvent('extension-navigate', { detail: { path } }));\n }\n });\n\n router.registerMethod('ui.notification', async (_extensionId, params) => {\n window.dispatchEvent(new CustomEvent('extension-notification', { detail: params }));\n });\n\n router.registerMethod('session.navigate', async (_extensionId, params) => {\n const sessionKey =\n params && typeof params === 'object' && params !== null && 'sessionKey' in params\n ? String((params as { sessionKey?: string }).sessionKey ?? '')\n : '';\n if (sessionKey) {\n window.dispatchEvent(\n new CustomEvent('navigate-to-chat', { detail: { sessionKey }, bubbles: true }),\n );\n }\n });\n\n router.registerMethod('session.list', async () => {\n const response = await apiFetch(apiUrl('/api/sessions'));\n if (!response.ok) throw new Error(`Failed to list sessions: ${response.status}`);\n const data = (await response.json()) as {\n items?: Array<{\n key: string;\n name?: string;\n updatedAt?: string;\n lastAccessedAt?: string;\n messageCount?: number;\n }>;\n };\n return (data.items ?? []).map((s) => ({\n sessionKey: s.key,\n title: s.name,\n lastMessageAt: s.updatedAt ?? s.lastAccessedAt,\n messageCount: s.messageCount,\n }));\n });\n\n router.registerMethod('agent.sendMessage', async (_extensionId, params) => {\n const { message, sessionKey, newSession } = params as {\n message: string;\n sessionKey?: string;\n newSession?: boolean;\n };\n const response = await apiFetch(apiUrl('/api/agent'), {\n method: 'POST',\n headers: { Accept: 'application/json' },\n body: JSON.stringify({\n message,\n channel: 'webchat',\n sessionKey: newSession ? undefined : sessionKey,\n newSession: Boolean(newSession),\n }),\n });\n if (!response.ok) throw new Error(`Agent request failed: ${response.status}`);\n const data = (await response.json()) as {\n payload?: { sessionKey?: string; key?: string };\n sessionKey?: string;\n };\n const fromPayload = data.payload?.sessionKey ?? data.payload?.key;\n return { sessionKey: fromPayload ?? data.sessionKey ?? sessionKey ?? '' };\n });\n\n router.registerMethod('config.get', async (extensionId) => {\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/config`));\n if (!response.ok) throw new Error(`Failed to get config: ${response.status}`);\n return response.json();\n });\n\n router.registerMethod('config.set', async (extensionId, params) => {\n const patch =\n params && typeof params === 'object' && params !== null && !Array.isArray(params)\n ? (params as Record<string, unknown>)\n : {};\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/config`), {\n method: 'PATCH',\n body: JSON.stringify(patch),\n });\n if (!response.ok) throw new Error(`Failed to set config: ${response.status}`);\n });\n\n router.registerMethod('storage.get', async (extensionId, params) => {\n const key =\n params && typeof params === 'object' && params !== null && 'key' in params\n ? String((params as { key?: string }).key ?? '')\n : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n );\n if (response.status === 404) return undefined;\n if (!response.ok) throw new Error(`Failed to get storage key: ${response.status}`);\n const data = (await response.json()) as { value: unknown };\n return data.value;\n });\n\n router.registerMethod('storage.set', async (extensionId, params) => {\n const raw = params as { key?: string; value?: unknown } | undefined;\n const key = raw && typeof raw.key === 'string' ? raw.key : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n { method: 'PUT', body: JSON.stringify({ value: raw?.value }) },\n );\n if (!response.ok) throw new Error(`Failed to set storage key: ${response.status}`);\n });\n\n router.registerMethod('storage.remove', async (extensionId, params) => {\n const key =\n params && typeof params === 'object' && params !== null && 'key' in params\n ? String((params as { key?: string }).key ?? '')\n : '';\n const response = await apiFetch(\n apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage/${encodeURIComponent(key)}`),\n { method: 'DELETE' },\n );\n if (response.status === 404) return;\n if (!response.ok) throw new Error(`Failed to remove storage key: ${response.status}`);\n });\n\n router.registerMethod('storage.keys', async (extensionId) => {\n const response = await apiFetch(apiUrl(`/api/extensions/${encodeURIComponent(extensionId)}/storage`));\n if (!response.ok) throw new Error(`Failed to list storage keys: ${response.status}`);\n const data = (await response.json()) as { keys?: string[] };\n return data.keys ?? [];\n });\n}\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef } from 'react';\nimport useSWR from 'swr';\n\nimport { useGatewayStore } from '@/stores/gateway-store';\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\nimport { useThemeStore } from '@/stores/theme-store';\n\nimport { ExtensionMessageRouter, registerBuiltinMethods } from './extension-message-router';\nimport type { ExtensionApiRow, ExtensionsListResponse } from './types';\nimport { buildThemeInfo } from './theme-bridge';\n\ntype Ctx = {\n router: ExtensionMessageRouter;\n extensions: ExtensionApiRow[];\n loading: boolean;\n};\n\nconst ExtensionContext = createContext<Ctx | null>(null);\n\nexport function ExtensionProvider({ children }: { children: React.ReactNode }) {\n const routerRef = useRef<ExtensionMessageRouter | null>(null);\n if (!routerRef.current) {\n const newRouter = new ExtensionMessageRouter();\n registerBuiltinMethods(newRouter);\n routerRef.current = newRouter;\n }\n const router = routerRef.current;\n const hasToken = useGatewayStore((s) => Boolean(s.token));\n const { data, isLoading } = useSWR(\n hasToken ? 'gateway-extensions-list' : null,\n () => fetchJson<ExtensionsListResponse>(apiUrl('/api/extensions')),\n { revalidateOnFocus: false },\n );\n\n const extensions = data?.extensions ?? [];\n const resolved = useThemeStore((s) => s.resolved);\n\n const handleAgentStreamEvent = useCallback(\n (event: Event) => {\n const detail = (event as CustomEvent<{ sessionKey?: string; event?: unknown }>).detail;\n if (!detail?.sessionKey) return;\n router.forwardAgentStreamEvent(detail.sessionKey, detail.event ?? detail);\n },\n [router],\n );\n\n useEffect(() => {\n window.addEventListener('agent-stream-event', handleAgentStreamEvent as EventListener);\n return () => {\n window.removeEventListener('agent-stream-event', handleAgentStreamEvent as EventListener);\n };\n }, [handleAgentStreamEvent]);\n\n useEffect(() => {\n const theme = buildThemeInfo(resolved);\n router.broadcastEvent('theme.changed', theme);\n }, [resolved, router]);\n\n const routerForCleanupRef = useRef(router);\n routerForCleanupRef.current = router;\n useEffect(\n () => () => {\n routerForCleanupRef.current.dispose();\n // React StrictMode (dev) invokes this cleanup, then remounts. `useRef` survives,\n // so we must clear the ref or the next render would reuse a disposed router\n // (no `window` message listener — extension requests time out).\n routerRef.current = null;\n },\n [],\n );\n\n const value = useMemo(\n () => ({ router, extensions, loading: isLoading }),\n [router, extensions, isLoading],\n );\n\n return <ExtensionContext.Provider value={value}>{children}</ExtensionContext.Provider>;\n}\n\nexport function useExtensionRouter(): ExtensionMessageRouter {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensionRouter must be used within ExtensionProvider');\n }\n return ctx.router;\n}\n\nexport function useExtensions(): ExtensionApiRow[] {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensions must be used within ExtensionProvider');\n }\n return ctx.extensions;\n}\n\n/** Loaded in the gateway process (tools/hooks) or marked to load after restart. */\nfunction extensionUiUnlocked(e: ExtensionApiRow): boolean {\n return e.active || e.activationEligible === true;\n}\n\n/** Manifest declares iframe surfaces (served from disk); show nav/routes even when Node side is not active yet. */\nfunction manifestDeclaresGatewayContributions(e: ExtensionApiRow): boolean {\n const c = e.ui?.contributions;\n if (!c) return false;\n return (\n (Array.isArray(c.pages) && c.pages.length > 0) ||\n (Array.isArray(c.settingsPanels) && c.settingsPanels.length > 0) ||\n (Array.isArray(c.chatWidgets) && c.chatWidgets.length > 0)\n );\n}\n\n/** Used by Apps detail links and {@link useUiExtensions}. */\nexport function extensionExposesGatewayShellUi(e: ExtensionApiRow): boolean {\n if (!e.hasUi) return false;\n // Extension must be enabled (active or scheduled to activate after restart) before\n // its UI contributions appear in the shell. `manifestDeclaresGatewayContributions`\n // only determines whether the iframe surfaces are shown *while* the Node-side is still\n // starting up — it must not override a deliberate disable action by the user.\n if (!extensionUiUnlocked(e)) return false;\n return manifestDeclaresGatewayContributions(e);\n}\n\nexport function useUiExtensions(): ExtensionApiRow[] {\n const list = useExtensions();\n return useMemo(() => list.filter(extensionExposesGatewayShellUi), [list]);\n}\n\nexport function useExtensionsLoading(): boolean {\n const ctx = useContext(ExtensionContext);\n if (!ctx) {\n throw new Error('useExtensionsLoading must be used within ExtensionProvider');\n }\n return ctx.loading;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./vendor-react-QAsRxa6t.js";import{u as t}from"./chunk-QFMPRPBF-DOYp8d2p.js";import{o as n}from"./extension-provider-CO2jxBA9.js";import{t as r}from"./extension-iframe-host-Cs1Kde9o.js";var i=e();function a(){let{extensionId:e,panelId:a}=t(),s=n();if(!e)return(0,i.jsx)(o,{message:`No extension ID provided.`});let c=s.find(t=>t.id===e);if(!c)return(0,i.jsx)(o,{message:`Extension "${e}" not found or has no UI.`});let l=c.ui?.contributions?.settingsPanels;if(!l?.length)return(0,i.jsx)(o,{message:`Extension "${e}" has no settings panels.`});let u=a?l.find(t=>t.id===a||t.id===`${e}.${a}`):l[0];return u?(0,i.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,i.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:u.title}),(0,i.jsx)(`div`,{className:`overflow-hidden rounded-xl border border-edge bg-surface-base`,children:(0,i.jsx)(r,{extensionId:e,extensionName:c.name,entrypoint:u.entrypoint,permissions:c.ui?.permissions,title:u.title,className:`w-full`,minHeight:120,maxHeight:2e3})})]}):(0,i.jsx)(o,{message:`Settings panel "${a}" not found.`})}function o({message:e}){return(0,i.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:(0,i.jsx)(`p`,{className:`text-sm text-fg-muted`,children:e})})}export{a as ExtensionSettingsPage};
2
- //# sourceMappingURL=extension-settings-page-D9Ul8uSt.js.map
1
+ import{t as e}from"./vendor-react-QAsRxa6t.js";import{u as t}from"./chunk-QFMPRPBF-DOYp8d2p.js";import{o as n}from"./extension-provider-DZCZgQE2.js";import{t as r}from"./extension-iframe-host-D5HEF0KR.js";var i=e();function a(){let{extensionId:e,panelId:a}=t(),s=n();if(!e)return(0,i.jsx)(o,{message:`No extension ID provided.`});let c=s.find(t=>t.id===e);if(!c)return(0,i.jsx)(o,{message:`Extension "${e}" not found or has no UI.`});let l=c.ui?.contributions?.settingsPanels;if(!l?.length)return(0,i.jsx)(o,{message:`Extension "${e}" has no settings panels.`});let u=a?l.find(t=>t.id===a||t.id===`${e}.${a}`):l[0];return u?(0,i.jsxs)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:[(0,i.jsx)(`h1`,{className:`text-lg font-semibold text-fg`,children:u.title}),(0,i.jsx)(`div`,{className:`overflow-hidden rounded-xl border border-edge bg-surface-base`,children:(0,i.jsx)(r,{extensionId:e,extensionName:c.name,entrypoint:u.entrypoint,permissions:c.ui?.permissions,title:u.title,className:`w-full`,minHeight:120,maxHeight:2e3})})]}):(0,i.jsx)(o,{message:`Settings panel "${a}" not found.`})}function o({message:e}){return(0,i.jsx)(`div`,{className:`mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8`,children:(0,i.jsx)(`p`,{className:`text-sm text-fg-muted`,children:e})})}export{a as ExtensionSettingsPage};
2
+ //# sourceMappingURL=extension-settings-page-CX6STpx3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extension-settings-page-D9Ul8uSt.js","names":[],"sources":["../../../../../web/src/features/extensions/extension-settings-page.tsx"],"sourcesContent":["/**\n * ExtensionSettingsPage — renders an extension's settings panel via ExtensionIframeHost.\n *\n * Mounted at /settings/ext/:extensionId/:panelId within the settings layout.\n */\n\nimport { useParams } from 'react-router-dom';\n\nimport { ExtensionIframeHost } from './extension-iframe-host';\nimport { useUiExtensions } from './extension-provider';\n\nexport function ExtensionSettingsPage() {\n const { extensionId, panelId } = useParams<{ extensionId: string; panelId?: string }>();\n const uiExtensions = useUiExtensions();\n\n if (!extensionId) {\n return <SettingsPanelNotFound message=\"No extension ID provided.\" />;\n }\n\n const extension = uiExtensions.find((ext) => ext.id === extensionId);\n if (!extension) {\n return (\n <SettingsPanelNotFound message={`Extension \"${extensionId}\" not found or has no UI.`} />\n );\n }\n\n const panels = extension.ui?.contributions?.settingsPanels;\n if (!panels?.length) {\n return (\n <SettingsPanelNotFound message={`Extension \"${extensionId}\" has no settings panels.`} />\n );\n }\n\n const panel = panelId\n ? panels.find((p) => p.id === panelId || p.id === `${extensionId}.${panelId}`)\n : panels[0];\n\n if (!panel) {\n return <SettingsPanelNotFound message={`Settings panel \"${panelId}\" not found.`} />;\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{panel.title}</h1>\n <div className=\"overflow-hidden rounded-xl border border-edge bg-surface-base\">\n <ExtensionIframeHost\n extensionId={extensionId}\n extensionName={extension.name}\n entrypoint={panel.entrypoint}\n permissions={extension.ui?.permissions}\n title={panel.title}\n className=\"w-full\"\n minHeight={120}\n maxHeight={2000}\n />\n </div>\n </div>\n );\n}\n\nfunction SettingsPanelNotFound({ message }: { message: string }) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{message}</p>\n </div>\n );\n}\n"],"mappings":"uNAWA,SAAgB,GAAwB,CACtC,GAAM,CAAE,cAAa,WAAY,GAAsD,CACjF,EAAe,GAAiB,CAEtC,GAAI,CAAC,EACH,OAAO,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAQ,4BAA8B,CAAA,CAGtE,IAAM,EAAY,EAAa,KAAM,GAAQ,EAAI,KAAO,EAAY,CACpE,GAAI,CAAC,EACH,OACE,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,cAAc,EAAY,2BAA8B,CAAA,CAI5F,IAAM,EAAS,EAAU,IAAI,eAAe,eAC5C,GAAI,CAAC,GAAQ,OACX,OACE,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,cAAc,EAAY,2BAA8B,CAAA,CAI5F,IAAM,EAAQ,EACV,EAAO,KAAM,GAAM,EAAE,KAAO,GAAW,EAAE,KAAO,GAAG,EAAY,GAAG,IAAU,CAC5E,EAAO,GAMX,OAJK,GAKH,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uEAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,yCAAiC,EAAM,MAAW,CAAA,EAChE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,0EACb,EAAA,EAAA,KAAC,EAAD,CACe,cACb,cAAe,EAAU,KACzB,WAAY,EAAM,WAClB,YAAa,EAAU,IAAI,YAC3B,MAAO,EAAM,MACb,UAAU,SACV,UAAW,IACX,UAAW,IACX,CAAA,CACE,CAAA,CACF,IAlBC,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,mBAAmB,EAAQ,cAAiB,CAAA,CAsBvF,SAAS,EAAsB,CAAE,WAAgC,CAC/D,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wEACb,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,iCAAyB,EAAY,CAAA,CAC9C,CAAA"}
1
+ {"version":3,"file":"extension-settings-page-CX6STpx3.js","names":[],"sources":["../../../../../web/src/features/extensions/extension-settings-page.tsx"],"sourcesContent":["/**\n * ExtensionSettingsPage — renders an extension's settings panel via ExtensionIframeHost.\n *\n * Mounted at /settings/ext/:extensionId/:panelId within the settings layout.\n */\n\nimport { useParams } from 'react-router-dom';\n\nimport { ExtensionIframeHost } from './extension-iframe-host';\nimport { useUiExtensions } from './extension-provider';\n\nexport function ExtensionSettingsPage() {\n const { extensionId, panelId } = useParams<{ extensionId: string; panelId?: string }>();\n const uiExtensions = useUiExtensions();\n\n if (!extensionId) {\n return <SettingsPanelNotFound message=\"No extension ID provided.\" />;\n }\n\n const extension = uiExtensions.find((ext) => ext.id === extensionId);\n if (!extension) {\n return (\n <SettingsPanelNotFound message={`Extension \"${extensionId}\" not found or has no UI.`} />\n );\n }\n\n const panels = extension.ui?.contributions?.settingsPanels;\n if (!panels?.length) {\n return (\n <SettingsPanelNotFound message={`Extension \"${extensionId}\" has no settings panels.`} />\n );\n }\n\n const panel = panelId\n ? panels.find((p) => p.id === panelId || p.id === `${extensionId}.${panelId}`)\n : panels[0];\n\n if (!panel) {\n return <SettingsPanelNotFound message={`Settings panel \"${panelId}\" not found.`} />;\n }\n\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <h1 className=\"text-lg font-semibold text-fg\">{panel.title}</h1>\n <div className=\"overflow-hidden rounded-xl border border-edge bg-surface-base\">\n <ExtensionIframeHost\n extensionId={extensionId}\n extensionName={extension.name}\n entrypoint={panel.entrypoint}\n permissions={extension.ui?.permissions}\n title={panel.title}\n className=\"w-full\"\n minHeight={120}\n maxHeight={2000}\n />\n </div>\n </div>\n );\n}\n\nfunction SettingsPanelNotFound({ message }: { message: string }) {\n return (\n <div className=\"mx-auto flex w-full max-w-app-main flex-col gap-3 px-4 py-8\">\n <p className=\"text-sm text-fg-muted\">{message}</p>\n </div>\n );\n}\n"],"mappings":"uNAWA,SAAgB,GAAwB,CACtC,GAAM,CAAE,cAAa,WAAY,GAAsD,CACjF,EAAe,GAAiB,CAEtC,GAAI,CAAC,EACH,OAAO,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAQ,4BAA8B,CAAA,CAGtE,IAAM,EAAY,EAAa,KAAM,GAAQ,EAAI,KAAO,EAAY,CACpE,GAAI,CAAC,EACH,OACE,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,cAAc,EAAY,2BAA8B,CAAA,CAI5F,IAAM,EAAS,EAAU,IAAI,eAAe,eAC5C,GAAI,CAAC,GAAQ,OACX,OACE,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,cAAc,EAAY,2BAA8B,CAAA,CAI5F,IAAM,EAAQ,EACV,EAAO,KAAM,GAAM,EAAE,KAAO,GAAW,EAAE,KAAO,GAAG,EAAY,GAAG,IAAU,CAC5E,EAAO,GAMX,OAJK,GAKH,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,uEAAf,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,yCAAiC,EAAM,MAAW,CAAA,EAChE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,0EACb,EAAA,EAAA,KAAC,EAAD,CACe,cACb,cAAe,EAAU,KACzB,WAAY,EAAM,WAClB,YAAa,EAAU,IAAI,YAC3B,MAAO,EAAM,MACb,UAAU,SACV,UAAW,IACX,UAAW,IACX,CAAA,CACE,CAAA,CACF,IAlBC,EAAA,EAAA,KAAC,EAAD,CAAuB,QAAS,mBAAmB,EAAQ,cAAiB,CAAA,CAsBvF,SAAS,EAAsB,CAAE,WAAgC,CAC/D,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,wEACb,EAAA,EAAA,KAAC,IAAD,CAAG,UAAU,iCAAyB,EAAY,CAAA,CAC9C,CAAA"}
@@ -1,2 +1,2 @@
1
- import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{i as t}from"./vendor-react-QAsRxa6t.js";import{r as n,t as r}from"./url-CtSqjF9J.js";import{a as i,r as a}from"./vendor-swr-8rdcElid.js";import{r as o}from"./cn-DPF56z7S.js";var s=o(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),c=e(t(),1);function l(){return r(`/api/config`)}var u=null;async function d(){return u||(u=n(l()).finally(()=>{u=null}),u)}function f(e){let t=a(e?l():null,d,{revalidateOnFocus:!1});return(0,c.useEffect)(()=>{if(!e)return;let t=l(),n=()=>{i(t)};return window.addEventListener(`config-reload`,n),()=>window.removeEventListener(`config-reload`,n)},[e]),t}function p(){return i(l())}export{s as i,p as n,f as r,d as t};
2
- //# sourceMappingURL=gateway-config-swr-Bc8SVD15.js.map
1
+ import{i as e}from"./rolldown-runtime-B1FJdls4.js";import{i as t}from"./vendor-react-QAsRxa6t.js";import{r as n,t as r}from"./url-D7yWllI8.js";import{a as i,r as a}from"./vendor-swr-8rdcElid.js";import{r as o}from"./cn-DPF56z7S.js";var s=o(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),c=e(t(),1);function l(){return r(`/api/config`)}var u=null;async function d(){return u||(u=n(l()).finally(()=>{u=null}),u)}function f(e){let t=a(e?l():null,d,{revalidateOnFocus:!1});return(0,c.useEffect)(()=>{if(!e)return;let t=l(),n=()=>{i(t)};return window.addEventListener(`config-reload`,n),()=>window.removeEventListener(`config-reload`,n)},[e]),t}function p(){return i(l())}export{s as i,p as n,f as r,d as t};
2
+ //# sourceMappingURL=gateway-config-swr-Cph02QZn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-config-swr-Bc8SVD15.js","names":[],"sources":["../../../../../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/icons/eye.js","../../../../../web/src/features/gateway/gateway-config-swr.ts"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.js.map\n","import { useEffect } from 'react';\nimport useSWR, { mutate } from 'swr';\n\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport type GatewayConfigApiResponse = {\n ok?: boolean;\n payload?: { config?: unknown };\n};\n\nexport function gatewayConfigSwrKey(): string {\n return apiUrl('/api/config');\n}\n\nlet _gatewayConfigInflight: Promise<GatewayConfigApiResponse> | null = null;\n\n/**\n * GET /api/config. Concurrent in-flight calls share one HTTP request (e.g. onboarding + SWR\n * on settings, or chat bootstrap + `fetchChatAgents` fallback) so a full refresh does not\n * duplicate the same payload fetch.\n */\nexport async function fetchGatewayConfigSwrResponse(): Promise<GatewayConfigApiResponse> {\n if (_gatewayConfigInflight) return _gatewayConfigInflight;\n _gatewayConfigInflight = fetchJson<GatewayConfigApiResponse>(gatewayConfigSwrKey()).finally(\n () => {\n _gatewayConfigInflight = null;\n },\n );\n return _gatewayConfigInflight;\n}\n\n/**\n * Shared GET /api/config for gateway console. Multiple settings panels use the same SWR key so\n * navigation and Strict Mode do not duplicate network calls.\n */\nexport function useGatewayConfigSwr(shouldFetch: boolean) {\n const key = shouldFetch ? gatewayConfigSwrKey() : null;\n const swr = useSWR(key, fetchGatewayConfigSwrResponse, { revalidateOnFocus: false });\n\n useEffect(() => {\n if (!shouldFetch) return;\n const k = gatewayConfigSwrKey();\n const onReload = () => {\n void mutate(k);\n };\n window.addEventListener('config-reload', onReload);\n return () => window.removeEventListener('config-reload', onReload);\n }, [shouldFetch]);\n\n return swr;\n}\n\nexport function revalidateGatewayConfig(): Promise<GatewayConfigApiResponse | undefined> {\n return mutate(gatewayConfigSwrKey());\n}\n"],"x_google_ignoreList":[0],"mappings":"wOAmBA,IAAM,EAAM,EAAiB,MAVV,CACjB,CACE,OACA,CACE,EAAG,wGACH,IAAK,SACN,CACF,CACD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,CAAC,CAC1D,CAC8C,YCR/C,SAAgB,GAA8B,CAC5C,OAAO,EAAO,cAAc,CAG9B,IAAI,EAAmE,KAOvE,eAAsB,GAAmE,CAOvF,OANI,IACJ,EAAyB,EAAoC,GAAqB,CAAC,CAAC,YAC5E,CACJ,EAAyB,MAE5B,CACM,GAOT,SAAgB,EAAoB,EAAsB,CAExD,IAAM,EAAM,EADA,EAAc,GAAqB,CAAG,KAC1B,EAA+B,CAAE,kBAAmB,GAAO,CAAC,CAYpF,OAVA,EAAA,EAAA,eAAgB,CACd,GAAI,CAAC,EAAa,OAClB,IAAM,EAAI,GAAqB,CACzB,MAAiB,CAChB,EAAO,EAAE,EAGhB,OADA,OAAO,iBAAiB,gBAAiB,EAAS,KACrC,OAAO,oBAAoB,gBAAiB,EAAS,EACjE,CAAC,EAAY,CAAC,CAEV,EAGT,SAAgB,GAAyE,CACvF,OAAO,EAAO,GAAqB,CAAC"}
1
+ {"version":3,"file":"gateway-config-swr-Cph02QZn.js","names":[],"sources":["../../../../../node_modules/.pnpm/lucide-react@1.8.0_react@19.2.5/node_modules/lucide-react/dist/esm/icons/eye.js","../../../../../web/src/features/gateway/gateway-config-swr.ts"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.js.map\n","import { useEffect } from 'react';\nimport useSWR, { mutate } from 'swr';\n\nimport { fetchJson } from '@/lib/fetch';\nimport { apiUrl } from '@/lib/url';\n\nexport type GatewayConfigApiResponse = {\n ok?: boolean;\n payload?: { config?: unknown };\n};\n\nexport function gatewayConfigSwrKey(): string {\n return apiUrl('/api/config');\n}\n\nlet _gatewayConfigInflight: Promise<GatewayConfigApiResponse> | null = null;\n\n/**\n * GET /api/config. Concurrent in-flight calls share one HTTP request (e.g. onboarding + SWR\n * on settings, or chat bootstrap + `fetchChatAgents` fallback) so a full refresh does not\n * duplicate the same payload fetch.\n */\nexport async function fetchGatewayConfigSwrResponse(): Promise<GatewayConfigApiResponse> {\n if (_gatewayConfigInflight) return _gatewayConfigInflight;\n _gatewayConfigInflight = fetchJson<GatewayConfigApiResponse>(gatewayConfigSwrKey()).finally(\n () => {\n _gatewayConfigInflight = null;\n },\n );\n return _gatewayConfigInflight;\n}\n\n/**\n * Shared GET /api/config for gateway console. Multiple settings panels use the same SWR key so\n * navigation and Strict Mode do not duplicate network calls.\n */\nexport function useGatewayConfigSwr(shouldFetch: boolean) {\n const key = shouldFetch ? gatewayConfigSwrKey() : null;\n const swr = useSWR(key, fetchGatewayConfigSwrResponse, { revalidateOnFocus: false });\n\n useEffect(() => {\n if (!shouldFetch) return;\n const k = gatewayConfigSwrKey();\n const onReload = () => {\n void mutate(k);\n };\n window.addEventListener('config-reload', onReload);\n return () => window.removeEventListener('config-reload', onReload);\n }, [shouldFetch]);\n\n return swr;\n}\n\nexport function revalidateGatewayConfig(): Promise<GatewayConfigApiResponse | undefined> {\n return mutate(gatewayConfigSwrKey());\n}\n"],"x_google_ignoreList":[0],"mappings":"wOAmBA,IAAM,EAAM,EAAiB,MAVV,CACjB,CACE,OACA,CACE,EAAG,wGACH,IAAK,SACN,CACF,CACD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,CAAC,CAC1D,CAC8C,YCR/C,SAAgB,GAA8B,CAC5C,OAAO,EAAO,cAAc,CAG9B,IAAI,EAAmE,KAOvE,eAAsB,GAAmE,CAOvF,OANI,IACJ,EAAyB,EAAoC,GAAqB,CAAC,CAAC,YAC5E,CACJ,EAAyB,MAE5B,CACM,GAOT,SAAgB,EAAoB,EAAsB,CAExD,IAAM,EAAM,EADA,EAAc,GAAqB,CAAG,KAC1B,EAA+B,CAAE,kBAAmB,GAAO,CAAC,CAYpF,OAVA,EAAA,EAAA,eAAgB,CACd,GAAI,CAAC,EAAa,OAClB,IAAM,EAAI,GAAqB,CACzB,MAAiB,CAChB,EAAO,EAAE,EAGhB,OADA,OAAO,iBAAiB,gBAAiB,EAAS,KACrC,OAAO,oBAAoB,gBAAiB,EAAS,EACjE,CAAC,EAAY,CAAC,CAEV,EAGT,SAAgB,GAAyE,CACvF,OAAO,EAAO,GAAqB,CAAC"}
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:"";--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", system-ui, "Segoe UI", Roboto, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Noto Sans CJK SC", "Microsoft YaHei", 微软雅黑, sans-serif;--font-mono:ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas, monospace;--color-red-50:#fef2f2;--color-red-100:#ffe2e2;--color-red-200:#ffcaca;--color-red-300:#ffa3a3;--color-red-400:#ff6568;--color-red-500:#fb2c36;--color-red-600:#e40014;--color-red-700:#bf000f;--color-red-800:#9f0712;--color-red-900:#82181a;--color-red-950:#460809;--color-amber-50:#fffbeb;--color-amber-100:#fef3c6;--color-amber-200:#fee685;--color-amber-400:#fcbb00;--color-amber-500:#f99c00;--color-amber-600:#dd7400;--color-amber-800:#953d00;--color-amber-900:#7b3306;--color-amber-950:#461901;--color-yellow-400:#fac800;--color-yellow-600:#cd8900;--color-green-400:#05df72;--color-green-600:#00a544;--color-emerald-50:#ecfdf5;--color-emerald-100:#d0fae5;--color-emerald-200:#a4f4cf;--color-emerald-300:#5ee9b5;--color-emerald-400:#00d294;--color-emerald-500:#00bb7f;--color-emerald-600:#009767;--color-emerald-700:#007956;--color-emerald-800:#005f46;--color-emerald-900:#004e3b;--color-emerald-950:#002c22;--color-blue-50:#eff6ff;--color-blue-100:#dbeafe;--color-blue-200:#bedbff;--color-blue-400:#54a2ff;--color-blue-600:#155dfc;--color-blue-800:#193cb8;--color-blue-900:#1c398e;--color-blue-950:#162456;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-sm:.625rem;--radius-md:.75rem;--radius-lg:.875rem;--radius-xl:1.125rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-surface-base:#f5f5f7;--color-surface-panel:#fff;--color-surface-hover:#e8e8ed;--color-surface-active:#dcdcde;--color-fg:#1d1d1f;--color-fg-muted:#6e6e73;--color-fg-subtle:#86868b;--color-fg-disabled:#aeaeb2;--color-edge-subtle:#ebebed;--color-edge:#d2d2d7;--color-edge-strong:#bcbcc0;--color-accent:#2563eb;--color-accent-hover:#1d4ed8;--color-accent-soft:#eff6ff;--color-accent-fg:#2563eb;--color-checkbox-accent:#3c3c43;--color-success:#059669;--color-success-soft:#d1fae5;--color-danger:#dc2626;--color-warning:#d97706;--color-scrim:#0000005c;--radius-pill:9999px;--max-width-app-main:56rem;--max-width-chat:52rem}@supports (color:lab(0% 0 0)){:root,:host{--color-red-50:lab(96.5005% 4.18508 1.52328);--color-red-100:lab(92.243% 10.2865 3.83865);--color-red-200:lab(86.017% 19.8815 7.75869);--color-red-300:lab(76.5514% 36.422 15.5335);--color-red-400:lab(63.7053% 60.745 31.3109);--color-red-500:lab(55.4814% 75.0732 48.8528);--color-red-600:lab(48.4493% 77.4328 61.5452);--color-red-700:lab(40.4273% 67.2623 53.7441);--color-red-800:lab(33.7174% 55.8993 41.0293);--color-red-900:lab(28.5139% 44.5539 29.0463);--color-red-950:lab(13.003% 29.04 16.7519);--color-amber-50:lab(98.6252% -.635922 8.42309);--color-amber-100:lab(95.916% -1.21653 23.111);--color-amber-200:lab(91.7203% -.505269 49.9084);--color-amber-400:lab(80.1641% 16.6016 99.2089);--color-amber-500:lab(72.7183% 31.8672 97.9407);--color-amber-600:lab(60.3514% 40.5624 87.1228);--color-amber-800:lab(37.8822% 37.1699 52.2718);--color-amber-900:lab(31.2288% 30.2627 40.0378);--color-amber-950:lab(15.8111% 20.9107 23.3752);--color-yellow-400:lab(83.2664% 8.65132 106.895);--color-yellow-600:lab(62.7799% 22.4197 86.1544);--color-green-400:lab(78.503% -64.9265 39.7492);--color-green-600:lab(59.0978% -58.6621 41.2579);--color-emerald-50:lab(97.8462% -6.94966 1.85487);--color-emerald-100:lab(94.9004% -17.0769 5.63836);--color-emerald-200:lab(90.2247% -31.039 9.47084);--color-emerald-300:lab(83.9203% -48.7124 13.8849);--color-emerald-400:lab(75.0771% -60.7313 19.4147);--color-emerald-500:lab(66.9756% -58.27 19.5419);--color-emerald-600:lab(55.0481% -49.9246 15.93);--color-emerald-700:lab(44.4871% -41.0396 11.0361);--color-emerald-800:lab(35.3675% -33.1188 8.04002);--color-emerald-900:lab(28.8637% -26.9249 5.45986);--color-emerald-950:lab(15.0582% -17.9507 2.38369);--color-blue-50:lab(96.492% -1.14644 -5.11479);--color-blue-100:lab(92.0301% -2.24757 -11.6453);--color-blue-200:lab(86.15% -4.04379 -21.0797);--color-blue-400:lab(65.0361% -1.42065 -56.9802);--color-blue-600:lab(44.0605% 29.0279 -86.0352);--color-blue-800:lab(30.2514% 27.7853 -70.2699);--color-blue-900:lab(26.1542% 15.7545 -51.5504);--color-blue-950:lab(15.6723% 8.86232 -32.2945)}}}@layer base{*,:after,:before{box-sizing:border-box;border:0 solid;margin:0;padding:0}::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{box-sizing:border-box}html{height:100%;font-family:var(--font-sans);background-color:var(--color-surface-base);color:var(--color-fg);--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;font-size:100%;overflow:hidden}@media (prefers-color-scheme:dark){html{--lightningcss-light: ;--lightningcss-dark:initial}}html[data-font-scale=compact]{font-size:87.5%}html[data-font-scale=large]{font-size:112.5%}body{letter-spacing:-.006em;height:100%;min-height:100%;margin:0;font-size:.9375rem;line-height:1.47059;overflow:hidden}#root{flex-direction:column;height:100%;min-height:0;display:flex;overflow:hidden}::selection{background:var(--color-accent-soft);color:var(--color-accent-fg)}:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}:focus-visible:not(input):not(textarea){border-radius:var(--radius-sm)}:focus:not(:focus-visible){outline:none}input:focus,input:focus-visible,textarea:focus,textarea:focus-visible,select:focus,select:focus-visible{outline-offset:0;box-shadow:none;outline:none}}@layer components{.ui-checkbox{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-edge);background-color:var(--color-surface-panel);accent-color:var(--color-checkbox-accent);border-radius:.25rem;flex-shrink:0}.ui-checkbox:disabled{cursor:not-allowed;opacity:.5}.ui-select{border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-edge-subtle);background-color:var(--color-surface-panel);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-snug);line-height:var(--leading-snug);--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal);color:var(--color-fg);cursor:pointer;transition-property:border-color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out)}@media (hover:hover){.ui-select:hover{border-color:var(--color-edge);background-color:#e8e8ed73}@supports (color:color-mix(in lab, red, red)){.ui-select:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 45%, transparent)}}}.ui-select:focus,.ui-select:focus-visible{--tw-outline-style:none;outline-style:none}.ui-select:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ui-select:focus-visible{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);border-color:var(--color-edge)}html.dark .ui-select{border-color:var(--color-edge-subtle);background-color:var(--color-surface-panel)}html.dark .ui-select:hover{border-color:var(--color-edge);background-color:#e8e8ed8c}@supports (color:color-mix(in lab, red, red)){html.dark .ui-select:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 55%, transparent)}}.ui-select:disabled{cursor:not-allowed;opacity:.5}.chat-skill-pill{max-width:100%;padding-inline:calc(var(--spacing) * 2.5);padding-block:calc(var(--spacing) * .5);vertical-align:baseline;--tw-leading:calc(var(--spacing) * 5);font-size:.9375rem;line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:#8a8a2e;background-color:#f5f5e6;border-radius:3.40282e38px;flex-shrink:0;align-items:center;display:inline-flex}html.dark .chat-skill-pill{color:#c4c47a;background-color:#2d2d24}.chat-file-pill{background:var(--color-accent-soft);color:var(--color-accent-fg);white-space:nowrap;-webkit-user-select:none;user-select:none;cursor:default;vertical-align:baseline;border-radius:.25rem;align-items:center;gap:.125rem;padding:.0625rem .375rem;font-size:.8125rem;font-weight:500;display:inline-flex}.composer-input{white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;position:relative}.composer-input-empty:before{content:attr(data-placeholder);color:var(--color-fg-disabled);pointer-events:none}}@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-4{inset:calc(var(--spacing) * 4)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-1{top:calc(var(--spacing) * -1)}.top-0{top:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.top-3{top:calc(var(--spacing) * 3)}.top-full{top:100%}.-right-1{right:calc(var(--spacing) * -1)}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-1{bottom:calc(var(--spacing) * 1)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-\[calc\(11rem\+env\(safe-area-inset-bottom\,0px\)\)\]{bottom:calc(11rem + env(safe-area-inset-bottom,0px))}.left-0{left:calc(var(--spacing) * 0)}.left-0\.5{left:calc(var(--spacing) * .5)}.left-1\/2{left:50%}.left-3{left:calc(var(--spacing) * 3)}.left-full{left:100%}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.z-\[55\]{z-index:55}.z-\[60\]{z-index:60}.z-\[62\]{z-index:62}.z-\[65\]{z-index:65}.z-\[66\]{z-index:66}.z-\[70\]{z-index:70}.z-\[80\]{z-index:80}.z-\[81\]{z-index:81}.z-\[100\]{z-index:100}.z-\[120\]{z-index:120}.z-\[130\]{z-index:130}.z-\[131\]{z-index:131}.z-\[200\]{z-index:200}.z-\[201\]{z-index:201}.order-1{order:1}.order-2{order:2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mx-1\.5{margin-inline:calc(var(--spacing) * 1.5)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-4{margin-block:calc(var(--spacing) * 4)}.-mt-2{margin-top:calc(var(--spacing) * -2)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-10{margin-top:calc(var(--spacing) * 10)}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-4{-webkit-line-clamp:4;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-14{width:calc(var(--spacing) * 14);height:calc(var(--spacing) * 14)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.size-\[1\.35rem\]{width:1.35rem;height:1.35rem}.size-\[1\.125rem\]{width:1.125rem;height:1.125rem}.size-\[4\.5rem\]{width:4.5rem;height:4.5rem}.size-\[18px\]{width:18px;height:18px}.size-full{width:100%;height:100%}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-24{height:calc(var(--spacing) * 24)}.h-32{height:calc(var(--spacing) * 32)}.h-36{height:calc(var(--spacing) * 36)}.h-40{height:calc(var(--spacing) * 40)}.h-52{height:calc(var(--spacing) * 52)}.h-\[100dvh\]{height:100dvh}.h-\[calc\(100dvh-2rem\)\]{height:calc(100dvh - 2rem)}.h-\[min\(18rem\,40vh\)\]{height:min(18rem,40vh)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.max-h-16{max-height:calc(var(--spacing) * 16)}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[4\.5rem\]{max-height:4.5rem}.max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.max-h-\[min\(16rem\,calc\(100vh-10rem\)\)\]{max-height:min(16rem,100vh - 10rem)}.max-h-\[min\(20rem\,calc\(100vh-6rem\)\)\]{max-height:min(20rem,100vh - 6rem)}.max-h-\[min\(24rem\,50vh\)\]{max-height:min(24rem,50vh)}.max-h-\[min\(24rem\,55vh\)\]{max-height:min(24rem,55vh)}.max-h-\[min\(26rem\,54vh\)\]{max-height:min(26rem,54vh)}.max-h-\[min\(28rem\,60vh\)\]{max-height:min(28rem,60vh)}.max-h-\[min\(30vh\,11rem\)\]{max-height:min(30vh,11rem)}.max-h-\[min\(32rem\,85vh\)\]{max-height:min(32rem,85vh)}.max-h-\[min\(32rem\,90vh\)\]{max-height:min(32rem,90vh)}.max-h-\[min\(42vh\,20rem\)\]{max-height:min(42vh,20rem)}.max-h-\[min\(50vh\,20rem\)\]{max-height:min(50vh,20rem)}.max-h-\[min\(90vh\,32rem\)\]{max-height:min(90vh,32rem)}.max-h-\[min\(90vh\,44rem\)\]{max-height:min(90vh,44rem)}.max-h-\[min\(90vh\,48rem\)\]{max-height:min(90vh,48rem)}.max-h-\[min\(90vh\,52rem\)\]{max-height:min(90vh,52rem)}.max-h-\[min\(90vh\,56rem\)\]{max-height:min(90vh,56rem)}.max-h-\[min\(90vh\,640px\)\]{max-height:min(90vh,640px)}.max-h-\[min\(90vh\,720px\)\]{max-height:min(90vh,720px)}.max-h-\[min\(90vh\,800px\)\]{max-height:min(90vh,800px)}.max-h-\[min\(90vh\,840px\)\]{max-height:min(90vh,840px)}.max-h-\[min\(100\%\,calc\(100dvh-9rem\)\)\]{max-height:min(100%,100dvh - 9rem)}.max-h-\[min\(100vh-2rem\,44rem\)\]{max-height:min(100vh - 2rem,44rem)}.max-h-full{max-height:100%}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-8{min-height:calc(var(--spacing) * 8)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-\[1\.125rem\]{min-height:1.125rem}.min-h-\[1\.3125rem\]{min-height:1.3125rem}.min-h-\[2\.5rem\]{min-height:2.5rem}.min-h-\[2\.75rem\]{min-height:2.75rem}.min-h-\[4\.5rem\]{min-height:4.5rem}.min-h-\[5\.5rem\]{min-height:5.5rem}.min-h-\[7\.5rem\]{min-height:7.5rem}.min-h-\[11rem\]{min-height:11rem}.min-h-\[12rem\]{min-height:12rem}.min-h-\[44px\]{min-height:44px}.min-h-\[88px\]{min-height:88px}.min-h-\[100px\]{min-height:100px}.min-h-\[140px\]{min-height:140px}.min-h-\[200px\]{min-height:200px}.min-h-\[320px\]{min-height:320px}.min-h-\[min\(40vh\,16rem\)\]{min-height:min(40vh,16rem)}.min-h-\[min\(40vh\,20rem\)\]{min-height:min(40vh,20rem)}.min-h-full{min-height:100%}.w-0\.5{width:calc(var(--spacing) * .5)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-5\/6{width:83.3333%}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-40{width:calc(var(--spacing) * 40)}.w-48{width:calc(var(--spacing) * 48)}.w-52{width:calc(var(--spacing) * 52)}.w-64{width:calc(var(--spacing) * 64)}.w-80{width:calc(var(--spacing) * 80)}.w-\[4\.5rem\]{width:4.5rem}.w-\[5\.25rem\]{width:5.25rem}.w-\[9\.25rem\]{width:9.25rem}.w-\[min\(22rem\,calc\(100vw-2rem\)\)\]{width:min(22rem,100vw - 2rem)}.w-\[min\(28rem\,calc\(100vw-2rem\)\)\]{width:min(28rem,100vw - 2rem)}.w-\[min\(42rem\,calc\(100vw-1\.5rem\)\)\]{width:min(42rem,100vw - 1.5rem)}.w-\[min\(100\%\,var\(--max-width-app-main\)\)\]{width:min(100%, var(--max-width-app-main))}.w-\[min\(100\%-2rem\,22rem\)\]{width:min(100% - 2rem,22rem)}.w-\[min\(100\%-2rem\,24rem\)\]{width:min(100% - 2rem,24rem)}.w-\[min\(100\%-2rem\,26rem\)\]{width:min(100% - 2rem,26rem)}.w-\[min\(100\%-2rem\,28rem\)\]{width:min(100% - 2rem,28rem)}.w-\[min\(100\%-2rem\,32rem\)\]{width:min(100% - 2rem,32rem)}.w-\[min\(100\%-2rem\,36rem\)\]{width:min(100% - 2rem,36rem)}.w-\[min\(100\%-2rem\,min\(92vw\,48rem\)\)\]{width:min(100% - 2rem,min(92vw,48rem))}.w-\[min\(100\%-2rem\,min\(92vw\,56rem\)\)\]{width:min(100% - 2rem,min(92vw,56rem))}.w-\[min\(calc\(100vw-2rem\)\,15rem\)\]{width:min(100vw - 2rem,15rem)}.w-\[min\(calc\(100vw-2rem\)\,20rem\)\]{width:min(100vw - 2rem,20rem)}.w-\[var\(--radix-popover-trigger-width\)\]{width:var(--radix-popover-trigger-width)}.w-auto{width:auto}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:max-content}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-80{max-width:calc(var(--spacing) * 80)}.max-w-\[7rem\]{max-width:7rem}.max-w-\[8rem\]{max-width:8rem}.max-w-\[10rem\]{max-width:10rem}.max-w-\[11rem\]{max-width:11rem}.max-w-\[12rem\]{max-width:12rem}.max-w-\[14rem\]{max-width:14rem}.max-w-\[16rem\]{max-width:16rem}.max-w-\[200px\]{max-width:200px}.max-w-\[min\(6\.5rem\,30vw\)\]{max-width:min(6.5rem,30vw)}.max-w-\[min\(10rem\,calc\(100vw-12rem\)\)\]{max-width:min(10rem,100vw - 12rem)}.max-w-\[min\(12rem\,40vw\)\]{max-width:min(12rem,40vw)}.max-w-\[min\(16rem\,48vw\)\]{max-width:min(16rem,48vw)}.max-w-\[min\(20rem\,calc\(100vw-10rem\)\)\]{max-width:min(20rem,100vw - 10rem)}.max-w-\[min\(32rem\,calc\(100vw-8rem\)\)\]{max-width:min(32rem,100vw - 8rem)}.max-w-\[min\(85\%\,var\(--max-width-chat\)\)\]{max-width:min(85%, var(--max-width-chat))}.max-w-\[min\(100\%\,12rem\)\]{max-width:min(100%,12rem)}.max-w-\[min\(100\%\,48rem\)\]{max-width:min(100%,48rem)}.max-w-\[min\(100\%\,52rem\)\]{max-width:min(100%,52rem)}.max-w-\[min\(280px\,90vw\)\]{max-width:min(280px,90vw)}.max-w-\[min\(calc\(100vw-1rem\)\,28rem\)\]{max-width:min(100vw - 1rem,28rem)}.max-w-\[min\(calc\(100vw-2rem\)\,16rem\)\]{max-width:min(100vw - 2rem,16rem)}.max-w-\[var\(--max-width-chat\)\]{max-width:var(--max-width-chat)}.max-w-app-main{max-width:var(--max-width-app-main)}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-\[4\.5rem\]{min-width:4.5rem}.min-w-\[4\.25rem\]{min-width:4.25rem}.min-w-\[4rem\]{min-width:4rem}.min-w-\[5rem\]{min-width:5rem}.min-w-\[6\.5rem\]{min-width:6.5rem}.min-w-\[7\.5rem\]{min-width:7.5rem}.min-w-\[8\.5rem\]{min-width:8.5rem}.min-w-\[8rem\]{min-width:8rem}.min-w-\[9\.5rem\]{min-width:9.5rem}.min-w-\[9rem\]{min-width:9rem}.min-w-\[10rem\]{min-width:10rem}.min-w-\[11rem\]{min-width:11rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[32rem\]{min-width:32rem}.min-w-\[44px\]{min-width:44px}.min-w-\[700px\]{min-width:700px}.min-w-\[min\(16rem\,90vw\)\]{min-width:min(16rem,90vw)}.min-w-\[min\(100\%\,36rem\)\]{min-width:min(100%,36rem)}.min-w-\[min\(240px\,85vw\)\]{min-width:min(240px,85vw)}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.cursor-wait{cursor:wait}.touch-none{touch-action:none}.resize{resize:both}.resize-y{resize:vertical}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.appearance-none{appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[5\.5rem_1fr\]{grid-template-columns:5.5rem 1fr}.grid-cols-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-columns:auto minmax(0,1fr) auto}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-px{gap:1px}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-0\.5{column-gap:calc(var(--spacing) * .5)}.gap-x-1\.5{column-gap:calc(var(--spacing) * 1.5)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-0{row-gap:calc(var(--spacing) * 0)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-edge>:not(:last-child)){border-color:var(--color-edge)}:where(.divide-edge-subtle>:not(:last-child)){border-color:var(--color-edge-subtle)}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.overscroll-y-contain{overscroll-behavior-y:contain}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-pill{border-radius:var(--radius-pill)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t-xl{border-top-left-radius:var(--radius-xl);border-top-right-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-accent{border-color:var(--color-accent)}.border-accent\/20{border-color:#2563eb33}@supports (color:color-mix(in lab, red, red)){.border-accent\/20{border-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.border-accent\/25{border-color:#2563eb40}@supports (color:color-mix(in lab, red, red)){.border-accent\/25{border-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.border-accent\/40{border-color:#2563eb66}@supports (color:color-mix(in lab, red, red)){.border-accent\/40{border-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.border-amber-100{border-color:var(--color-amber-100)}.border-amber-200{border-color:var(--color-amber-200)}.border-amber-500{border-color:var(--color-amber-500)}.border-amber-500\/40{border-color:#f99c0066}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/40{border-color:color-mix(in oklab, var(--color-amber-500) 40%, transparent)}}.border-blue-200\/80{border-color:#bedbffcc}@supports (color:color-mix(in lab, red, red)){.border-blue-200\/80{border-color:color-mix(in oklab, var(--color-blue-200) 80%, transparent)}}.border-danger\/30{border-color:#dc26264d}@supports (color:color-mix(in lab, red, red)){.border-danger\/30{border-color:color-mix(in oklab, var(--color-danger) 30%, transparent)}}.border-danger\/35{border-color:#dc262659}@supports (color:color-mix(in lab, red, red)){.border-danger\/35{border-color:color-mix(in oklab, var(--color-danger) 35%, transparent)}}.border-danger\/40{border-color:#dc262666}@supports (color:color-mix(in lab, red, red)){.border-danger\/40{border-color:color-mix(in oklab, var(--color-danger) 40%, transparent)}}.border-edge{border-color:var(--color-edge)}.border-edge-subtle{border-color:var(--color-edge-subtle)}.border-edge-subtle\/60{border-color:#ebebed99}@supports (color:color-mix(in lab, red, red)){.border-edge-subtle\/60{border-color:color-mix(in oklab, var(--color-edge-subtle) 60%, transparent)}}.border-edge-subtle\/80{border-color:#ebebedcc}@supports (color:color-mix(in lab, red, red)){.border-edge-subtle\/80{border-color:color-mix(in oklab, var(--color-edge-subtle) 80%, transparent)}}.border-edge-subtle\/90{border-color:#ebebede6}@supports (color:color-mix(in lab, red, red)){.border-edge-subtle\/90{border-color:color-mix(in oklab, var(--color-edge-subtle) 90%, transparent)}}.border-edge\/60{border-color:#d2d2d799}@supports (color:color-mix(in lab, red, red)){.border-edge\/60{border-color:color-mix(in oklab, var(--color-edge) 60%, transparent)}}.border-emerald-200{border-color:var(--color-emerald-200)}.border-emerald-500\/40{border-color:#00bb7f66}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/40{border-color:color-mix(in oklab, var(--color-emerald-500) 40%, transparent)}}.border-fg{border-color:var(--color-fg)}.border-red-100{border-color:var(--color-red-100)}.border-red-200{border-color:var(--color-red-200)}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/30{border-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.border-red-500\/30{border-color:color-mix(in oklab, var(--color-red-500) 30%, transparent)}}.border-red-500\/40{border-color:#fb2c3666}@supports (color:color-mix(in lab, red, red)){.border-red-500\/40{border-color:color-mix(in oklab, var(--color-red-500) 40%, transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-transparent{border-color:#0000}.border-t-transparent{border-top-color:#0000}.border-l-accent\/60{border-left-color:#2563eb99}@supports (color:color-mix(in lab, red, red)){.border-l-accent\/60{border-left-color:color-mix(in oklab, var(--color-accent) 60%, transparent)}}.bg-\[\#0a0a0a\]{background-color:#0a0a0a}.bg-\[\#000000\]{background-color:#000}.bg-\[\#1d1d1f\]{background-color:#1d1d1f}.bg-\[\#10b981\]{background-color:#10b981}.bg-\[\#28c840\]{background-color:#28c840}.bg-\[\#34d399\]{background-color:#34d399}.bg-\[\#065f46\]{background-color:#065f46}.bg-\[\#134e2a\]{background-color:#134e2a}.bg-\[\#2563eb\]{background-color:#2563eb}.bg-\[\#d2d2d7\]{background-color:#d2d2d7}.bg-\[\#f5f5f7\]{background-color:#f5f5f7}.bg-\[\#febc2e\]{background-color:#febc2e}.bg-\[\#ff5f57\]{background-color:#ff5f57}.bg-\[\#ffffff\]{background-color:#fff}.bg-accent{background-color:var(--color-accent)}.bg-accent-soft{background-color:var(--color-accent-soft)}.bg-accent-soft\/40{background-color:#eff6ff66}@supports (color:color-mix(in lab, red, red)){.bg-accent-soft\/40{background-color:color-mix(in oklab, var(--color-accent-soft) 40%, transparent)}}.bg-accent-soft\/55{background-color:#eff6ff8c}@supports (color:color-mix(in lab, red, red)){.bg-accent-soft\/55{background-color:color-mix(in oklab, var(--color-accent-soft) 55%, transparent)}}.bg-accent-soft\/60{background-color:#eff6ff99}@supports (color:color-mix(in lab, red, red)){.bg-accent-soft\/60{background-color:color-mix(in oklab, var(--color-accent-soft) 60%, transparent)}}.bg-accent-soft\/70{background-color:#eff6ffb3}@supports (color:color-mix(in lab, red, red)){.bg-accent-soft\/70{background-color:color-mix(in oklab, var(--color-accent-soft) 70%, transparent)}}.bg-accent-soft\/80{background-color:#eff6ffcc}@supports (color:color-mix(in lab, red, red)){.bg-accent-soft\/80{background-color:color-mix(in oklab, var(--color-accent-soft) 80%, transparent)}}.bg-accent\/5{background-color:#2563eb0d}@supports (color:color-mix(in lab, red, red)){.bg-accent\/5{background-color:color-mix(in oklab, var(--color-accent) 5%, transparent)}}.bg-accent\/10{background-color:#2563eb1a}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\/15{background-color:#2563eb26}@supports (color:color-mix(in lab, red, red)){.bg-accent\/15{background-color:color-mix(in oklab, var(--color-accent) 15%, transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-50\/80{background-color:#fffbebcc}@supports (color:color-mix(in lab, red, red)){.bg-amber-50\/80{background-color:color-mix(in oklab, var(--color-amber-50) 80%, transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/10{background-color:color-mix(in oklab, var(--color-amber-500) 10%, transparent)}}.bg-black\/0{background-color:#0000}@supports (color:color-mix(in lab, red, red)){.bg-black\/0{background-color:color-mix(in oklab, var(--color-black) 0%, transparent)}}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.bg-black\/40{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-blue-50\/95{background-color:#eff6fff2}@supports (color:color-mix(in lab, red, red)){.bg-blue-50\/95{background-color:color-mix(in oklab, var(--color-blue-50) 95%, transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-danger{background-color:var(--color-danger)}.bg-danger\/10{background-color:#dc26261a}@supports (color:color-mix(in lab, red, red)){.bg-danger\/10{background-color:color-mix(in oklab, var(--color-danger) 10%, transparent)}}.bg-edge{background-color:var(--color-edge)}.bg-edge-subtle{background-color:var(--color-edge-subtle)}.bg-edge-subtle\/80{background-color:#ebebedcc}@supports (color:color-mix(in lab, red, red)){.bg-edge-subtle\/80{background-color:color-mix(in oklab, var(--color-edge-subtle) 80%, transparent)}}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-emerald-500\/15{background-color:#00bb7f26}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/15{background-color:color-mix(in oklab, var(--color-emerald-500) 15%, transparent)}}.bg-fg{background-color:var(--color-fg)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-red-500\/15{background-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/15{background-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.bg-red-500\/20{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/20{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-scrim{background-color:var(--color-scrim)}.bg-success{background-color:var(--color-success)}.bg-success-soft{background-color:var(--color-success-soft)}.bg-surface-active{background-color:var(--color-surface-active)}.bg-surface-active\/70{background-color:#dcdcdeb3}@supports (color:color-mix(in lab, red, red)){.bg-surface-active\/70{background-color:color-mix(in oklab, var(--color-surface-active) 70%, transparent)}}.bg-surface-base{background-color:var(--color-surface-base)}.bg-surface-base\/40{background-color:#f5f5f766}@supports (color:color-mix(in lab, red, red)){.bg-surface-base\/40{background-color:color-mix(in oklab, var(--color-surface-base) 40%, transparent)}}.bg-surface-base\/80{background-color:#f5f5f7cc}@supports (color:color-mix(in lab, red, red)){.bg-surface-base\/80{background-color:color-mix(in oklab, var(--color-surface-base) 80%, transparent)}}.bg-surface-hover{background-color:var(--color-surface-hover)}.bg-surface-hover\/20{background-color:#e8e8ed33}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/20{background-color:color-mix(in oklab, var(--color-surface-hover) 20%, transparent)}}.bg-surface-hover\/25{background-color:#e8e8ed40}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/25{background-color:color-mix(in oklab, var(--color-surface-hover) 25%, transparent)}}.bg-surface-hover\/30{background-color:#e8e8ed4d}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/30{background-color:color-mix(in oklab, var(--color-surface-hover) 30%, transparent)}}.bg-surface-hover\/35{background-color:#e8e8ed59}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/35{background-color:color-mix(in oklab, var(--color-surface-hover) 35%, transparent)}}.bg-surface-hover\/40{background-color:#e8e8ed66}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/40{background-color:color-mix(in oklab, var(--color-surface-hover) 40%, transparent)}}.bg-surface-hover\/45{background-color:#e8e8ed73}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/45{background-color:color-mix(in oklab, var(--color-surface-hover) 45%, transparent)}}.bg-surface-hover\/50{background-color:#e8e8ed80}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/50{background-color:color-mix(in oklab, var(--color-surface-hover) 50%, transparent)}}.bg-surface-hover\/60{background-color:#e8e8ed99}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/60{background-color:color-mix(in oklab, var(--color-surface-hover) 60%, transparent)}}.bg-surface-hover\/70{background-color:#e8e8edb3}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/70{background-color:color-mix(in oklab, var(--color-surface-hover) 70%, transparent)}}.bg-surface-hover\/80{background-color:#e8e8edcc}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/80{background-color:color-mix(in oklab, var(--color-surface-hover) 80%, transparent)}}.bg-surface-hover\/90{background-color:#e8e8ede6}@supports (color:color-mix(in lab, red, red)){.bg-surface-hover\/90{background-color:color-mix(in oklab, var(--color-surface-hover) 90%, transparent)}}.bg-surface-panel{background-color:var(--color-surface-panel)}.bg-surface-panel\/40{background-color:#fff6}@supports (color:color-mix(in lab, red, red)){.bg-surface-panel\/40{background-color:color-mix(in oklab, var(--color-surface-panel) 40%, transparent)}}.bg-surface-panel\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-surface-panel\/60{background-color:color-mix(in oklab, var(--color-surface-panel) 60%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.\[fill\:var\(--color-fg\)\]{fill:var(--color-fg)}.fill-edge{fill:var(--color-edge)}.\[stroke\:var\(--color-accent\)\]{stroke:var(--color-accent)}.stroke-\[1\.75\]{stroke-width:1.75px}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing) * 0)}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:calc(var(--spacing) * 0)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-8{padding-top:calc(var(--spacing) * 8)}.pt-\[min\(20vh\,8rem\)\]{padding-top:min(20vh,8rem)}.pr-0{padding-right:calc(var(--spacing) * 0)}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-14{padding-right:calc(var(--spacing) * 14)}.pr-20{padding-right:calc(var(--spacing) * 20)}.pb-0{padding-bottom:calc(var(--spacing) * 0)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-8{padding-bottom:calc(var(--spacing) * 8)}.pl-0{padding-left:calc(var(--spacing) * 0)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.pl-9{padding-left:calc(var(--spacing) * 9)}.pl-10{padding-left:calc(var(--spacing) * 10)}.\[text-align\:inherit\]{text-align:inherit}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.8125rem\]{font-size:.8125rem}.text-\[0\.9375rem\]{font-size:.9375rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.text-balance{text-wrap:balance}.text-pretty{text-wrap:pretty}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-accent{color:var(--color-accent)}.text-accent-fg{color:var(--color-accent-fg)}.text-amber-600{color:var(--color-amber-600)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-amber-950{color:var(--color-amber-950)}.text-blue-600{color:var(--color-blue-600)}.text-blue-800{color:var(--color-blue-800)}.text-current{color:currentColor}.text-danger{color:var(--color-danger)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-800{color:var(--color-emerald-800)}.text-fg{color:var(--color-fg)}.text-fg-disabled{color:var(--color-fg-disabled)}.text-fg-muted{color:var(--color-fg-muted)}.text-fg-muted\/25{color:#6e6e7340}@supports (color:color-mix(in lab, red, red)){.text-fg-muted\/25{color:color-mix(in oklab, var(--color-fg-muted) 25%, transparent)}}.text-fg-subtle{color:var(--color-fg-subtle)}.text-green-600{color:var(--color-green-600)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-red-900{color:var(--color-red-900)}.text-success{color:var(--color-success)}.text-surface-panel{color:var(--color-surface-panel)}.text-white{color:var(--color-white)}.text-yellow-600{color:var(--color-yellow-600)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.decoration-accent-fg\/40{text-decoration-color:#2563eb66}@supports (color:color-mix(in lab, red, red)){.decoration-accent-fg\/40{-webkit-text-decoration-color:color-mix(in oklab, var(--color-accent-fg) 40%, transparent);-webkit-text-decoration-color:color-mix(in oklab, var(--color-accent-fg) 40%, transparent);-webkit-text-decoration-color:color-mix(in oklab, var(--color-accent-fg) 40%, transparent);text-decoration-color:color-mix(in oklab, var(--color-accent-fg) 40%, transparent)}}.underline-offset-2{text-underline-offset:2px}.caret-current{caret-color:currentColor}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-90{opacity:.9}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_1px_var\(--color-accent\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--color-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-elevated{--tw-shadow:0 2px 8px var(--tw-shadow-color,#0000000f), 0 4px 24px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-float{--tw-shadow:0 4px 16px var(--tw-shadow-color,#0000001a), 0 12px 40px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-popover{--tw-shadow:0 8px 32px var(--tw-shadow-color,#0000001f), 0 2px 12px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-surface{--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000000a), 0 1px 6px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring,.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-accent{--tw-ring-color:var(--color-accent)}.ring-accent\/25{--tw-ring-color:#2563eb40}@supports (color:color-mix(in lab, red, red)){.ring-accent\/25{--tw-ring-color:color-mix(in oklab, var(--color-accent) 25%, transparent)}}.ring-edge{--tw-ring-color:var(--color-edge)}.ring-edge-subtle\/80{--tw-ring-color:#ebebedcc}@supports (color:color-mix(in lab, red, red)){.ring-edge-subtle\/80{--tw-ring-color:color-mix(in oklab, var(--color-edge-subtle) 80%, transparent)}}.ring-edge\/35{--tw-ring-color:#d2d2d759}@supports (color:color-mix(in lab, red, red)){.ring-edge\/35{--tw-ring-color:color-mix(in oklab, var(--color-edge) 35%, transparent)}}.ring-edge\/40{--tw-ring-color:#d2d2d766}@supports (color:color-mix(in lab, red, red)){.ring-edge\/40{--tw-ring-color:color-mix(in oklab, var(--color-edge) 40%, transparent)}}.ring-offset-surface-base{--tw-ring-offset-color:var(--color-surface-base)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.backdrop-blur-\[1px\]{--tw-backdrop-blur:blur(1px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-\[2px\]{--tw-backdrop-blur:blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[border-color\,background-color\]{transition-property:border-color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[border-color\,box-shadow\]{transition-property:border-color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,background-color\,border-color\,opacity\]{transition-property:color,background-color,border-color,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,background-color\,border-color\]{transition-property:color,background-color,border-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,background-color\,box-shadow\]{transition-property:color,background-color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,box-shadow\]{transition-property:transform,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,width\,height\]{transition-property:transform,width,height;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.\[transition-timing-function\:cubic-bezier\(0\.32\,0\.72\,0\,1\)\]{transition-timing-function:cubic-bezier(.32,.72,0,1)}.will-change-transform{will-change:transform}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[-ms-overflow-style\:none\]{-ms-overflow-style:none}.\[-webkit-app-region\:drag\]{-webkit-app-region:drag}.\[-webkit-app-region\:no-drag\]{-webkit-app-region:no-drag}.\[backface-visibility\:hidden\]{backface-visibility:hidden}.\[fill-opacity\:0\.82\]{fill-opacity:.82}.\[scrollbar-gutter\:stable\]{scrollbar-gutter:stable}.\[scrollbar-width\:none\]{scrollbar-width:none}.ring-inset{--tw-ring-inset:inset}.group-open\:rotate-180:is(:where(.group):is([open],:popover-open,:open) *){rotate:180deg}.group-open\:text-fg-muted:is(:where(.group):is([open],:popover-open,:open) *){color:var(--color-fg-muted)}@media (hover:hover){.group-hover\:-translate-y-px:is(:where(.group):hover *){--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\:bg-black\/25:is(:where(.group):hover *){background-color:#00000040}@supports (color:color-mix(in lab, red, red)){.group-hover\:bg-black\/25:is(:where(.group):hover *){background-color:color-mix(in oklab, var(--color-black) 25%, transparent)}}.group-hover\:text-fg:is(:where(.group):hover *){color:var(--color-fg)}.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\:ring-edge\/55:is(:where(.group):hover *){--tw-ring-color:#d2d2d78c}@supports (color:color-mix(in lab, red, red)){.group-hover\:ring-edge\/55:is(:where(.group):hover *){--tw-ring-color:color-mix(in oklab, var(--color-edge) 55%, transparent)}}}.placeholder\:text-fg-disabled::placeholder{color:var(--color-fg-disabled)}.placeholder\:text-fg-muted::placeholder{color:var(--color-fg-muted)}.placeholder\:text-fg-subtle::placeholder{color:var(--color-fg-subtle)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:bottom-0:after{content:var(--tw-content);bottom:calc(var(--spacing) * 0)}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.after\:w-9:after{content:var(--tw-content);width:calc(var(--spacing) * 9)}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.after\:rounded-full:after{content:var(--tw-content);border-radius:3.40282e38px}.after\:bg-accent:after{content:var(--tw-content);background-color:var(--color-accent)}.last\:mb-0:last-child{margin-bottom:calc(var(--spacing) * 0)}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.open\:pb-3:is([open],:popover-open,:open){padding-bottom:calc(var(--spacing) * 3)}.focus-within\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:border-accent:hover{border-color:var(--color-accent)}.hover\:border-accent\/40:hover{border-color:#2563eb66}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/40:hover{border-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.hover\:border-accent\/50:hover{border-color:#2563eb80}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/50:hover{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.hover\:border-edge:hover{border-color:var(--color-edge)}.hover\:border-edge-strong:hover{border-color:var(--color-edge-strong)}.hover\:border-edge-subtle:hover{border-color:var(--color-edge-subtle)}.hover\:bg-accent-hover:hover{background-color:var(--color-accent-hover)}.hover\:bg-accent-soft:hover{background-color:var(--color-accent-soft)}.hover\:bg-accent-soft\/50:hover{background-color:#eff6ff80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-soft\/50:hover{background-color:color-mix(in oklab, var(--color-accent-soft) 50%, transparent)}}.hover\:bg-accent-soft\/60:hover{background-color:#eff6ff99}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-soft\/60:hover{background-color:color-mix(in oklab, var(--color-accent-soft) 60%, transparent)}}.hover\:bg-accent-soft\/80:hover{background-color:#eff6ffcc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-soft\/80:hover{background-color:color-mix(in oklab, var(--color-accent-soft) 80%, transparent)}}.hover\:bg-accent-soft\/90:hover{background-color:#eff6ffe6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent-soft\/90:hover{background-color:color-mix(in oklab, var(--color-accent-soft) 90%, transparent)}}.hover\:bg-accent\/15:hover{background-color:#2563eb26}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/15:hover{background-color:color-mix(in oklab, var(--color-accent) 15%, transparent)}}.hover\:bg-accent\/90:hover{background-color:#2563ebe6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/90:hover{background-color:color-mix(in oklab, var(--color-accent) 90%, transparent)}}.hover\:bg-danger\/90:hover{background-color:#dc2626e6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-danger\/90:hover{background-color:color-mix(in oklab, var(--color-danger) 90%, transparent)}}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-red-500\/10:hover{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-500\/10:hover{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.hover\:bg-red-500\/15:hover{background-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-500\/15:hover{background-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-surface-active:hover{background-color:var(--color-surface-active)}.hover\:bg-surface-active\/70:hover{background-color:#dcdcdeb3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-active\/70:hover{background-color:color-mix(in oklab, var(--color-surface-active) 70%, transparent)}}.hover\:bg-surface-base:hover{background-color:var(--color-surface-base)}.hover\:bg-surface-hover:hover{background-color:var(--color-surface-hover)}.hover\:bg-surface-hover\/40:hover{background-color:#e8e8ed66}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/40:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 40%, transparent)}}.hover\:bg-surface-hover\/45:hover{background-color:#e8e8ed73}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/45:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 45%, transparent)}}.hover\:bg-surface-hover\/50:hover{background-color:#e8e8ed80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/50:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 50%, transparent)}}.hover\:bg-surface-hover\/60:hover{background-color:#e8e8ed99}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/60:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 60%, transparent)}}.hover\:bg-surface-hover\/70:hover{background-color:#e8e8edb3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/70:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 70%, transparent)}}.hover\:bg-surface-hover\/80:hover{background-color:#e8e8edcc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/80:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 80%, transparent)}}.hover\:bg-surface-hover\/90:hover{background-color:#e8e8ede6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-hover\/90:hover{background-color:color-mix(in oklab, var(--color-surface-hover) 90%, transparent)}}.hover\:bg-surface-panel:hover{background-color:var(--color-surface-panel)}.hover\:bg-surface-panel\/60:hover{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.hover\:bg-surface-panel\/60:hover{background-color:color-mix(in oklab, var(--color-surface-panel) 60%, transparent)}}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-accent-fg:hover{color:var(--color-accent-fg)}.hover\:text-fg:hover{color:var(--color-fg)}.hover\:text-fg-muted:hover{color:var(--color-fg-muted)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:underline:hover{text-decoration-line:underline}.hover\:decoration-accent-fg:hover{-webkit-text-decoration-color:var(--color-accent-fg);-webkit-text-decoration-color:var(--color-accent-fg);-webkit-text-decoration-color:var(--color-accent-fg);text-decoration-color:var(--color-accent-fg)}.hover\:opacity-90:hover{opacity:.9}.hover\:opacity-95:hover{opacity:.95}}.focus\:not-sr-only:focus{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.focus\:absolute:focus{position:absolute}.focus\:top-3:focus{top:calc(var(--spacing) * 3)}.focus\:left-4:focus{left:calc(var(--spacing) * 4)}.focus\:border-0:focus{border-style:var(--tw-border-style);border-width:0}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:border-edge-strong:focus{border-color:var(--color-edge-strong)}.focus\:opacity-100:focus{opacity:1}.focus\:shadow-none:focus{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-0:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-accent:focus{--tw-ring-color:var(--color-accent)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:border-edge:focus-visible{border-color:var(--color-edge)}.focus-visible\:border-edge-strong:focus-visible{border-color:var(--color-edge-strong)}.focus-visible\:shadow-none:focus-visible{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-accent:focus-visible{--tw-ring-color:var(--color-accent)}.focus-visible\:ring-accent\/40:focus-visible{--tw-ring-color:#2563eb66}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-accent\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-accent) 40%, transparent)}}.focus-visible\:ring-red-500\/40:focus-visible{--tw-ring-color:#fb2c3666}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-red-500\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-red-500) 40%, transparent)}}.focus-visible\:ring-offset-0:focus-visible{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-surface-base:focus-visible{--tw-ring-offset-color:var(--color-surface-base)}.focus-visible\:ring-offset-surface-panel:focus-visible{--tw-ring-offset-color:var(--color-surface-panel)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-100:active{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:scale-\[0\.97\]:active{scale:.97}.active\:scale-\[0\.99\]:active{scale:.99}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-25:disabled{opacity:.25}.disabled\:opacity-35:disabled{opacity:.35}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.disabled\:opacity-100:disabled{opacity:1}.data-highlighted\:bg-red-500\/10[data-highlighted]{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.data-highlighted\:bg-red-500\/10[data-highlighted]{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.data-highlighted\:bg-surface-hover[data-highlighted]{background-color:var(--color-surface-hover)}.data-\[highlighted\]\:bg-red-50[data-highlighted]{background-color:var(--color-red-50)}.data-\[highlighted\]\:bg-surface-hover[data-highlighted]{background-color:var(--color-surface-hover)}.data-\[state\=open\]\:border-edge[data-state=open]{border-color:var(--color-edge)}@media (prefers-reduced-motion:reduce){.motion-reduce\:animate-none{animation:none}.motion-reduce\:opacity-100{opacity:1}.motion-reduce\:\!transition-none{transition-property:none!important}.motion-reduce\:transition-none{transition-property:none}.motion-reduce\:\!duration-0{--tw-duration:0s!important;transition-duration:0s!important}.motion-reduce\:active\:scale-100:active{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}@media not all and (min-width:48rem){.max-md\:pointer-events-none{pointer-events:none}.max-md\:fixed{position:fixed}.max-md\:top-0{top:calc(var(--spacing) * 0)}.max-md\:right-0{right:calc(var(--spacing) * 0)}.max-md\:left-0{left:calc(var(--spacing) * 0)}.max-md\:z-50{z-index:50}.max-md\:hidden{display:none}.max-md\:h-\[100dvh\]{height:100dvh}.max-md\:w-\[min\(16rem\,85vw\)\]{width:min(16rem,85vw)}.max-md\:w-\[min\(20rem\,92vw\)\]{width:min(20rem,92vw)}.max-md\:-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.max-md\:translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.max-md\:translate-x-full{--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.max-md\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.max-md\:border-edge{border-color:var(--color-edge)}.max-md\:shadow-popover{--tw-shadow:0 8px 32px var(--tw-shadow-color,#0000001f), 0 2px 12px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.max-md\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.max-md\:duration-200{--tw-duration:.2s;transition-duration:.2s}.max-md\:ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}}@media (prefers-reduced-motion:reduce){@media not all and (min-width:48rem){.motion-reduce\:max-md\:transition-none{transition-property:none}}}@media (min-width:40rem){.sm\:not-sr-only{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.sm\:inset-auto{inset:auto}.sm\:top-1\/2{top:50%}.sm\:top-4{top:calc(var(--spacing) * 4)}.sm\:right-2{right:calc(var(--spacing) * 2)}.sm\:right-3{right:calc(var(--spacing) * 3)}.sm\:right-4{right:calc(var(--spacing) * 4)}.sm\:left-1\/2{left:50%}.sm\:order-1{order:1}.sm\:order-2{order:2}.sm\:col-span-2{grid-column:span 2/span 2}.sm\:mt-0{margin-top:calc(var(--spacing) * 0)}.sm\:mt-12{margin-top:calc(var(--spacing) * 12)}.sm\:mr-auto{margin-right:auto}.sm\:ml-0{margin-left:calc(var(--spacing) * 0)}.sm\:ml-2\.5{margin-left:calc(var(--spacing) * 2.5)}.sm\:ml-auto{margin-left:auto}.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.sm\:size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.sm\:size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.sm\:h-\[min\(88vh\,48rem\)\]{height:min(88vh,48rem)}.sm\:max-h-\[min\(88vh\,48rem\)\]{max-height:min(88vh,48rem)}.sm\:min-h-9{min-height:calc(var(--spacing) * 9)}.sm\:min-h-10{min-height:calc(var(--spacing) * 10)}.sm\:min-h-\[32rem\]{min-height:32rem}.sm\:w-9{width:calc(var(--spacing) * 9)}.sm\:w-48{width:calc(var(--spacing) * 48)}.sm\:w-56{width:calc(var(--spacing) * 56)}.sm\:w-\[5\.25rem\]{width:5.25rem}.sm\:w-\[min\(100\%\,14rem\)\]{width:min(100%,14rem)}.sm\:w-\[min\(100\%-2rem\,58rem\)\]{width:min(100% - 2rem,58rem)}.sm\:w-auto{width:auto}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-\[11rem\]{max-width:11rem}.sm\:max-w-\[12rem\]{max-width:12rem}.sm\:max-w-\[14rem\]{max-width:14rem}.sm\:max-w-\[17rem\]{max-width:17rem}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:min-w-0{min-width:calc(var(--spacing) * 0)}.sm\:min-w-\[7\.5rem\]{min-width:7.5rem}.sm\:min-w-\[7rem\]{min-width:7rem}.sm\:min-w-\[11rem\]{min-width:11rem}.sm\:min-w-\[12rem\]{min-width:12rem}.sm\:flex-1{flex:1}.sm\:shrink-0{flex-shrink:0}.sm\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sm\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:flex-col{flex-direction:column}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:items-center{align-items:center}.sm\:items-end{align-items:flex-end}.sm\:items-start{align-items:flex-start}.sm\:items-stretch{align-items:stretch}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:justify-start{justify-content:flex-start}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:gap-2\.5{gap:calc(var(--spacing) * 2.5)}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:gap-4{gap:calc(var(--spacing) * 4)}.sm\:gap-6{gap:calc(var(--spacing) * 6)}.sm\:self-center{align-self:center}.sm\:overflow-hidden{overflow:hidden}.sm\:overflow-y-auto{overflow-y:auto}.sm\:border-x{border-inline-style:var(--tw-border-style);border-inline-width:1px}.sm\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.sm\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.sm\:border-edge{border-color:var(--color-edge)}.sm\:p-8{padding:calc(var(--spacing) * 8)}.sm\:px-0{padding-inline:calc(var(--spacing) * 0)}.sm\:px-2{padding-inline:calc(var(--spacing) * 2)}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:px-5{padding-inline:calc(var(--spacing) * 5)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-8{padding-inline:calc(var(--spacing) * 8)}.sm\:px-12{padding-inline:calc(var(--spacing) * 12)}.sm\:py-3{padding-block:calc(var(--spacing) * 3)}.sm\:py-4{padding-block:calc(var(--spacing) * 4)}.sm\:py-10{padding-block:calc(var(--spacing) * 10)}.sm\:pt-10{padding-top:calc(var(--spacing) * 10)}.sm\:pr-3{padding-right:calc(var(--spacing) * 3)}.sm\:pr-5{padding-right:calc(var(--spacing) * 5)}.sm\:pr-16{padding-right:calc(var(--spacing) * 16)}.sm\:pb-3{padding-bottom:calc(var(--spacing) * 3)}.sm\:pl-2{padding-left:calc(var(--spacing) * 2)}.sm\:pl-4{padding-left:calc(var(--spacing) * 4)}.sm\:text-left{text-align:left}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.sm\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.sm\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.sm\:text-\[0\.9375rem\]{font-size:.9375rem}}@media (min-width:48rem){.md\:pointer-events-none{pointer-events:none}.md\:relative{position:relative}.md\:right-10{right:calc(var(--spacing) * 10)}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:inline-flex{display:inline-flex}.md\:h-full{height:100%}.md\:max-h-none{max-height:none}.md\:min-h-0{min-height:calc(var(--spacing) * 0)}.md\:w-0{width:calc(var(--spacing) * 0)}.md\:w-80{width:calc(var(--spacing) * 80)}.md\:w-\[4\.5rem\]{width:4.5rem}.md\:max-w-0{max-width:calc(var(--spacing) * 0)}.md\:max-w-80{max-width:calc(var(--spacing) * 80)}.md\:min-w-0{min-width:calc(var(--spacing) * 0)}.md\:flex-1{flex:1}.md\:shrink-0{flex-shrink:0}.md\:translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.md\:flex-row{flex-direction:row}.md\:overflow-hidden{overflow:hidden}.md\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.md\:border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.md\:border-edge{border-color:var(--color-edge)}.md\:pb-4{padding-bottom:calc(var(--spacing) * 4)}.md\:text-center{text-align:center}.md\:transition-\[width\,max-width\]{transition-property:width,max-width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.md\:duration-300{--tw-duration:.3s;transition-duration:.3s}.md\:ease-\[cubic-bezier\(0\.22\,1\,0\.36\,1\)\]{--tw-ease:cubic-bezier(.22,1,.36,1);transition-timing-function:cubic-bezier(.22,1,.36,1)}}@media (prefers-reduced-motion:reduce){@media (min-width:48rem){.motion-reduce\:md\:transition-none{transition-property:none}}}@media (min-width:64rem){.lg\:inline{display:inline}.lg\:max-w-app-main{max-width:var(--max-width-app-main)}.lg\:max-w-xl{max-width:var(--container-xl)}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (min-width:80rem){.xl\:px-6{padding-inline:calc(var(--spacing) * 6)}}:where(.dark\:divide-edge:where(.dark,.dark *)>:not(:last-child)){border-color:var(--color-edge)}.dark\:border-accent\/30:where(.dark,.dark *){border-color:#2563eb4d}@supports (color:color-mix(in lab, red, red)){.dark\:border-accent\/30:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.dark\:border-amber-800:where(.dark,.dark *){border-color:var(--color-amber-800)}.dark\:border-amber-900\/40:where(.dark,.dark *){border-color:#7b330666}@supports (color:color-mix(in lab, red, red)){.dark\:border-amber-900\/40:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-amber-900) 40%, transparent)}}.dark\:border-blue-900\/50:where(.dark,.dark *){border-color:#1c398e80}@supports (color:color-mix(in lab, red, red)){.dark\:border-blue-900\/50:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-blue-900) 50%, transparent)}}.dark\:border-danger\/40:where(.dark,.dark *){border-color:#dc262666}@supports (color:color-mix(in lab, red, red)){.dark\:border-danger\/40:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-danger) 40%, transparent)}}.dark\:border-edge:where(.dark,.dark *){border-color:var(--color-edge)}.dark\:border-edge-subtle:where(.dark,.dark *){border-color:var(--color-edge-subtle)}.dark\:border-edge-subtle\/70:where(.dark,.dark *){border-color:#ebebedb3}@supports (color:color-mix(in lab, red, red)){.dark\:border-edge-subtle\/70:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-edge-subtle) 70%, transparent)}}.dark\:border-edge-subtle\/90:where(.dark,.dark *){border-color:#ebebede6}@supports (color:color-mix(in lab, red, red)){.dark\:border-edge-subtle\/90:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-edge-subtle) 90%, transparent)}}.dark\:border-emerald-900\/40:where(.dark,.dark *){border-color:#004e3b66}@supports (color:color-mix(in lab, red, red)){.dark\:border-emerald-900\/40:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-emerald-900) 40%, transparent)}}.dark\:border-red-800:where(.dark,.dark *){border-color:var(--color-red-800)}.dark\:border-red-900\/40:where(.dark,.dark *){border-color:#82181a66}@supports (color:color-mix(in lab, red, red)){.dark\:border-red-900\/40:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-red-900) 40%, transparent)}}.dark\:border-red-900\/50:where(.dark,.dark *){border-color:#82181a80}@supports (color:color-mix(in lab, red, red)){.dark\:border-red-900\/50:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-red-900) 50%, transparent)}}.dark\:border-red-900\/60:where(.dark,.dark *){border-color:#82181a99}@supports (color:color-mix(in lab, red, red)){.dark\:border-red-900\/60:where(.dark,.dark *){border-color:color-mix(in oklab, var(--color-red-900) 60%, transparent)}}.dark\:bg-\[\#1e1e1e\]:where(.dark,.dark *){background-color:#1e1e1e}.dark\:bg-accent-soft\/25:where(.dark,.dark *){background-color:#eff6ff40}@supports (color:color-mix(in lab, red, red)){.dark\:bg-accent-soft\/25:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-accent-soft) 25%, transparent)}}.dark\:bg-accent-soft\/35:where(.dark,.dark *){background-color:#eff6ff59}@supports (color:color-mix(in lab, red, red)){.dark\:bg-accent-soft\/35:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-accent-soft) 35%, transparent)}}.dark\:bg-accent-soft\/40:where(.dark,.dark *){background-color:#eff6ff66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-accent-soft\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-accent-soft) 40%, transparent)}}.dark\:bg-accent\/10:where(.dark,.dark *){background-color:#2563eb1a}@supports (color:color-mix(in lab, red, red)){.dark\:bg-accent\/10:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.dark\:bg-amber-950\/30:where(.dark,.dark *){background-color:#4619014d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-950\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-amber-950) 30%, transparent)}}.dark\:bg-amber-950\/40:where(.dark,.dark *){background-color:#46190166}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-950\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-amber-950) 40%, transparent)}}.dark\:bg-amber-950\/50:where(.dark,.dark *){background-color:#46190180}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-950\/50:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-amber-950) 50%, transparent)}}.dark\:bg-black\/60:where(.dark,.dark *){background-color:#0009}@supports (color:color-mix(in lab, red, red)){.dark\:bg-black\/60:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.dark\:bg-blue-950:where(.dark,.dark *){background-color:var(--color-blue-950)}.dark\:bg-blue-950\/40:where(.dark,.dark *){background-color:#16245666}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-950\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-blue-950) 40%, transparent)}}.dark\:bg-blue-950\/45:where(.dark,.dark *){background-color:#16245673}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-950\/45:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-blue-950) 45%, transparent)}}.dark\:bg-emerald-950:where(.dark,.dark *){background-color:var(--color-emerald-950)}.dark\:bg-emerald-950\/40:where(.dark,.dark *){background-color:#002c2266}@supports (color:color-mix(in lab, red, red)){.dark\:bg-emerald-950\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-emerald-950) 40%, transparent)}}.dark\:bg-fg:where(.dark,.dark *){background-color:var(--color-fg)}.dark\:bg-red-500\/25:where(.dark,.dark *){background-color:#fb2c3640}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-500\/25:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-red-500) 25%, transparent)}}.dark\:bg-red-950\/40:where(.dark,.dark *){background-color:#46080966}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-950\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-red-950) 40%, transparent)}}.dark\:bg-red-950\/50:where(.dark,.dark *){background-color:#46080980}@supports (color:color-mix(in lab, red, red)){.dark\:bg-red-950\/50:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-red-950) 50%, transparent)}}.dark\:bg-surface-active:where(.dark,.dark *){background-color:var(--color-surface-active)}.dark\:bg-surface-active\/50:where(.dark,.dark *){background-color:#dcdcde80}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-active\/50:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-active) 50%, transparent)}}.dark\:bg-surface-active\/80:where(.dark,.dark *){background-color:#dcdcdecc}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-active\/80:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-active) 80%, transparent)}}.dark\:bg-surface-base\/20:where(.dark,.dark *){background-color:#f5f5f733}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-base\/20:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-base) 20%, transparent)}}.dark\:bg-surface-hover\/15:where(.dark,.dark *){background-color:#e8e8ed26}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/15:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 15%, transparent)}}.dark\:bg-surface-hover\/20:where(.dark,.dark *){background-color:#e8e8ed33}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/20:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 20%, transparent)}}.dark\:bg-surface-hover\/25:where(.dark,.dark *){background-color:#e8e8ed40}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/25:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 25%, transparent)}}.dark\:bg-surface-hover\/30:where(.dark,.dark *){background-color:#e8e8ed4d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/30:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 30%, transparent)}}.dark\:bg-surface-hover\/35:where(.dark,.dark *){background-color:#e8e8ed59}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/35:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 35%, transparent)}}.dark\:bg-surface-hover\/40:where(.dark,.dark *){background-color:#e8e8ed66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/40:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 40%, transparent)}}.dark\:bg-surface-hover\/50:where(.dark,.dark *){background-color:#e8e8ed80}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/50:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 50%, transparent)}}.dark\:bg-surface-hover\/70:where(.dark,.dark *){background-color:#e8e8edb3}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/70:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 70%, transparent)}}.dark\:bg-surface-hover\/80:where(.dark,.dark *){background-color:#e8e8edcc}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-hover\/80:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-hover) 80%, transparent)}}.dark\:bg-surface-panel:where(.dark,.dark *){background-color:var(--color-surface-panel)}.dark\:bg-surface-panel\/60:where(.dark,.dark *){background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-panel\/60:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-panel) 60%, transparent)}}.dark\:bg-surface-panel\/95:where(.dark,.dark *){background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.dark\:bg-surface-panel\/95:where(.dark,.dark *){background-color:color-mix(in oklab, var(--color-surface-panel) 95%, transparent)}}.dark\:text-accent-fg:where(.dark,.dark *){color:var(--color-accent-fg)}.dark\:text-amber-100:where(.dark,.dark *){color:var(--color-amber-100)}.dark\:text-amber-200:where(.dark,.dark *){color:var(--color-amber-200)}.dark\:text-amber-400:where(.dark,.dark *){color:var(--color-amber-400)}.dark\:text-blue-200:where(.dark,.dark *){color:var(--color-blue-200)}.dark\:text-blue-400:where(.dark,.dark *){color:var(--color-blue-400)}.dark\:text-emerald-200:where(.dark,.dark *){color:var(--color-emerald-200)}.dark\:text-emerald-300:where(.dark,.dark *){color:var(--color-emerald-300)}.dark\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.dark\:text-green-400:where(.dark,.dark *){color:var(--color-green-400)}.dark\:text-red-100:where(.dark,.dark *){color:var(--color-red-100)}.dark\:text-red-200:where(.dark,.dark *){color:var(--color-red-200)}.dark\:text-red-300:where(.dark,.dark *){color:var(--color-red-300)}.dark\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.dark\:text-surface-panel:where(.dark,.dark *){color:var(--color-surface-panel)}.dark\:text-yellow-400:where(.dark,.dark *){color:var(--color-yellow-400)}.dark\:shadow-elevated:where(.dark,.dark *){--tw-shadow:0 2px 8px var(--tw-shadow-color,#0000000f), 0 4px 24px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.dark\:shadow-none:where(.dark,.dark *){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.dark\:shadow-sm:where(.dark,.dark *){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.dark\:ring-1:where(.dark,.dark *){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.dark\:ring-edge-strong\/40:where(.dark,.dark *){--tw-ring-color:#bcbcc066}@supports (color:color-mix(in lab, red, red)){.dark\:ring-edge-strong\/40:where(.dark,.dark *){--tw-ring-color:color-mix(in oklab, var(--color-edge-strong) 40%, transparent)}}.dark\:ring-edge-subtle:where(.dark,.dark *){--tw-ring-color:var(--color-edge-subtle)}.dark\:ring-edge\/50:where(.dark,.dark *){--tw-ring-color:#d2d2d780}@supports (color:color-mix(in lab, red, red)){.dark\:ring-edge\/50:where(.dark,.dark *){--tw-ring-color:color-mix(in oklab, var(--color-edge) 50%, transparent)}}.dark\:ring-edge\/55:where(.dark,.dark *){--tw-ring-color:#d2d2d78c}@supports (color:color-mix(in lab, red, red)){.dark\:ring-edge\/55:where(.dark,.dark *){--tw-ring-color:color-mix(in oklab, var(--color-edge) 55%, transparent)}}@media (hover:hover){.dark\:group-hover\:ring-edge\/65:where(.dark,.dark *):is(:where(.group):hover *){--tw-ring-color:#d2d2d7a6}@supports (color:color-mix(in lab, red, red)){.dark\:group-hover\:ring-edge\/65:where(.dark,.dark *):is(:where(.group):hover *){--tw-ring-color:color-mix(in oklab, var(--color-edge) 65%, transparent)}}.dark\:hover\:border-edge:where(.dark,.dark *):hover{border-color:var(--color-edge)}.dark\:hover\:bg-accent-soft:where(.dark,.dark *):hover{background-color:var(--color-accent-soft)}.dark\:hover\:bg-black\/70:where(.dark,.dark *):hover{background-color:#000000b3}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-black\/70:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-black) 70%, transparent)}}.dark\:hover\:bg-red-950\/40:where(.dark,.dark *):hover{background-color:#46080966}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-red-950\/40:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-red-950) 40%, transparent)}}.dark\:hover\:bg-red-950\/70:where(.dark,.dark *):hover{background-color:#460809b3}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-red-950\/70:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-red-950) 70%, transparent)}}.dark\:hover\:bg-surface-hover\/25:where(.dark,.dark *):hover{background-color:#e8e8ed40}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-surface-hover\/25:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-surface-hover) 25%, transparent)}}.dark\:hover\:bg-surface-hover\/30:where(.dark,.dark *):hover{background-color:#e8e8ed4d}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-surface-hover\/30:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-surface-hover) 30%, transparent)}}.dark\:hover\:bg-surface-hover\/50:where(.dark,.dark *):hover{background-color:#e8e8ed80}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-surface-hover\/50:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-surface-hover) 50%, transparent)}}.dark\:hover\:bg-surface-hover\/55:where(.dark,.dark *):hover{background-color:#e8e8ed8c}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-surface-hover\/55:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-surface-hover) 55%, transparent)}}.dark\:hover\:bg-surface-panel\/40:where(.dark,.dark *):hover{background-color:#fff6}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-surface-panel\/40:where(.dark,.dark *):hover{background-color:color-mix(in oklab, var(--color-surface-panel) 40%, transparent)}}.dark\:hover\:text-red-400:where(.dark,.dark *):hover{color:var(--color-red-400)}}@media not all and (min-width:48rem){.max-md\:dark\:border-edge:where(.dark,.dark *){border-color:var(--color-edge)}}@media (min-width:40rem){.dark\:sm\:border-edge:where(.dark,.dark *){border-color:var(--color-edge)}}@media (min-width:48rem){.md\:dark\:border-edge:where(.dark,.dark *){border-color:var(--color-edge)}}.\[\&_\.markdown-body\]\:text-sm .markdown-body{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.\[\&_\.markdown-body\]\:leading-snug .markdown-body{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}.\[\&\:\:-webkit-scrollbar\]\:hidden::-webkit-scrollbar{display:none}.\[\&\>\*\]\:min-h-0>*{min-height:calc(var(--spacing) * 0)}.\[\&\>\*\]\:flex-1>*{flex:1}.\[\&\>div\]\:border-0>div{border-style:var(--tw-border-style);border-width:0}.\[\&\>div\]\:pt-0>div{padding-top:calc(var(--spacing) * 0)}}html.dark{--color-surface-base:#1c1c1e;--color-surface-panel:#2c2c2e;--color-surface-hover:#3a3a3c;--color-surface-active:#48484a;--color-fg:#f5f5f7;--color-fg-muted:#a1a1a6;--color-fg-subtle:#8e8e93;--color-fg-disabled:#636366;--color-edge-subtle:#3a3a3c;--color-edge:#48484a;--color-edge-strong:#636366;--color-accent:#3b82f6;--color-accent-hover:#60a5fa;--color-accent-soft:#1e3a8a8c;--color-accent-fg:#60a5fa;--color-checkbox-accent:#c7c7cc;--color-success:#34d399;--color-success-soft:#064e3b80;--color-danger:#f87171;--color-danger-soft:#7f1d1d80;--color-warning:#fbbf24;--color-warning-soft:#713f1280;--color-scrim:#00000085;--shadow-surface:0 0 0 1px #ffffff0f;--shadow-elevated:0 8px 32px #00000073;--shadow-float:0 12px 48px #0000008c;--shadow-popover:0 16px 48px #00000080}.app-sidebar-push{transform:translateZ(0)}@media (min-width:768px){.app-sidebar-push{transition:width .2s cubic-bezier(.4,0,.2,1)}.app-sidebar-expanded-width{width:var(--sidebar-expanded-px,16rem)}}.app-sidebar-push.sidebar-width-resizing{transition:none!important}@media (prefers-reduced-motion:reduce){.app-sidebar-push{transition:none}}@media (min-width:768px){.settings-page-rail{width:var(--sidebar-expanded-px,16rem);transition:width .2s cubic-bezier(.4,0,.2,1);transform:translateZ(0)}}.settings-page-rail.settings-page-rail-resizing{transition:none!important}@media (prefers-reduced-motion:reduce){.settings-page-rail{transition:none}}@keyframes page-enter{0%{opacity:0;transform:translateY(4px)translateZ(0)}to{opacity:1;transform:translateY(0)translateZ(0)}}.page-enter{animation:.2s both page-enter}.page-enter--gentle{animation-duration:.28s;animation-timing-function:cubic-bezier(.22,1,.36,1)}@media (prefers-reduced-motion:reduce){.page-enter,.page-enter--gentle{animation:none}}@media (prefers-reduced-motion:no-preference){::view-transition-old(root){animation-duration:.42s;animation-timing-function:ease}::view-transition-new(root){animation-duration:.42s;animation-timing-function:ease}}html[data-color-scheme=emerald]{--color-surface-base:#f0fdf4;--color-surface-panel:#fff;--color-surface-hover:#dcfce7;--color-surface-active:#bbf7d0;--color-fg:#052e16;--color-fg-muted:#166534;--color-fg-subtle:#15803d;--color-fg-disabled:#86efac;--color-edge-subtle:#bbf7d0;--color-edge:#86efac;--color-edge-strong:#4ade80;--color-accent:#059669;--color-accent-hover:#047857;--color-accent-soft:#d1fae5;--color-accent-fg:#047857;--color-checkbox-accent:#059669;--color-success:#059669;--color-success-soft:#d1fae5;--color-danger:#dc2626;--color-danger-soft:#fee2e2;--color-warning:#d97706;--color-warning-soft:#fef3c7;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem}html.dark[data-color-scheme=emerald]{--color-surface-base:#000;--color-surface-panel:#0a0a0a;--color-surface-hover:#111;--color-surface-active:#1a1a1a;--color-fg:#d1fae5;--color-fg-muted:#6ee7b7;--color-fg-subtle:#34d399;--color-fg-disabled:#065f46;--color-edge-subtle:#0d2818;--color-edge:#134e2a;--color-edge-strong:#166534;--color-accent:#10b981;--color-accent-hover:#34d399;--color-accent-soft:#064e3b99;--color-accent-fg:#34d399;--color-checkbox-accent:#10b981;--color-success:#34d399;--color-success-soft:#064e3b80;--color-danger:#f87171;--color-danger-soft:#7f1d1d80;--color-warning:#fbbf24;--color-warning-soft:#713f1280;--color-scrim:#000000b8;--shadow-surface:0 0 0 1px #10b9811a;--shadow-elevated:0 8px 32px #000c, 0 0 0 1px #10b98112;--shadow-float:0 12px 48px #000000e6, 0 0 0 1px #10b9810f;--shadow-popover:0 16px 48px #000000d9, 0 0 0 1px #10b9811f;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--color-edge-strong);border-radius:9999px}::-webkit-scrollbar-thumb:hover{background:var(--color-fg-subtle)}.chat-messages{scrollbar-gutter:stable;scrollbar-width:thin;scrollbar-color:#bcbcc094 transparent}@supports (color:color-mix(in lab, red, red)){.chat-messages{scrollbar-color:color-mix(in srgb, var(--color-edge-strong) 58%, transparent) transparent}}.chat-messages{overscroll-behavior-y:contain}.markdown-content{min-width:0;max-width:100%}.markdown-content .markdown-body{overflow-wrap:anywhere;word-break:break-word;min-width:0;max-width:100%}.markdown-content .markdown-body pre{box-sizing:border-box;min-width:0;max-width:100%}.markdown-content .markdown-body pre code.hljs{box-sizing:border-box;max-width:100%}.markdown-content .markdown-body table{table-layout:fixed;max-width:100%}.markdown-content .markdown-body th,.markdown-content .markdown-body td{word-break:break-word;overflow-wrap:anywhere}html.dark .chat-messages{scrollbar-color:#d2d2d7b8 transparent}@supports (color:color-mix(in lab, red, red)){html.dark .chat-messages{scrollbar-color:color-mix(in srgb, var(--color-edge) 72%, transparent) transparent}}.chat-messages::-webkit-scrollbar{width:10px}.chat-messages::-webkit-scrollbar-track{background:0 0}.chat-messages::-webkit-scrollbar-thumb{background-color:#bcbcc080;background-clip:content-box;border:3px solid #0000;border-radius:9999px}@supports (color:color-mix(in lab, red, red)){.chat-messages::-webkit-scrollbar-thumb{background-color:color-mix(in srgb, var(--color-edge-strong) 50%, transparent)}}.chat-messages::-webkit-scrollbar-thumb:hover{background-color:#86868b61}@supports (color:color-mix(in lab, red, red)){.chat-messages::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb, var(--color-fg-subtle) 38%, transparent)}}html.dark .chat-messages::-webkit-scrollbar-thumb{background-color:#d2d2d78c}@supports (color:color-mix(in lab, red, red)){html.dark .chat-messages::-webkit-scrollbar-thumb{background-color:color-mix(in srgb, var(--color-edge) 55%, transparent)}}html.dark .chat-messages::-webkit-scrollbar-thumb:hover{background-color:#6e6e7373}@supports (color:color-mix(in lab, red, red)){html.dark .chat-messages::-webkit-scrollbar-thumb:hover{background-color:color-mix(in srgb, var(--color-fg-muted) 45%, transparent)}}.app-sidebar-nav-scroll{-ms-overflow-style:none;scrollbar-width:none}.app-sidebar-nav-scroll::-webkit-scrollbar{width:0;height:0;display:none}@keyframes xopc-overlay-in{0%{opacity:0}to{opacity:1}}@keyframes xopc-drawer-in{0%{transform:translate(-100%)}to{transform:translate(0)}}@keyframes xopc-dialog-overlay-in{0%{opacity:0}to{opacity:1}}@keyframes xopc-dialog-overlay-out{0%{opacity:1}to{opacity:0}}@keyframes xopc-dialog-content-in{0%{opacity:0}to{opacity:1}}@keyframes xopc-dialog-content-out{0%{opacity:1}to{opacity:0}}@keyframes xopc-dialog-fullscreen-in{0%{opacity:0}to{opacity:1}}@keyframes xopc-dialog-fullscreen-out{0%{opacity:1}to{opacity:0}}@keyframes xopc-dialog-pane-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes xopc-dialog-pane-out{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}}@keyframes xopc-drawer-right-in{0%{opacity:.92;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes xopc-drawer-right-out{0%{opacity:1;transform:translate(0)}to{opacity:.92;transform:translate(100%)}}.xopc-dialog-overlay[data-state=open]{animation:.2s ease-out both xopc-dialog-overlay-in}.xopc-dialog-overlay[data-state=closed]{animation:.15s ease-in both xopc-dialog-overlay-out}.xopc-dialog-content[data-state=open]{animation:.25s cubic-bezier(.32,.72,0,1) both xopc-dialog-content-in}.xopc-dialog-content[data-state=closed]{animation:.2s ease-in both xopc-dialog-content-out}.xopc-dialog-content-fullscreen[data-state=open]{animation:.25s cubic-bezier(.32,.72,0,1) both xopc-dialog-fullscreen-in}.xopc-dialog-content-fullscreen[data-state=closed]{animation:.2s ease-in both xopc-dialog-fullscreen-out}.xopc-dialog-content-pane[data-state=open]{animation:.25s cubic-bezier(.32,.72,0,1) both xopc-dialog-pane-in}.xopc-dialog-content-pane[data-state=closed]{animation:.2s ease-in both xopc-dialog-pane-out}.xopc-drawer-right[data-state=open]{animation:.38s cubic-bezier(.22,1,.36,1) both xopc-drawer-right-in}.xopc-drawer-right[data-state=closed]{animation:.24s cubic-bezier(.4,0,1,1) both xopc-drawer-right-out}.xopc-mobile-nav-overlay[data-state=open]{animation:.2s ease-out both xopc-overlay-in}.xopc-mobile-nav-overlay[data-state=closed]{animation:.15s ease-in both xopc-dialog-overlay-out}.xopc-mobile-nav-content[data-state=open]{animation:.28s cubic-bezier(.32,.72,0,1) both xopc-drawer-in}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}