auramaxx 0.0.17 → 0.0.19

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 (296) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +70 -70
  3. package/.next/app-path-routes-manifest.json +2 -2
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +30 -30
  6. package/.next/react-loadable-manifest.json +16 -16
  7. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/_not-found.html +1 -1
  10. package/.next/server/app/_not-found.rsc +5 -5
  11. package/.next/server/app/api/[...doc]/page.js.nft.json +1 -1
  12. package/.next/server/app/api/[...doc]/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/agent-requests/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/apps/install/route.js.nft.json +1 -1
  15. package/.next/server/app/api/apps/install/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/apps/manifests/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/apps/static/[...path]/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/docs/plain/route.js.nft.json +1 -1
  19. package/.next/server/app/api/docs/plain/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/import-from-openclaw/[channel]/route.js.nft.json +1 -1
  22. package/.next/server/app/api/import-from-openclaw/[channel]/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/import-from-openclaw/route.js.nft.json +1 -1
  24. package/.next/server/app/api/import-from-openclaw/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/import-from-openclaw/validate/[channel]/route.js.nft.json +1 -1
  26. package/.next/server/app/api/import-from-openclaw/validate/[channel]/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/page.js.nft.json +1 -1
  28. package/.next/server/app/api/page_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/workspace/[id]/apps/[wid]/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/workspace/[id]/apps/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/workspace/[id]/export/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/workspace/[id]/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/workspace/config/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/workspace/import/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/workspace/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/app-legacy-do-not-use/page.js +3 -3
  40. package/.next/server/app/app-legacy-do-not-use/page.js.nft.json +1 -1
  41. package/.next/server/app/app-legacy-do-not-use/page_client-reference-manifest.js +1 -1
  42. package/.next/server/app/app-legacy-do-not-use.html +1 -1
  43. package/.next/server/app/app-legacy-do-not-use.rsc +6 -6
  44. package/.next/server/app/approve/[actionId]/page.js.nft.json +1 -1
  45. package/.next/server/app/approve/[actionId]/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/docs/[...doc]/page.js.nft.json +1 -1
  47. package/.next/server/app/docs/[...doc]/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/docs/page.js.nft.json +1 -1
  49. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  50. package/.next/server/app/health/page.js.nft.json +1 -1
  51. package/.next/server/app/health/page_client-reference-manifest.js +1 -1
  52. package/.next/server/app/health.html +1 -1
  53. package/.next/server/app/health.rsc +5 -5
  54. package/.next/server/app/hello/page.js.nft.json +1 -1
  55. package/.next/server/app/hello/page_client-reference-manifest.js +1 -1
  56. package/.next/server/app/hello.html +1 -1
  57. package/.next/server/app/hello.rsc +5 -5
  58. package/.next/server/app/index.html +1 -1
  59. package/.next/server/app/index.rsc +6 -6
  60. package/.next/server/app/page.js +9 -3
  61. package/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/server/app/privacy/page.js.nft.json +1 -1
  64. package/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app/privacy.html +1 -1
  66. package/.next/server/app/privacy.rsc +5 -5
  67. package/.next/server/app/share/[token]/page.js.nft.json +1 -1
  68. package/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  69. package/.next/server/app/terms/page.js.nft.json +1 -1
  70. package/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  71. package/.next/server/app/terms.html +1 -1
  72. package/.next/server/app/terms.rsc +5 -5
  73. package/.next/server/app/yo/page.js +1 -1
  74. package/.next/server/app/yo/page.js.nft.json +1 -1
  75. package/.next/server/app/yo/page_client-reference-manifest.js +1 -1
  76. package/.next/server/app/yo.html +1 -1
  77. package/.next/server/app/yo.rsc +6 -6
  78. package/.next/server/app-paths-manifest.json +2 -2
  79. package/.next/server/chunks/1196.js +1 -1
  80. package/.next/server/chunks/{6415.js → 2123.js} +2 -2
  81. package/.next/server/chunks/2234.js +1 -1
  82. package/.next/server/chunks/4224.js +1 -0
  83. package/.next/server/chunks/4600.js +1 -1
  84. package/.next/server/chunks/5678.js +1 -1
  85. package/.next/server/chunks/5991.js +7 -0
  86. package/.next/server/chunks/6470.js +1 -1
  87. package/.next/server/chunks/7585.js +1 -1
  88. package/.next/server/chunks/7935.js +19 -11
  89. package/.next/server/chunks/8468.js +1 -1
  90. package/.next/server/chunks/{1350.js → 9323.js} +3 -3
  91. package/.next/server/chunks/9971.js +1 -1
  92. package/.next/server/functions-config-manifest.json +1 -1
  93. package/.next/server/middleware-build-manifest.js +1 -1
  94. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  95. package/.next/server/pages/404.html +1 -1
  96. package/.next/server/pages/500.html +1 -1
  97. package/.next/server/server-reference-manifest.json +1 -1
  98. package/.next/static/chunks/{1168.aaac1edbb597fe5a.js → 1168.bb1c93965872e980.js} +1 -1
  99. package/.next/static/chunks/2891-bf010357841c9ce9.js +1 -0
  100. package/.next/static/chunks/{2927.7e00cc878d9a3f52.js → 2927.3976471e61df966e.js} +1 -1
  101. package/.next/static/chunks/{3573-1b41d7b8a000d015.js → 3573-667bc4c8f56afcff.js} +1 -1
  102. package/.next/static/chunks/{3a91511d-ba215c0b5dc21ba9.js → 3a91511d-da2c74cad6c6fc33.js} +2 -2
  103. package/.next/static/chunks/4114-a375178fd94c4d8a.js +1 -0
  104. package/.next/static/chunks/{4256.48407d9abad5ea33.js → 4256.aa831e4d8c3f65bc.js} +1 -1
  105. package/.next/static/chunks/{4919-7e7cdd5efc9f2110.js → 4919-0e698cd95504e355.js} +1 -1
  106. package/.next/static/chunks/{5336-233ec7ab3807267c.js → 5336-b775f449d7433604.js} +1 -1
  107. package/.next/static/chunks/{7338-3ce17a93614f1d77.js → 5362-2e8fcdd0bc6273ca.js} +4 -4
  108. package/.next/static/chunks/67-cb9bbb430499e803.js +1 -0
  109. package/.next/static/chunks/{8273-8e92d34180669ca9.js → 8273-3b9d882c5dd6a9a8.js} +1 -1
  110. package/.next/static/chunks/8291-8f6fb6554e692552.js +1 -0
  111. package/.next/static/chunks/8370-6537b6b27df58b23.js +1 -0
  112. package/.next/static/chunks/app/app-legacy-do-not-use/page-efa348da049c5873.js +1 -0
  113. package/.next/static/chunks/app/{error-63cbe72522239cff.js → error-04a18fd49a89ee17.js} +1 -1
  114. package/.next/static/chunks/app/layout-7093dda0d106f34d.js +1 -0
  115. package/.next/static/chunks/app/page-0ec7cf48550f71e6.js +1 -0
  116. package/.next/static/chunks/app/yo/{page-cf5d6540ea31c31c.js → page-48930746b135037e.js} +1 -1
  117. package/.next/static/chunks/{webpack-79ad58260e9b10b4.js → webpack-15ec0114c9d658c2.js} +1 -1
  118. package/.next/static/css/35991998d1b5eff0.css +3 -0
  119. package/.next/trace +28 -28
  120. package/README.md +2 -2
  121. package/bin/auramaxx.js +87 -3
  122. package/package.json +8 -4
  123. package/prisma/migrations/20260301225214_social_tables/migration.sql +81 -0
  124. package/prisma/migrations/20260302120000_add_notification_hash/migration.sql +8 -0
  125. package/prisma/migrations/20260302160000_add_public_key_hex/migration.sql +5 -0
  126. package/prisma/migrations/20260302170000_add_inbound_author_public_key/migration.sql +5 -0
  127. package/prisma/schema.prisma +272 -177
  128. package/shared/credential-field-schema.ts +10 -0
  129. package/skills/auramaxx/SKILL.md +33 -4
  130. package/skills/auramaxx/docs/AGENT_SETUP.md +7 -2
  131. package/src/app/UnlockPageClient.tsx +448 -43
  132. package/src/app/app-legacy-do-not-use/page.tsx +5 -3
  133. package/src/app/globals.css +1 -1
  134. package/src/components/AgentPicker.tsx +278 -0
  135. package/src/components/CreateAgentModal.tsx +192 -0
  136. package/src/components/NotificationDrawer.tsx +15 -13
  137. package/src/components/agent/AgentSidebar.tsx +2 -19
  138. package/src/components/agent/CredentialAgent.tsx +70 -37
  139. package/src/components/agent/CredentialForm.tsx +32 -7
  140. package/src/components/agent/CredentialList.tsx +149 -72
  141. package/src/components/agents/AgentsView.tsx +1035 -0
  142. package/src/components/design-system/TextAreaInput.tsx +78 -0
  143. package/src/components/design-system/index.ts +1 -0
  144. package/src/components/hub/HubView.tsx +58 -0
  145. package/src/components/layout/LeftRail.tsx +333 -40
  146. package/src/components/layout/ViewShell.tsx +125 -0
  147. package/src/components/layout/index.ts +1 -0
  148. package/src/components/social/PrimaryHubRegistrationGate.tsx +260 -0
  149. package/src/components/social/SocialView.tsx +904 -0
  150. package/src/hooks/useSocialNotifications.ts +123 -0
  151. package/src/lib/events.ts +10 -1
  152. package/src/lib/social-client.ts +319 -0
  153. package/src/lib/view-registry.ts +22 -4
  154. package/src/server/cli/commands/agent.ts +33 -7
  155. package/src/server/cli/commands/create.ts +209 -0
  156. package/src/server/cli/commands/onboard.ts +39 -0
  157. package/src/server/cli/commands/play.ts +68 -0
  158. package/src/server/cli/commands/register-agent.ts +181 -0
  159. package/src/server/cli/commands/social.ts +648 -0
  160. package/src/server/cli/commands/start.ts +4 -3
  161. package/src/server/cron/index.ts +5 -9
  162. package/src/server/cron/jobs/social-inbound.ts +596 -0
  163. package/src/server/cron/jobs/social-outbound.ts +70 -0
  164. package/src/server/index.ts +14 -0
  165. package/src/server/lib/agent-profiles.ts +10 -1
  166. package/src/server/lib/cold.ts +0 -45
  167. package/src/server/lib/credential-import.ts +53 -47
  168. package/src/server/lib/defaults.ts +11 -0
  169. package/src/server/lib/feature-flags.ts +3 -0
  170. package/src/server/lib/hub-auth.ts +159 -0
  171. package/src/server/lib/migrate-agent-profiles.ts +96 -0
  172. package/src/server/lib/notifications.ts +12 -1
  173. package/src/server/lib/permissions.ts +10 -0
  174. package/src/server/lib/project-scope.ts +33 -5
  175. package/src/server/lib/social/create.ts +176 -0
  176. package/src/server/lib/social/global-aura-id.ts +115 -0
  177. package/src/server/lib/social/hub-rpc-client.ts +99 -0
  178. package/src/server/lib/social/hub-session.ts +6 -0
  179. package/src/server/lib/social/public-key.ts +32 -0
  180. package/src/server/lib/social/register.ts +162 -0
  181. package/src/server/lib/social/sign.ts +95 -0
  182. package/src/server/lib/social/sync.ts +301 -0
  183. package/src/server/mcp/server.ts +142 -18
  184. package/src/server/mcp/tools.ts +552 -0
  185. package/src/server/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  186. package/src/server/routes/agent-hub.ts +276 -0
  187. package/src/server/routes/agent-profiles.ts +145 -19
  188. package/src/server/routes/credentials.ts +49 -15
  189. package/src/server/routes/heartbeat.ts +3 -7
  190. package/src/server/routes/passkey.ts +7 -1
  191. package/src/server/routes/social.ts +869 -0
  192. package/src/server/routes/unlock.ts +17 -1
  193. package/src/server/routes/verified-credentials.ts +312 -0
  194. package/src/server/test-data/template.db +0 -0
  195. package/src/server/test-data/worker-1/agent-primary.json +12 -0
  196. package/src/server/test-data/worker-1/auramaxx.db +0 -0
  197. package/src/server/test-data/worker-1/backups/auramaxx.db.20260305_011404.bak +0 -0
  198. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-00ntf5h3.json +24 -0
  199. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-dh8fa9k3.json +24 -0
  200. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-prfhlyow.json +25 -0
  201. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-w26jd6zi.json +22 -0
  202. package/src/server/test-data/worker-1/config.json +33 -0
  203. package/src/server/test-data/worker-1/test.db +0 -0
  204. package/src/server/test-data/worker-10/agent-primary.json +12 -0
  205. package/src/server/test-data/worker-10/config.json +33 -0
  206. package/src/server/test-data/worker-10/test.db +0 -0
  207. package/src/server/test-data/worker-11/agent-primary.json +12 -0
  208. package/src/server/test-data/worker-11/config.json +33 -0
  209. package/src/server/test-data/worker-11/test.db +0 -0
  210. package/src/server/test-data/worker-12/agent-primary.json +12 -0
  211. package/src/server/test-data/worker-12/config.json +33 -0
  212. package/src/server/test-data/worker-12/credentials/cred-hboagned.json +25 -0
  213. package/src/server/test-data/worker-12/credentials/cred-nt14xd9t.json +24 -0
  214. package/src/server/test-data/worker-12/credentials/cred-qn59xefc.json +24 -0
  215. package/src/server/test-data/worker-12/test.db +0 -0
  216. package/src/server/test-data/worker-13/agent-primary.json +12 -0
  217. package/src/server/test-data/worker-13/approval-context.json +56 -0
  218. package/src/server/test-data/worker-13/approval-context.key +1 -0
  219. package/src/server/test-data/worker-13/config.json +33 -0
  220. package/src/server/test-data/worker-13/credentials-recently-deleted/cred-jn9yqy2m.json +20 -0
  221. package/src/server/test-data/worker-13/test.db +0 -0
  222. package/src/server/test-data/worker-14/agent-primary.json +12 -0
  223. package/src/server/test-data/worker-14/config.json +33 -0
  224. package/src/server/test-data/worker-14/test.db +0 -0
  225. package/src/server/test-data/worker-15/agent-primary.json +12 -0
  226. package/src/server/test-data/worker-15/config.json +33 -0
  227. package/src/server/test-data/worker-15/test.db +0 -0
  228. package/src/server/test-data/worker-15/update-check-4b305e76.json +5 -0
  229. package/src/server/test-data/worker-2/agent-primary.json +12 -0
  230. package/src/server/test-data/worker-2/config.json +33 -0
  231. package/src/server/test-data/worker-2/test.db +0 -0
  232. package/src/server/test-data/worker-3/agent-primary.json +12 -0
  233. package/src/server/test-data/worker-3/config.json +33 -0
  234. package/src/server/test-data/worker-3/test.db +0 -0
  235. package/src/server/test-data/worker-4/agent-primary.json +12 -0
  236. package/src/server/test-data/worker-4/config.json +33 -0
  237. package/src/server/test-data/worker-4/credentials/cred-bm6p74u5.json +24 -0
  238. package/src/server/test-data/worker-4/credentials/cred-r8eqb07i.json +25 -0
  239. package/src/server/test-data/worker-4/credentials/cred-ziv49y9h.json +24 -0
  240. package/src/server/test-data/worker-4/test.db +0 -0
  241. package/src/server/test-data/worker-5/agent-primary.json +12 -0
  242. package/src/server/test-data/worker-5/config.json +33 -0
  243. package/src/server/test-data/worker-5/credentials/cred-15gyfeht.json +25 -0
  244. package/src/server/test-data/worker-5/credentials/cred-lp0ocnfc.json +24 -0
  245. package/src/server/test-data/worker-5/credentials/cred-zfbwfxw0.json +24 -0
  246. package/src/server/test-data/worker-5/test.db +0 -0
  247. package/src/server/test-data/worker-6/agent-primary.json +12 -0
  248. package/src/server/test-data/worker-6/config.json +33 -0
  249. package/src/server/test-data/worker-6/credentials/cred-dx8li3ue.json +24 -0
  250. package/src/server/test-data/worker-6/credentials/cred-myeskqky.json +24 -0
  251. package/src/server/test-data/worker-6/credentials/cred-tam01qdt.json +25 -0
  252. package/src/server/test-data/worker-6/credentials/cred-wdh6rslw.json +22 -0
  253. package/src/server/test-data/worker-6/credentials-archive/cred-4wg53v1y.json +25 -0
  254. package/src/server/test-data/worker-6/test.db +0 -0
  255. package/src/server/test-data/worker-7/agent-primary.json +12 -0
  256. package/src/server/test-data/worker-7/config.json +33 -0
  257. package/src/server/test-data/worker-7/credentials/cred-ji7ec57d.json +25 -0
  258. package/src/server/test-data/worker-7/credentials/cred-mmgj0ypo.json +24 -0
  259. package/src/server/test-data/worker-7/credentials/cred-nb0ic93x.json +24 -0
  260. package/src/server/test-data/worker-7/test.db +0 -0
  261. package/src/server/test-data/worker-8/agent-primary.json +12 -0
  262. package/src/server/test-data/worker-8/config.json +33 -0
  263. package/src/server/test-data/worker-8/test.db +0 -0
  264. package/src/server/test-data/worker-9/agent-primary.json +12 -0
  265. package/src/server/test-data/worker-9/test.db +0 -0
  266. package/src/server/tests/cli/bin-entrypoint.test.ts +99 -0
  267. package/src/server/tests/cli/social.test.ts +83 -0
  268. package/src/server/tests/cron/social-inbound-followers.unit.test.ts +164 -0
  269. package/src/server/tests/cron/social-inbound-staleness.test.ts +193 -0
  270. package/src/server/tests/cron/social-outbound.test.ts +252 -0
  271. package/src/server/tests/endpoints/agent.test.ts +0 -16
  272. package/src/server/tests/lib/credential-field-schema.test.ts +448 -0
  273. package/src/server/tests/lib/project-scope.test.ts +49 -0
  274. package/src/server/tests/lib/social/create.test.ts +207 -0
  275. package/src/server/tests/lib/social/sign.test.ts +163 -0
  276. package/src/server/tests/lib/social/sync.test.ts +198 -0
  277. package/src/server/tests/mcp/server.test.ts +1 -3
  278. package/src/server/tests/mcp/tools.test.ts +219 -7
  279. package/src/server/tsconfig.tsbuildinfo +1 -1
  280. package/tsconfig.json +1 -0
  281. package/.next/server/chunks/2460.js +0 -7
  282. package/.next/server/chunks/5246.js +0 -1
  283. package/.next/static/chunks/3667-1db7bd03948e60df.js +0 -1
  284. package/.next/static/chunks/5442-b5bb869e832e8967.js +0 -1
  285. package/.next/static/chunks/6872-a8f1ad5fc35a1c35.js +0 -1
  286. package/.next/static/chunks/7394-4bdb1feefad1a74a.js +0 -1
  287. package/.next/static/chunks/7587-8542eae6e5139d27.js +0 -1
  288. package/.next/static/chunks/app/app-legacy-do-not-use/page-569fed5d1a2bfe79.js +0 -1
  289. package/.next/static/chunks/app/layout-af8d9969c7aeb758.js +0 -1
  290. package/.next/static/chunks/app/page-9bd0ec3ba4aa6cea.js +0 -1
  291. package/.next/static/css/88f92e1578b1e5d9.css +0 -3
  292. package/shared/agent-profile-schema.ts +0 -81
  293. package/src/internal/security/frontend-api-authorization-audit.md +0 -206
  294. package/src/server/lib/agent-profile-records.ts +0 -72
  295. /package/.next/static/{QPzVnl7GToqgYBq14V_iC → yEruVJH_cuht5hu5_1R00}/_buildManifest.js +0 -0
  296. /package/.next/static/{QPzVnl7GToqgYBq14V_iC → yEruVJH_cuht5hu5_1R00}/_ssgManifest.js +0 -0
@@ -1,3 +0,0 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246/0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*
2
- ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
3
- */*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:JetBrains Mono,Menlo,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-y-0{top:0;bottom:0}.-bottom-\[1px\]{bottom:-1px}.-left-1{left:-.25rem}.-left-20{left:-5rem}.-left-8{left:-2rem}.-right-0\.5{right:-.125rem}.-right-6{right:-1.5rem}.-top-0\.5{top:-.125rem}.-top-40{top:-10rem}.-top-6{top:-1.5rem}.-top-60{top:-15rem}.bottom-0{bottom:0}.bottom-1{bottom:.25rem}.bottom-10{bottom:2.5rem}.bottom-12{bottom:3rem}.bottom-14{bottom:3.5rem}.bottom-2{bottom:.5rem}.bottom-20{bottom:5rem}.bottom-3{bottom:.75rem}.bottom-4{bottom:1rem}.bottom-\[-1px\]{bottom:-1px}.bottom-\[5\%\]{bottom:5%}.bottom-full{bottom:100%}.left-0{left:0}.left-1{left:.25rem}.left-1\/2{left:50%}.left-10{left:2.5rem}.left-12{left:3rem}.left-2{left:.5rem}.left-3{left:.75rem}.left-4{left:1rem}.left-6{left:1.5rem}.left-8{left:2rem}.left-\[-1px\]{left:-1px}.left-\[200px\]{left:200px}.left-\[290px\]{left:290px}.left-\[2px\]{left:2px}.left-\[30\%\]{left:30%}.left-\[5\%\]{left:5%}.right-0{right:0}.right-1{right:.25rem}.right-1\/4{right:25%}.right-10{right:2.5rem}.right-12{right:3rem}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-6{right:1.5rem}.right-8{right:2rem}.right-\[-1px\]{right:-1px}.right-\[10px\]{right:10px}.right-\[5\%\]{right:5%}.top-0{top:0}.top-0\.5{top:.125rem}.top-1{top:.25rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.top-2{top:.5rem}.top-20{top:5rem}.top-24{top:6rem}.top-3{top:.75rem}.top-4{top:1rem}.top-5{top:1.25rem}.top-6{top:1.5rem}.top-7{top:1.75rem}.top-8{top:2rem}.top-\[-1px\]{top:-1px}.top-\[31px\]{top:31px}.top-\[5\%\]{top:5%}.top-\[6px\]{top:6px}.top-full{top:100%}.isolate{isolation:isolate}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[10\]{z-index:10}.z-\[110\]{z-index:110}.z-\[120\]{z-index:120}.z-\[1\]{z-index:1}.z-\[2\]{z-index:2}.z-\[5\]{z-index:5}.z-\[9998\]{z-index:9998}.z-\[9999\]{z-index:9999}.order-1{order:1}.order-2{order:2}.col-span-12{grid-column:span 12/span 12}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.col-span-6{grid-column:span 6/span 6}.col-span-8{grid-column:span 8/span 8}.col-span-9{grid-column:span 9/span 9}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-mb-\[1px\]{margin-bottom:-1px}.-mr-\[var\(--space-1\)\]{margin-right:calc(var(--space-1) * -1)}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.mb-\[1px\]{margin-bottom:1px}.mb-\[var\(--space-1\)\]{margin-bottom:var(--space-1)}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-2\.5{margin-top:.625rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-\[1px\]{margin-top:1px}.mt-\[2px\]{margin-top:2px}.mt-\[var\(--space-1\)\]{margin-top:var(--space-1)}.mt-auto{margin-top:auto}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.\!h-6{height:1.5rem!important}.\!h-8{height:2rem!important}.\!h-\[var\(--control-height-sm\)\]{height:var(--control-height-sm)!important}.\!h-auto{height:auto!important}.h-0{height:0}.h-0\.5{height:.125rem}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-24{height:6rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-44{height:11rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[14px\]{height:14px}.h-\[16px\]{height:16px}.h-\[180px\]{height:180px}.h-\[1px\]{height:1px}.h-\[2px\]{height:2px}.h-\[3px\]{height:3px}.h-\[calc\(100\%-12px\)\]{height:calc(100% - 12px)}.h-\[calc\(var\(--control-height-lg\)\+var\(--space-2\)\)\]{height:calc(var(--control-height-lg) + var(--space-2))}.h-\[min\(82vh\2c 900px\)\]{height:min(82vh,900px)}.h-\[var\(--control-height-lg\)\]{height:var(--control-height-lg)}.h-\[var\(--control-height-md\)\]{height:var(--control-height-md)}.h-\[var\(--control-height-sm\)\]{height:var(--control-height-sm)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-20{max-height:5rem}.max-h-24{max-height:6rem}.max-h-32{max-height:8rem}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-\[120px\]{max-height:120px}.max-h-\[220px\]{max-height:220px}.max-h-\[240px\]{max-height:240px}.max-h-\[70vh\]{max-height:70vh}.max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.min-h-0{min-height:0}.min-h-\[100px\]{min-height:100px}.min-h-\[200px\]{min-height:200px}.min-h-\[24px\]{min-height:24px}.min-h-\[280px\]{min-height:280px}.min-h-\[360px\]{min-height:360px}.min-h-\[500vh\]{min-height:500vh}.min-h-\[600px\]{min-height:600px}.min-h-\[800px\]{min-height:800px}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.\!w-6{width:1.5rem!important}.\!w-8{width:2rem!important}.w-0{width:0}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-24{width:6rem}.w-28{width:7rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-4{width:1rem}.w-40{width:10rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-\[136vw\]{width:136vw}.w-\[140px\]{width:140px}.w-\[14px\]{width:14px}.w-\[170px\]{width:170px}.w-\[180px\]{width:180px}.w-\[220px\]{width:220px}.w-\[280px\]{width:280px}.w-\[300px\]{width:300px}.w-\[320px\]{width:320px}.w-\[48px\]{width:48px}.w-\[56px\]{width:56px}.w-\[6px\]{width:6px}.w-\[min\(760px\2c calc\(100\%-2rem\)\)\]{width:min(760px,calc(100% - 2rem))}.w-\[min\(94vw\2c 620px\)\]{width:min(94vw,620px)}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0}.min-w-\[100px\]{min-width:100px}.min-w-\[13rem\]{min-width:13rem}.min-w-\[14px\]{min-width:14px}.min-w-\[160px\]{min-width:160px}.min-w-\[16px\]{min-width:16px}.min-w-\[170px\]{min-width:170px}.min-w-\[200px\]{min-width:200px}.min-w-\[220px\]{min-width:220px}.min-w-\[240px\]{min-width:240px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-\[100px\]{max-width:100px}.max-w-\[1400px\]{max-width:1400px}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-\[280px\]{max-width:280px}.max-w-\[300px\]{max-width:300px}.max-w-\[320px\]{max-width:320px}.max-w-\[380px\]{max-width:380px}.max-w-\[420px\]{max-width:420px}.max-w-\[900px\]{max-width:900px}.max-w-\[920px\]{max-width:920px}.max-w-\[min\(94vw\2c 740px\)\]{max-width:min(94vw,740px)}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.basis-full{flex-basis:100%}.-translate-x-1\/2{--tw-translate-x:-50%}.-translate-x-1\/2,.-translate-y-1\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%}.translate-x-0{--tw-translate-x:0px}.translate-x-0,.translate-x-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-full{--tw-translate-x:100%}.-rotate-1{--tw-rotate:-1deg}.-rotate-1,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.rotate-3{--tw-rotate:3deg}.rotate-3,.rotate-90{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate:90deg}.-skew-x-12{--tw-skew-x:-12deg}.-skew-x-12,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.animate-\[float-left_5s_ease-in-out_infinite_0\.5s\]{animation:float-left 5s ease-in-out .5s infinite}.animate-\[float-left_6s_ease-in-out_infinite\]{animation:float-left 6s ease-in-out infinite}.animate-\[float-right_7s_ease-in-out_infinite_1s\]{animation:float-right 7s ease-in-out 1s infinite}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}@keyframes ticker{0%{transform:translateX(0)}to{transform:translateX(-100%)}}.animate-ticker{animation:ticker 30s linear infinite}.cursor-default{cursor:default}.cursor-e-resize{cursor:e-resize}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-n-resize{cursor:n-resize}.cursor-ne-resize{cursor:ne-resize}.cursor-not-allowed{cursor:not-allowed}.cursor-nw-resize{cursor:nw-resize}.cursor-pointer{cursor:pointer}.cursor-s-resize{cursor:s-resize}.cursor-se-resize{cursor:se-resize}.cursor-sw-resize{cursor:sw-resize}.cursor-w-resize{cursor:w-resize}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.resize-none{resize:none}.resize{resize:both}.list-none{list-style-type:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.auto-rows-max{grid-auto-rows:max-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[140px_1fr\]{grid-template-columns:140px 1fr}.grid-cols-\[minmax\(0\2c 1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.\!justify-start{justify-content:flex-start!important}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.\!justify-between{justify-content:space-between!important}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-10{gap:2.5rem}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.gap-\[2px\]{gap:2px}.gap-\[var\(--space-1\)\]{gap:var(--space-1)}.gap-\[var\(--space-2\)\]{gap:var(--space-2)}.gap-\[var\(--space-3\)\]{gap:var(--space-3)}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-1{row-gap:.25rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-2\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.625rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.625rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-\[var\(--space-3\)\]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(var(--space-3) * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(var(--space-3) * var(--tw-space-y-reverse))}.space-y-\[var\(--space-4\)\]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(var(--space-4) * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(var(--space-4) * var(--tw-space-y-reverse))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis}.truncate,.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.\!rounded-none{border-radius:0!important}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[1px\]{border-radius:1px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.border{border-width:1px}.border-0{border-width:0}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0}.border-b-2{border-bottom-width:2px}.border-b-4{border-bottom-width:4px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-r-2{border-right-width:2px}.border-r-4{border-right-width:4px}.border-t{border-top-width:1px}.border-t-2{border-top-width:2px}.border-t-4{border-top-width:4px}.border-dashed{border-style:dashed}.\!border-\[var\(--color-warning\)\]{border-color:var(--color-warning)!important}.\!border-\[var\(--color-warning-alt\2c \#ff9500\)\]{border-color:var(--color-warning-alt,#ff9500)!important}.border-\[\#222222\]{--tw-border-opacity:1;border-color:rgb(34 34 34/var(--tw-border-opacity,1))}.border-\[\#2a2a2a\]{--tw-border-opacity:1;border-color:rgb(42 42 42/var(--tw-border-opacity,1))}.border-\[var\(--app-blue-accent\2c rgba\(0\2c 71\2c 255\2c 0\.3\)\)\]{border-color:var(--app-blue-accent,rgba(0,71,255,.3))}.border-\[var\(--app-gray-accent\2c rgba\(107\2c 114\2c 128\2c 0\.3\)\)\]{border-color:var(--app-gray-accent,rgba(107,114,128,.3))}.border-\[var\(--app-lime-accent\2c rgba\(132\2c 204\2c 22\2c 0\.3\)\)\]{border-color:var(--app-lime-accent,rgba(132,204,22,.3))}.border-\[var\(--app-orange-accent\2c rgba\(255\2c 77\2c 0\2c 0\.3\)\)\]{border-color:var(--app-orange-accent,rgba(255,77,0,.3))}.border-\[var\(--app-purple-accent\2c rgba\(124\2c 58\2c 237\2c 0\.3\)\)\]{border-color:var(--app-purple-accent,rgba(124,58,237,.3))}.border-\[var\(--app-rose-accent\2c rgba\(244\2c 63\2c 94\2c 0\.3\)\)\]{border-color:var(--app-rose-accent,rgba(244,63,94,.3))}.border-\[var\(--app-teal-accent\2c rgba\(20\2c 184\2c 166\2c 0\.3\)\)\]{border-color:var(--app-teal-accent,rgba(20,184,166,.3))}.border-\[var\(--color-accent\)\]{border-color:var(--color-accent)}.border-\[var\(--color-accent\2c \#ccff00\)\]{border-color:var(--color-accent,#ccff00)}.border-\[var\(--color-border\)\]{border-color:var(--color-border)}.border-\[var\(--color-border\2c \#d4d4d8\)\]{border-color:var(--color-border,#d4d4d8)}.border-\[var\(--color-border\2c \#e5e5e5\)\]{border-color:var(--color-border,#e5e5e5)}.border-\[var\(--color-border-focus\)\]{border-color:var(--color-border-focus)}.border-\[var\(--color-border-focus\2c \#0a0a0a\)\]{border-color:var(--color-border-focus,#0a0a0a)}.border-\[var\(--color-border-muted\2c \#a1a1aa\)\]{border-color:var(--color-border-muted,#a1a1aa)}.border-\[var\(--color-border-muted\2c \#e5e5e5\)\]{border-color:var(--color-border-muted,#e5e5e5)}.border-\[var\(--color-border-muted\2c \#e5e7eb\)\]{border-color:var(--color-border-muted,#e5e7eb)}.border-\[var\(--color-credential-array-border\2c \#8d8d95\)\]{border-color:var(--color-credential-array-border,#8d8d95)}.border-\[var\(--color-danger\2c \#ef4444\)\]{border-color:var(--color-danger,#ef4444)}.border-\[var\(--color-info\2c \#0047ff\)\]{border-color:var(--color-info,#0047ff)}.border-\[var\(--color-surface\2c \#ffffff\)\]{border-color:var(--color-surface,#ffffff)}.border-\[var\(--color-text\2c \#0a0a0a\)\]{border-color:var(--color-text,#0a0a0a)}.border-\[var\(--color-warning\)\]{border-color:var(--color-warning)}.border-\[var\(--color-warning\2c \#ff4d00\)\]{border-color:var(--color-warning,#ff4d00)}.border-\[var\(--color-warning-alt\2c \#ff9500\)\]{border-color:var(--color-warning-alt,#ff9500)}.border-amber-500\/40{border-color:rgb(245 158 11/.4)}.border-black\/10{border-color:rgb(0 0 0/.1)}.border-black\/20{border-color:rgb(0 0 0/.2)}.border-black\/25{border-color:rgb(0 0 0/.25)}.border-concrete{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity,1))}.border-concrete\/20{border-color:rgb(212 212 216/.2)}.border-concrete\/30{border-color:rgb(212 212 216/.3)}.border-ink{--tw-border-opacity:1;border-color:rgb(5 5 5/var(--tw-border-opacity,1))}.border-red-100{--tw-border-opacity:1;border-color:rgb(254 226 226/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.border-red-300{--tw-border-opacity:1;border-color:rgb(252 165 165/var(--tw-border-opacity,1))}.border-transparent{border-color:transparent}.border-void{--tw-border-opacity:1;border-color:rgb(10 10 10/var(--tw-border-opacity,1))}.border-void\/10{border-color:rgb(10 10 10/.1)}.border-voltage{--tw-border-opacity:1;border-color:rgb(204 255 0/var(--tw-border-opacity,1))}.border-voltage\/20{border-color:rgb(204 255 0/.2)}.border-voltage\/30{border-color:rgb(204 255 0/.3)}.border-voltage\/50{border-color:rgb(204 255 0/.5)}.border-white\/10{border-color:rgb(255 255 255/.1)}.border-white\/15{border-color:rgb(255 255 255/.15)}.border-white\/20{border-color:rgb(255 255 255/.2)}.border-l-ink{--tw-border-opacity:1;border-left-color:rgb(5 5 5/var(--tw-border-opacity,1))}.border-t-\[var\(--color-text\2c \#0a0a0a\)\]{border-top-color:var(--color-text,#0a0a0a)}.border-t-transparent{border-top-color:transparent}.\!bg-\[var\(--color-warning\)\]{background-color:var(--color-warning)!important}.\!bg-\[var\(--color-warning-alt\2c \#ff9500\)\]{background-color:var(--color-warning-alt,#ff9500)!important}.bg-\[\#0a0a0a\]{--tw-bg-opacity:1;background-color:rgb(10 10 10/var(--tw-bg-opacity,1))}.bg-\[\#0b0b0b\]{--tw-bg-opacity:1;background-color:rgb(11 11 11/var(--tw-bg-opacity,1))}.bg-\[\#0b0f18\]{--tw-bg-opacity:1;background-color:rgb(11 15 24/var(--tw-bg-opacity,1))}.bg-\[\#111111\]{--tw-bg-opacity:1;background-color:rgb(17 17 17/var(--tw-bg-opacity,1))}.bg-\[\#121212\]{--tw-bg-opacity:1;background-color:rgb(18 18 18/var(--tw-bg-opacity,1))}.bg-\[\#1a1a1a\]{--tw-bg-opacity:1;background-color:rgb(26 26 26/var(--tw-bg-opacity,1))}.bg-\[\#22c55e\]{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity,1))}.bg-\[\#28c840\]{--tw-bg-opacity:1;background-color:rgb(40 200 64/var(--tw-bg-opacity,1))}.bg-\[\#ef4444\]{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-\[\#f4f4f2\]{--tw-bg-opacity:1;background-color:rgb(244 244 242/var(--tw-bg-opacity,1))}.bg-\[\#f4f4f5\]{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.bg-\[\#f59e0b\]{--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity,1))}.bg-\[\#ff5f57\]{--tw-bg-opacity:1;background-color:rgb(255 95 87/var(--tw-bg-opacity,1))}.bg-\[\#ffbd2e\]{--tw-bg-opacity:1;background-color:rgb(255 189 46/var(--tw-bg-opacity,1))}.bg-\[color-mix\(in_srgb\2c var\(--color-info\2c \#0047ff\)_8\%\2c transparent\)\]{background-color:color-mix(in srgb,var(--color-info,#0047ff) 8%,transparent)}.bg-\[color-mix\(in_srgb\2c var\(--color-warning\)_5\%\2c transparent\)\]{background-color:color-mix(in srgb,var(--color-warning) 5%,transparent)}.bg-\[color-mix\(in_srgb\2c var\(--color-warning\2c \#ff4d00\)_10\%\2c transparent\)\]{background-color:color-mix(in srgb,var(--color-warning,#ff4d00) 10%,transparent)}.bg-\[var\(--app-blue-band\2c \#0047ff\)\]{background-color:var(--app-blue-band,#0047ff)}.bg-\[var\(--app-blue-bg\2c rgba\(0\2c 71\2c 255\2c 0\.05\)\)\]{background-color:var(--app-blue-bg,rgba(0,71,255,.05))}.bg-\[var\(--app-gray-band\2c \#6b7280\)\]{background-color:var(--app-gray-band,#6b7280)}.bg-\[var\(--app-gray-bg\2c rgba\(107\2c 114\2c 128\2c 0\.05\)\)\]{background-color:var(--app-gray-bg,rgba(107,114,128,.05))}.bg-\[var\(--app-lime-band\2c \#84cc16\)\]{background-color:var(--app-lime-band,#84cc16)}.bg-\[var\(--app-lime-bg\2c rgba\(132\2c 204\2c 22\2c 0\.05\)\)\]{background-color:var(--app-lime-bg,rgba(132,204,22,.05))}.bg-\[var\(--app-orange-band\2c \#ff4d00\)\]{background-color:var(--app-orange-band,#ff4d00)}.bg-\[var\(--app-orange-bg\2c rgba\(255\2c 77\2c 0\2c 0\.05\)\)\]{background-color:var(--app-orange-bg,rgba(255,77,0,.05))}.bg-\[var\(--app-purple-band\2c \#7c3aed\)\]{background-color:var(--app-purple-band,#7c3aed)}.bg-\[var\(--app-purple-bg\2c rgba\(124\2c 58\2c 237\2c 0\.05\)\)\]{background-color:var(--app-purple-bg,rgba(124,58,237,.05))}.bg-\[var\(--app-rose-band\2c \#f43f5e\)\]{background-color:var(--app-rose-band,#f43f5e)}.bg-\[var\(--app-rose-bg\2c rgba\(244\2c 63\2c 94\2c 0\.05\)\)\]{background-color:var(--app-rose-bg,rgba(244,63,94,.05))}.bg-\[var\(--app-teal-band\2c \#14b8a6\)\]{background-color:var(--app-teal-band,#14b8a6)}.bg-\[var\(--app-teal-bg\2c rgba\(20\2c 184\2c 166\2c 0\.05\)\)\]{background-color:var(--app-teal-bg,rgba(20,184,166,.05))}.bg-\[var\(--color-accent\2c \#ccff00\)\]{background-color:var(--color-accent,#ccff00)}.bg-\[var\(--color-background\2c \#f4f4f5\)\]{background-color:var(--color-background,#f4f4f5)}.bg-\[var\(--color-background\2c \#f5f5f5\)\]{background-color:var(--color-background,#f5f5f5)}.bg-\[var\(--color-background-alt\)\]{background-color:var(--color-background-alt)}.bg-\[var\(--color-background-alt\2c \#e8e8e6\)\]{background-color:var(--color-background-alt,#e8e8e6)}.bg-\[var\(--color-background-alt\2c \#f4f4f5\)\]{background-color:var(--color-background-alt,#f4f4f5)}.bg-\[var\(--color-border\)\]{background-color:var(--color-border)}.bg-\[var\(--color-border\2c \#d4d4d8\)\]{background-color:var(--color-border,#d4d4d8)}.bg-\[var\(--color-border\2c \#e5e5e5\)\]{background-color:var(--color-border,#e5e5e5)}.bg-\[var\(--color-info\2c \#0047ff\)\]{background-color:var(--color-info,#0047ff)}.bg-\[var\(--color-surface\)\]{background-color:var(--color-surface)}.bg-\[var\(--color-surface\2c \#f4f4f2\)\]{background-color:var(--color-surface,#f4f4f2)}.bg-\[var\(--color-surface\2c \#fff\)\]{background-color:var(--color-surface,#fff)}.bg-\[var\(--color-surface\2c \#ffffff\)\]{background-color:var(--color-surface,#ffffff)}.bg-\[var\(--color-surface-alt\)\]{background-color:var(--color-surface-alt)}.bg-\[var\(--color-surface-alt\2c \#d8d8d6\)\]{background-color:var(--color-surface-alt,#d8d8d6)}.bg-\[var\(--color-surface-alt\2c \#f5f5f5\)\]{background-color:var(--color-surface-alt,#f5f5f5)}.bg-\[var\(--color-surface-alt\2c \#fafafa\)\]{background-color:var(--color-surface-alt,#fafafa)}.bg-\[var\(--color-text\)\]{background-color:var(--color-text)}.bg-\[var\(--color-text\2c \#0a0a0a\)\]{background-color:var(--color-text,#0a0a0a)}.bg-\[var\(--color-text-muted\)\]{background-color:var(--color-text-muted)}.bg-\[var\(--color-text-muted\2c \#6b7280\)\]{background-color:var(--color-text-muted,#6b7280)}.bg-\[var\(--color-warning\2c \#ff4d00\)\]{background-color:var(--color-warning,#ff4d00)}.bg-alert{--tw-bg-opacity:1;background-color:rgb(255 77 0/var(--tw-bg-opacity,1))}.bg-amber-50{--tw-bg-opacity:1;background-color:rgb(255 251 235/var(--tw-bg-opacity,1))}.bg-amber-50\/50{background-color:rgb(255 251 235/.5)}.bg-black\/10{background-color:rgb(0 0 0/.1)}.bg-black\/35{background-color:rgb(0 0 0/.35)}.bg-concrete{--tw-bg-opacity:1;background-color:rgb(212 212 216/var(--tw-bg-opacity,1))}.bg-ink{--tw-bg-opacity:1;background-color:rgb(5 5 5/var(--tw-bg-opacity,1))}.bg-red-100\/40{background-color:rgb(254 226 226/.4)}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-tyvek{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-tyvek-dim{--tw-bg-opacity:1;background-color:rgb(240 240 240/var(--tw-bg-opacity,1))}.bg-tyvek-dim\/50{background-color:rgb(240 240 240/.5)}.bg-void{--tw-bg-opacity:1;background-color:rgb(10 10 10/var(--tw-bg-opacity,1))}.bg-void\/5{background-color:rgb(10 10 10/.05)}.bg-void\/70{background-color:rgb(10 10 10/.7)}.bg-void\/85{background-color:rgb(10 10 10/.85)}.bg-void\/90{background-color:rgb(10 10 10/.9)}.bg-voltage{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.bg-voltage\/10{background-color:rgb(204 255 0/.1)}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/30{background-color:rgb(255 255 255/.3)}.bg-white\/40{background-color:rgb(255 255 255/.4)}.bg-white\/50{background-color:rgb(255 255 255/.5)}.bg-\[linear-gradient\(to_right\2c \#e5e5e5_1px\2c transparent_1px\)\2c linear-gradient\(to_bottom\2c \#e5e5e5_1px\2c transparent_1px\)\]{background-image:linear-gradient(90deg,#e5e5e5 1px,transparent 0),linear-gradient(180deg,#e5e5e5 1px,transparent 0)}.bg-\[linear-gradient\(to_right\2c var\(--color-border-muted\2c \#e5e5e5\)_1px\2c transparent_1px\)\2c linear-gradient\(to_bottom\2c var\(--color-border-muted\2c \#e5e5e5\)_1px\2c transparent_1px\)\]{background-image:linear-gradient(to right,var(--color-border-muted,#e5e5e5) 1px,transparent 1px),linear-gradient(to bottom,var(--color-border-muted,#e5e5e5) 1px,transparent 1px)}.bg-\[linear-gradient\(transparent_50\%\2c rgba\(255\2c 255\2c 255\2c 0\.03\)_50\%\)\]{background-image:linear-gradient(transparent 50%,rgba(255,255,255,.03) 0)}.bg-\[radial-gradient\(\#000_1px\2c transparent_1px\)\]{background-image:radial-gradient(#000 1px,transparent 0)}.bg-\[radial-gradient\(circle_at_15\%_20\%\2c rgba\(0\2c 71\2c 255\2c 0\.16\)\2c transparent_40\%\)\2c radial-gradient\(circle_at_85\%_75\%\2c rgba\(204\2c 255\2c 0\2c 0\.16\)\2c transparent_35\%\)\2c linear-gradient\(180deg\2c \#f2f3ef_0\%\2c \#eceee8_100\%\)\]{background-image:radial-gradient(circle at 15% 20%,rgba(0,71,255,.16),transparent 40%),radial-gradient(circle at 85% 75%,rgba(204,255,0,.16),transparent 35%),linear-gradient(180deg,#f2f3ef,#eceee8)}.bg-\[radial-gradient\(var\(--color-text\2c \#000\)_1px\2c transparent_1px\)\]{background-image:radial-gradient(var(--color-text,#000) 1px,transparent 1px)}.bg-\[repeating-linear-gradient\(90deg\2c var\(--color-text\2c \#000\)\2c var\(--color-text\2c \#000\)_1px\2c transparent_1px\2c transparent_3px\)\]{background-image:repeating-linear-gradient(90deg,var(--color-text,#000),var(--color-text,#000) 1px,transparent 1px,transparent 3px)}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-grid-pattern{background-image:linear-gradient(90deg,#e5e5e5 1px,transparent 0),linear-gradient(180deg,#e5e5e5 1px,transparent 0)}.bg-grid-pattern-dark{background-image:linear-gradient(90deg,rgba(255,255,255,.06) 1px,transparent 0),linear-gradient(180deg,rgba(255,255,255,.06) 1px,transparent 0)}.from-transparent{--tw-gradient-from:transparent var(--tw-gradient-from-position);--tw-gradient-to:rgb(0 0 0/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-white\/10{--tw-gradient-to:rgb(255 255 255/0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),rgb(255 255 255/0.1) var(--tw-gradient-via-position),var(--tw-gradient-to)}.to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.bg-\[length\:100\%_4px\]{background-size:100% 4px}.bg-\[size\:3px_3px\]{background-size:3px 3px}.bg-\[size\:3rem_3rem\]{background-size:3rem 3rem}.bg-\[size\:4px_4px\]{background-size:4px 4px}.bg-\[size\:4rem_4rem\]{background-size:4rem 4rem}.fill-\[var\(--color-favorite\2c \#ff4d00\)\]{fill:var(--color-favorite,#ff4d00)}.fill-transparent{fill:transparent}.object-contain{-o-object-fit:contain;object-fit:contain}.\!p-0{padding:0!important}.\!p-2{padding:.5rem!important}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-\[var\(--space-1\)\]{padding:var(--space-1)}.p-\[var\(--space-2\)\]{padding:var(--space-2)}.p-\[var\(--space-3\)\]{padding:var(--space-3)}.p-\[var\(--space-4\)\]{padding:var(--space-4)}.p-\[var\(--space-6\)\]{padding:var(--space-6)}.p-\[var\(--space-md\)\]{padding:var(--space-md)}.\!px-0{padding-left:0!important;padding-right:0!important}.\!px-1\.5{padding-left:.375rem!important;padding-right:.375rem!important}.\!px-2{padding-left:.5rem!important;padding-right:.5rem!important}.\!px-3{padding-left:.75rem!important;padding-right:.75rem!important}.\!py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.px-0{padding-left:0;padding-right:0}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[var\(--space-1\)\]{padding-left:var(--space-1);padding-right:var(--space-1)}.px-\[var\(--space-2\)\]{padding-left:var(--space-2);padding-right:var(--space-2)}.px-\[var\(--space-3\)\]{padding-left:var(--space-3);padding-right:var(--space-3)}.px-\[var\(--space-4\)\]{padding-left:var(--space-4);padding-right:var(--space-4)}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-20{padding-top:5rem;padding-bottom:5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-32{padding-top:8rem;padding-bottom:8rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[var\(--space-2\)\]{padding-top:var(--space-2);padding-bottom:var(--space-2)}.py-\[var\(--space-3\)\]{padding-top:var(--space-3);padding-bottom:var(--space-3)}.pb-1{padding-bottom:.25rem}.pb-12{padding-bottom:3rem}.pb-14{padding-bottom:3.5rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pb-\[var\(--space-2\)\]{padding-bottom:var(--space-2)}.pl-0{padding-left:0}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-7{padding-left:1.75rem}.pl-\[calc\(var\(--space-4\)\+var\(--space-3\)\)\]{padding-left:calc(var(--space-4) + var(--space-3))}.pl-\[var\(--space-2\)\]{padding-left:var(--space-2)}.pr-1{padding-right:.25rem}.pr-12{padding-right:3rem}.pr-2{padding-right:.5rem}.pr-6{padding-right:1.5rem}.pr-7{padding-right:1.75rem}.pr-8{padding-right:2rem}.pr-\[calc\(var\(--space-4\)\+12px\)\]{padding-right:calc(var(--space-4) + 12px)}.pr-\[calc\(var\(--space-4\)\+var\(--space-4\)\)\]{padding-right:calc(var(--space-4) + var(--space-4))}.pr-\[var\(--space-2\)\]{padding-right:var(--space-2)}.pr-\[var\(--space-3\)\]{padding-right:var(--space-3)}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-1\.5{padding-top:.375rem}.pt-12{padding-top:3rem}.pt-16{padding-top:4rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-8{padding-top:2rem}.pt-9{padding-top:2.25rem}.pt-\[var\(--space-1\)\]{padding-top:var(--space-1)}.pt-\[var\(--space-2\)\]{padding-top:var(--space-2)}.pt-\[var\(--space-3\)\]{padding-top:var(--space-3)}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:JetBrains Mono,Menlo,monospace}.font-sans{font-family:Inter,system-ui,sans-serif}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-5xl{font-size:3rem;line-height:1}.text-\[10px\]{font-size:10px}.text-\[10vw\]{font-size:10vw}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[12rem\]{font-size:12rem}.text-\[12vw\]{font-size:12vw}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15vw\]{font-size:15vw}.text-\[18px\]{font-size:18px}.text-\[20rem\]{font-size:20rem}.text-\[20vw\]{font-size:20vw}.text-\[7px\]{font-size:7px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[clamp\(12px\2c 3\.2vw\2c 30px\)\]{font-size:clamp(12px,3.2vw,30px)}.text-\[length\:var\(--font-size-md\)\]{font-size:var(--font-size-md)}.text-\[length\:var\(--font-size-sm\)\]{font-size:var(--font-size-sm)}.text-\[length\:var\(--font-size-xs\)\]{font-size:var(--font-size-xs)}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.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)}.leading-6{line-height:1.5rem}.leading-\[0\.8\]{line-height:.8}.leading-\[0\.9\]{line-height:.9}.leading-\[1\.05\]{line-height:1.05}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.03em\]{letter-spacing:.03em}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.12em\]{letter-spacing:.12em}.tracking-\[0\.14em\]{letter-spacing:.14em}.tracking-\[0\.15em\]{letter-spacing:.15em}.tracking-\[0\.22em\]{letter-spacing:.22em}.tracking-\[0\.25em\]{letter-spacing:.25em}.tracking-\[0\.2em\]{letter-spacing:.2em}.tracking-\[0\.3em\]{letter-spacing:.3em}.tracking-normal{letter-spacing:0}.tracking-tight{letter-spacing:-.025em}.tracking-tighter{letter-spacing:-.05em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.\!text-white{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity,1))!important}.text-\[\#0047ff\]{--tw-text-opacity:1;color:rgb(0 71 255/var(--tw-text-opacity,1))}.text-\[\#5d5d5d\]{--tw-text-opacity:1;color:rgb(93 93 93/var(--tw-text-opacity,1))}.text-\[\#7d8590\]{--tw-text-opacity:1;color:rgb(125 133 144/var(--tw-text-opacity,1))}.text-\[\#86efac\]{--tw-text-opacity:1;color:rgb(134 239 172/var(--tw-text-opacity,1))}.text-\[\#8b8b8b\]{--tw-text-opacity:1;color:rgb(139 139 139/var(--tw-text-opacity,1))}.text-\[\#9ca3af\]{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-\[\#a3a3a3\]{--tw-text-opacity:1;color:rgb(163 163 163/var(--tw-text-opacity,1))}.text-\[\#f5f5f5\]{--tw-text-opacity:1;color:rgb(245 245 245/var(--tw-text-opacity,1))}.text-\[var\(--app-blue-text\2c \#0047ff\)\]{color:var(--app-blue-text,#0047ff)}.text-\[var\(--app-gray-text\2c \#6b7280\)\]{color:var(--app-gray-text,#6b7280)}.text-\[var\(--app-lime-text\2c \#65a30d\)\]{color:var(--app-lime-text,#65a30d)}.text-\[var\(--app-orange-text\2c \#ff4d00\)\]{color:var(--app-orange-text,#ff4d00)}.text-\[var\(--app-purple-text\2c \#7c3aed\)\]{color:var(--app-purple-text,#7c3aed)}.text-\[var\(--app-rose-text\2c \#f43f5e\)\]{color:var(--app-rose-text,#f43f5e)}.text-\[var\(--app-teal-text\2c \#14b8a6\)\]{color:var(--app-teal-text,#14b8a6)}.text-\[var\(--color-accent\)\]{color:var(--color-accent)}.text-\[var\(--color-accent\2c \#34d399\)\]{color:var(--color-accent,#34d399)}.text-\[var\(--color-accent\2c \#ccff00\)\]{color:var(--color-accent,#ccff00)}.text-\[var\(--color-accent-foreground\2c \#0a0a0a\)\]{color:var(--color-accent-foreground,#0a0a0a)}.text-\[var\(--color-border\2c \#d4d4d8\)\]{color:var(--color-border,#d4d4d8)}.text-\[var\(--color-danger\)\]{color:var(--color-danger)}.text-\[var\(--color-danger\2c \#ef4444\)\]{color:var(--color-danger,#ef4444)}.text-\[var\(--color-error\2c \#ff4d00\)\]{color:var(--color-error,#ff4d00)}.text-\[var\(--color-favorite\2c \#ff4d00\)\]{color:var(--color-favorite,#ff4d00)}.text-\[var\(--color-info\)\]{color:var(--color-info)}.text-\[var\(--color-info\2c \#0047ff\)\]{color:var(--color-info,#0047ff)}.text-\[var\(--color-success\)\]{color:var(--color-success)}.text-\[var\(--color-success\2c \#00c853\)\]{color:var(--color-success,#00c853)}.text-\[var\(--color-success\2c \#16a34a\)\]{color:var(--color-success,#16a34a)}.text-\[var\(--color-success\2c \#22c55e\)\]{color:var(--color-success,#22c55e)}.text-\[var\(--color-surface\)\]{color:var(--color-surface)}.text-\[var\(--color-surface\2c \#fff\)\]{color:var(--color-surface,#fff)}.text-\[var\(--color-surface\2c \#ffffff\)\]{color:var(--color-surface,#ffffff)}.text-\[var\(--color-text\)\]{color:var(--color-text)}.text-\[var\(--color-text\2c \#0a0a0a\)\]{color:var(--color-text,#0a0a0a)}.text-\[var\(--color-text-faint\)\]{color:var(--color-text-faint)}.text-\[var\(--color-text-faint\2c \#9ca3af\)\]{color:var(--color-text-faint,#9ca3af)}.text-\[var\(--color-text-muted\)\]{color:var(--color-text-muted)}.text-\[var\(--color-text-muted\2c \#6b7280\)\]{color:var(--color-text-muted,#6b7280)}.text-\[var\(--color-text-muted\2c \#71717a\)\]{color:var(--color-text-muted,#71717a)}.text-\[var\(--color-text-muted\2c \#a1a1aa\)\]{color:var(--color-text-muted,#a1a1aa)}.text-\[var\(--color-warning\)\]{color:var(--color-warning)}.text-\[var\(--color-warning\2c \#f59e0b\)\]{color:var(--color-warning,#f59e0b)}.text-\[var\(--color-warning\2c \#ff4d00\)\]{color:var(--color-warning,#ff4d00)}.text-\[var\(--color-warning-alt\2c \#ff9500\)\]{color:var(--color-warning-alt,#ff9500)}.text-amber-600{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity,1))}.text-amber-700{--tw-text-opacity:1;color:rgb(180 83 9/var(--tw-text-opacity,1))}.text-amber-800{--tw-text-opacity:1;color:rgb(146 64 14/var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-black\/40{color:rgb(0 0 0/.4)}.text-black\/50{color:rgb(0 0 0/.5)}.text-black\/60{color:rgb(0 0 0/.6)}.text-black\/70{color:rgb(0 0 0/.7)}.text-concrete{--tw-text-opacity:1;color:rgb(212 212 216/var(--tw-text-opacity,1))}.text-concrete\/40{color:rgb(212 212 216/.4)}.text-concrete\/50{color:rgb(212 212 216/.5)}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-green-600{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.text-ink{--tw-text-opacity:1;color:rgb(5 5 5/var(--tw-text-opacity,1))}.text-ink\/50{color:rgb(5 5 5/.5)}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity,1))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-tyvek{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-void{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.text-voltage{--tw-text-opacity:1;color:rgb(204 255 0/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-white\/60{color:rgb(255 255 255/.6)}.text-white\/70{color:rgb(255 255 255/.7)}.text-white\/90{color:rgb(255 255 255/.9)}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.underline-offset-2{text-underline-offset:2px}.placeholder-\[var\(--color-text-faint\2c \#9ca3af\)\]::-moz-placeholder{color:var(--color-text-faint,#9ca3af)}.placeholder-\[var\(--color-text-faint\2c \#9ca3af\)\]::placeholder{color:var(--color-text-faint,#9ca3af)}.placeholder-\[var\(--color-text-muted\2c \#6b7280\)\]::-moz-placeholder{color:var(--color-text-muted,#6b7280)}.placeholder-\[var\(--color-text-muted\2c \#6b7280\)\]::placeholder{color:var(--color-text-muted,#6b7280)}.accent-\[var\(--color-accent\)\]{accent-color:var(--color-accent)}.accent-\[var\(--color-accent\2c \#ccff00\)\]{accent-color:var(--color-accent,#ccff00)}.accent-\[var\(--color-text\2c \#0a0a0a\)\]{accent-color:var(--color-text,#0a0a0a)}.opacity-0{opacity:0}.opacity-10{opacity:.1}.opacity-100{opacity:1}.opacity-20{opacity:.2}.opacity-25{opacity:.25}.opacity-30{opacity:.3}.opacity-35{opacity:.35}.opacity-40{opacity:.4}.opacity-45{opacity:.45}.opacity-5{opacity:.05}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-90{opacity:.9}.opacity-\[0\.02\]{opacity:.02}.opacity-\[0\.03\]{opacity:.03}.opacity-\[0\.1\]{opacity:.1}.mix-blend-multiply{mix-blend-mode:multiply}.mix-blend-difference{mix-blend-mode:difference}.shadow-2xl{--tw-shadow:0 25px 50px -12px rgb(0 0 0/0.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)}.shadow-2xl,.shadow-\[0_0_0_1px_var\(--color-border-muted\2c \#a1a1aa\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_0_1px_var\(--color-border-muted\2c \#a1a1aa\)\]{--tw-shadow:0 0 0 1px var(--color-border-muted,#a1a1aa);--tw-shadow-colored:0 0 0 1px var(--tw-shadow-color)}.shadow-\[0_0_8px_\#ccff00\]{--tw-shadow:0 0 8px #ccff00;--tw-shadow-colored:0 0 8px var(--tw-shadow-color)}.shadow-\[0_0_8px_\#ccff00\],.shadow-\[0_10px_40px_-10px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-\[0_10px_40px_-10px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 10px 40px -10px rgba(0,0,0,0.3);--tw-shadow-colored:0 10px 40px -10px var(--tw-shadow-color)}.shadow-\[0_22px_80px_rgba\(0\2c 0\2c 0\2c 0\.35\)\]{--tw-shadow:0 22px 80px rgba(0,0,0,0.35);--tw-shadow-colored:0 22px 80px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-\[2px_2px_0_rgba\(10\2c 10\2c 10\2c 0\.08\)\]{--tw-shadow:2px 2px 0 rgba(10,10,10,0.08);--tw-shadow-colored:2px 2px 0 var(--tw-shadow-color)}.shadow-\[2px_2px_0_rgba\(10\2c 10\2c 10\2c 0\.08\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgb(0 0 0/0.1),0 4px 6px -4px rgb(0 0 0/0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgb(0 0 0/0.1),0 8px 10px -6px rgb(0 0 0/0.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-\[2px\]{--tw-backdrop-blur:blur(2px)}.backdrop-blur-\[2px\],.backdrop-blur-sm{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-sm{--tw-backdrop-blur:blur(4px)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[bottom\]{transition-property:bottom;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[transform\2c opacity\]{transition-property:transform,opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-\[1700ms\]{transition-duration:1.7s}.ease-\[cubic-bezier\(0\.22\2c 1\2c 0\.36\2c 1\)\]{transition-timing-function:cubic-bezier(.22,1,.36,1)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.will-change-transform{will-change:transform}.\[grid-template-columns\:repeat\(auto-fit\2c minmax\(56px\2c 1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(56px,1fr))}body{-webkit-app-region:no-drag}.bg-grid-adaptive{background-image:linear-gradient(to right,var(--color-border,#e5e5e5) 1px,transparent 1px),linear-gradient(to bottom,var(--color-border,#e5e5e5) 1px,transparent 1px)}@media (min-width:768px){details.sidebar-always-open>:not(summary){display:block!important}details.sidebar-always-open>summary{pointer-events:none}details.sidebar-always-open>summary *{pointer-events:auto}}@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap");:root{--ui-scale-factor:1;--color-bg:#f5f5f5;--color-surface:#ffffff;--color-text:#0a0a0a;--color-text-muted:#6b7280;--color-accent:#ccff00;--color-border:#d4d4d8;--radius-sm:6px;--radius-md:10px;--radius-lg:14px;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-6:24px;--space-xs:var(--space-1);--space-sm:var(--space-2);--space-md:var(--space-3);--space-lg:var(--space-4);--font-size-xs:10px;--font-size-sm:12px;--font-size-md:14px;--font-size-lg:18px;--control-height-sm:32px;--control-height-md:36px;--control-height-lg:40px;--theme-mode:light;--color-accent-foreground:#0a0a0a;--color-warning:#ff4d00;--color-warning-foreground:#ffffff;--color-favorite:#ff4d00;--color-danger:#ef4444;--color-danger-foreground:#ffffff;--color-success:#00c853;--color-success-foreground:#ffffff;--color-info:#0047ff;--color-info-foreground:#ffffff;--color-background:var(--color-bg);--color-background-alt:#e8e8e6;--color-surface-alt:#fafafa;--color-text-faint:#9ca3af;--color-border-muted:#e5e5e5;--color-border-focus:#0a0a0a;--color-credential-array-border:#c7c7cf;--color-scrollbar-track:#f5f5f5;--color-scrollbar-thumb:#d4d4d8;--color-scrollbar-thumb-hover:#0a0a0a;--app-blue-band:#0047ff;--app-blue-accent:rgba(0,71,255,0.3);--app-blue-bg:rgba(0,71,255,0.05);--app-blue-text:#0047ff;--app-orange-band:#ff4d00;--app-orange-accent:rgba(255,77,0,0.3);--app-orange-bg:rgba(255,77,0,0.05);--app-orange-text:#ff4d00;--app-lime-band:#84cc16;--app-lime-accent:rgba(132,204,22,0.3);--app-lime-bg:rgba(132,204,22,0.05);--app-lime-text:#65a30d;--app-purple-band:#7c3aed;--app-purple-accent:rgba(124,58,237,0.3);--app-purple-bg:rgba(124,58,237,0.05);--app-purple-text:#7c3aed;--app-gray-band:#6b7280;--app-gray-accent:rgba(107,114,128,0.3);--app-gray-bg:rgba(107,114,128,0.05);--app-gray-text:#6b7280;--app-teal-band:#14b8a6;--app-teal-accent:rgba(20,184,166,0.3);--app-teal-bg:rgba(20,184,166,0.05);--app-teal-text:#14b8a6;--app-rose-band:#f43f5e;--app-rose-accent:rgba(244,63,94,0.3);--app-rose-bg:rgba(244,63,94,0.05);--app-rose-text:#f43f5e}[data-theme=dark]{--theme-mode:dark;--color-bg:#0f0f0f;--color-surface:#1a1a1a;--color-text:#f5f5f5;--color-text-muted:#c7c7c7;--color-border:#303030;--color-favorite:#ccff00;--color-background:var(--color-bg);--color-background-alt:#141414;--color-surface-alt:#242424;--color-text-faint:#8f8f8f;--color-border-muted:#3f3f46;--color-border-focus:#ccff00;--color-credential-array-border:#2a2a2e;--color-scrollbar-track:#0a0a0a;--color-scrollbar-thumb:#3f3f46;--color-scrollbar-thumb-hover:#ccff00;--app-blue-accent:rgba(0,71,255,0.4);--app-blue-bg:rgba(0,71,255,0.1);--app-blue-text:#5c8aff;--app-orange-accent:rgba(255,77,0,0.4);--app-orange-bg:rgba(255,77,0,0.1);--app-orange-text:#ff7a40;--app-lime-accent:rgba(132,204,22,0.4);--app-lime-bg:rgba(132,204,22,0.1);--app-lime-text:#a3e635;--app-purple-accent:rgba(124,58,237,0.4);--app-purple-bg:rgba(124,58,237,0.1);--app-purple-text:#a78bfa;--app-gray-accent:rgba(107,114,128,0.4);--app-gray-bg:rgba(107,114,128,0.1);--app-gray-text:#9ca3af;--app-teal-accent:rgba(20,184,166,0.4);--app-teal-bg:rgba(20,184,166,0.1);--app-teal-text:#2dd4bf;--app-rose-accent:rgba(244,63,94,0.4);--app-rose-bg:rgba(244,63,94,0.1);--app-rose-text:#fb7185}[data-ui-scale=big]{--ui-scale-factor:1.25;--radius-sm:calc(6px * 1.25);--radius-md:calc(10px * 1.25);--radius-lg:calc(14px * 1.25);--space-1:calc(4px * 1.25);--space-2:calc(8px * 1.25);--space-3:calc(12px * 1.25);--space-4:calc(16px * 1.25);--space-6:calc(24px * 1.25);--space-xs:var(--space-1);--space-sm:var(--space-2);--space-md:var(--space-3);--space-lg:var(--space-4);--font-size-xs:calc(10px * 1.25);--font-size-sm:calc(12px * 1.25);--font-size-md:calc(14px * 1.25);--font-size-lg:calc(18px * 1.25);--control-height-sm:calc(32px * 1.25);--control-height-md:calc(36px * 1.25);--control-height-lg:calc(40px * 1.25)}body{font-family:Inter,system-ui,sans-serif;background-color:var(--color-background,#f5f5f5);color:var(--color-text,#0a0a0a);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::selection{background:var(--color-accent,#ccff00);color:var(--color-text,#0a0a0a)}::-moz-selection{background:var(--color-accent,#ccff00);color:var(--color-text,#0a0a0a)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--color-scrollbar-track,#f5f5f5)}::-webkit-scrollbar-thumb{background:var(--color-scrollbar-thumb,#d4d4d8)}::-webkit-scrollbar-thumb:hover{background:var(--color-scrollbar-thumb-hover,#0a0a0a)}.scrollbar-tyvek{scrollbar-width:thin;scrollbar-color:var(--color-border-focus,#0a0a0a) color-mix(in srgb,var(--color-surface,#ffffff) 84%,var(--color-border-muted,#e5e5e5));scrollbar-gutter:stable both-edges}.scrollbar-tyvek::-webkit-scrollbar{width:10px;height:10px}.scrollbar-tyvek::-webkit-scrollbar-track{background:color-mix(in srgb,var(--color-surface,#ffffff) 84%,var(--color-border-muted,#e5e5e5));border-left:1px solid color-mix(in srgb,var(--color-border,#d4d4d8) 65%,transparent)}.scrollbar-tyvek::-webkit-scrollbar-thumb{background:var(--color-text,#0a0a0a);border:1px solid color-mix(in srgb,var(--color-text,#0a0a0a) 25%,transparent);border-radius:0}.scrollbar-tyvek::-webkit-scrollbar-thumb:hover{background:var(--color-accent,#ccff00)}.scrollbar-tyvek::-webkit-scrollbar-corner{background:transparent}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{width:0;height:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}@keyframes scan-vertical{0%{top:0;opacity:0}10%{opacity:1}90%{opacity:1}to{top:100%;opacity:0}}.animate-scan{animation:scan-vertical 2s ease-in-out infinite}.clip-specimen{clip-path:polygon(10px 0,100% 0,100% calc(100% - 10px),calc(100% - 10px) 100%,0 100%,0 10px)}.clip-specimen-sm{clip-path:polygon(6px 0,100% 0,100% calc(100% - 6px),calc(100% - 6px) 100%,0 100%,0 6px)}.shadow-mech{box-shadow:4px 4px 0 rgba(0,0,0,.08)}.shadow-mech-hover{box-shadow:6px 6px 0 color-mix(in srgb,var(--color-accent,#ccff00) 25%,transparent)}.shadow-mech-active{box-shadow:2px 2px 0 rgba(0,0,0,.1)}.clip-mech-header{clip-path:polygon(20px 0,calc(100% - 20px) 0,100% 20px,100% 100%,0 100%,0 20px)}.clip-mech-footer{clip-path:polygon(0 0,100% 0,100% calc(100% - 20px),calc(100% - 20px) 100%,20px 100%,0 calc(100% - 20px))}.clip-mech-modal{clip-path:polygon(20px 0,calc(100% - 20px) 0,100% 20px,100% calc(100% - 20px),calc(100% - 20px) 100%,20px 100%,0 calc(100% - 20px),0 20px)}.clip-mech-panel{clip-path:polygon(0 0,100% 0,100% calc(100% - 30px),calc(100% - 30px) 100%,0 100%)}.border-mech{filter:drop-shadow(1px 0 0 var(--color-border,#d4d4d8)) drop-shadow(-1px 0 0 var(--color-border,#d4d4d8)) drop-shadow(0 1px 0 var(--color-border,#d4d4d8)) drop-shadow(0 -1px 0 var(--color-border,#d4d4d8))}.text-vertical{writing-mode:vertical-rl;text-orientation:mixed}.label-specimen{font-size:calc(9px * var(--ui-scale-factor, 1));font-weight:700;letter-spacing:.16em}.label-specimen,.label-specimen-sm{font-family:JetBrains Mono,Menlo,monospace;text-transform:uppercase;line-height:1}.label-specimen-sm{font-size:calc(8px * var(--ui-scale-factor, 1));font-weight:600;letter-spacing:.2em}.tabular-nums{font-variant-numeric:tabular-nums}.scanline-overlay{background-image:linear-gradient(transparent 50%,rgba(0,0,0,.04) 0);background-size:100% 4px}.skeleton-mech{position:relative;overflow:hidden;background:var(--color-background-alt,#f4f4f5)}.skeleton-mech:after{content:"";position:absolute;inset:0;background-image:repeating-linear-gradient(-45deg,transparent,transparent 6px,color-mix(in srgb,var(--color-accent,#ccff00) 8%,transparent) 6px,color-mix(in srgb,var(--color-accent,#ccff00) 8%,transparent) 12px);animation:ticker 8s linear infinite}.corner-marks{position:relative}.corner-marks:after,.corner-marks:before{content:"";position:absolute;width:8px;height:8px;pointer-events:none;z-index:20}.corner-marks:before{top:-1px;left:-1px;border-top:2px solid var(--color-border-focus,#0a0a0a);border-left:2px solid var(--color-border-focus,#0a0a0a)}.corner-marks:after{bottom:-1px;right:-1px;border-bottom:2px solid var(--color-border-focus,#0a0a0a);border-right:2px solid var(--color-border-focus,#0a0a0a)}.tyvek-label{border:1px dashed var(--color-border,#d4d4d8);background:var(--color-surface-alt,#fafafa)}.shard-start{clip-path:polygon(0 0,100% 0,calc(100% - 6px) 100%,0 100%)}.shard-end{clip-path:polygon(6px 0,100% 0,100% 100%,0 100%)}.bg-hazard-stripes{background-image:repeating-linear-gradient(135deg,transparent,transparent 10px,rgba(204,255,0,.06) 0,rgba(204,255,0,.06) 20px)}@keyframes fade-in-up{0%{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}.animate-fade-in-up{animation:fade-in-up .6s cubic-bezier(.16,1,.3,1) forwards}@keyframes fade-out-up{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-16px)}}.animate-fade-out-up{animation:fade-out-up .22s cubic-bezier(.55,0,1,.45) forwards}@keyframes float-left{0%,to{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-20px) rotate(2deg)}}@keyframes float-right{0%,to{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-25px) rotate(-2deg)}}@keyframes yo-sprite-frames{0%,to{background-position-x:0}25%{background-position-x:50%}50%{background-position-x:100%}75%{background-position-x:50%}}@keyframes yo-sprite-drift{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}@keyframes yo-mobile-agent-marquee{0%{transform:translateX(0)}to{transform:translateX(-25%)}}@keyframes yo-slide-in-right{0%{opacity:0;transform:translateX(12%)}to{opacity:1;transform:translateX(0)}}@keyframes yo-slide-out-left{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(-12%)}}.yo-slide-in-right{animation:yo-slide-in-right .76s cubic-bezier(.22,1,.36,1) both}.yo-slide-out-left{animation:yo-slide-out-left .76s cubic-bezier(.22,1,.36,1) both}.yo-sprite{width:clamp(64px,11vw,110px);aspect-ratio:2/3;border:none;background-repeat:no-repeat;background-size:300% 300%;background-position-x:0;background-position-y:0;image-rendering:pixelated;filter:drop-shadow(0 8px 12px rgba(0,0,0,.2));animation:yo-sprite-frames .9s step-end infinite,yo-sprite-drift 1.9s ease-in-out infinite;will-change:transform,background-position}.yo-mobile-agent-marquee{animation:yo-mobile-agent-marquee 22s linear infinite;will-change:transform}@media (prefers-reduced-motion:reduce){.yo-mobile-agent-marquee{animation:none}}.marketing-grid{background-image:linear-gradient(90deg,rgba(0,0,0,.06) 1px,transparent 0),linear-gradient(180deg,rgba(0,0,0,.06) 1px,transparent 0);background-size:46px 46px;-webkit-mask-image:radial-gradient(circle at center,rgba(0,0,0,.9),transparent 85%);mask-image:radial-gradient(circle at center,rgba(0,0,0,.9),transparent 85%)}.marketing-section-card{border:1px solid rgba(0,0,0,.22);background:rgba(255,255,255,.78);backdrop-filter:blur(4px);padding:1.1rem}.docs-top-link{display:inline-flex;align-items:center;justify-content:center;height:2.1rem;border:1px solid rgba(0,0,0,.35);padding:0 .75rem;font-size:10px;letter-spacing:.16em;font-weight:700;font-family:JetBrains Mono,Menlo,monospace;transition:background-color .15s ease,color .15s ease}.docs-top-link:hover{background:#0a0a0a;color:#fff}.tyvek-texture{inset:0;width:100%;height:100%;z-index:9999;opacity:.35;mix-blend-mode:multiply;filter:url(#tyvekFilter);background-image:url(https://grainy-gradients.vercel.app/noise.svg)}.thermal-bond,.tyvek-texture{position:fixed;pointer-events:none}.thermal-bond{inset:12px;z-index:9997;border:1px solid rgba(0,0,0,.11);outline:12px solid rgba(255,255,255,.75);box-shadow:inset 0 0 16px rgba(0,0,0,.06),0 0 0 2px rgba(0,0,0,.04)}.thermal-seal-texture{position:absolute;inset:0 auto auto 0;width:100%;height:24px;opacity:.28;background-image:radial-gradient(circle,#b6b6b6 1px,transparent 0);background-size:4px 4px}.marketing-scan{position:absolute;inset:0;pointer-events:none}.marketing-scan:before{content:"";position:absolute;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.24),transparent);animation:marketing-scan 3s linear infinite}@keyframes marketing-scan{0%{transform:translateY(-20px)}to{transform:translateY(120%)}}.prose-mono{font-size:12px;line-height:1.8;color:var(--color-text,rgba(0,0,0,.8))}.prose-mono h1,.prose-mono h2,.prose-mono h3,.prose-mono h4{font-family:Inter,system-ui,sans-serif;font-weight:700;color:var(--color-text,#0a0a0a);letter-spacing:-.01em;margin-top:1.8em;margin-bottom:.6em}.prose-mono h1{font-size:18px}.prose-mono h1,.prose-mono h2{text-transform:uppercase;letter-spacing:.04em}.prose-mono h2{font-size:14px;border-bottom:1px solid var(--color-border,rgba(0,0,0,.1));padding-bottom:.4em}.prose-mono h3{font-size:12px;text-transform:uppercase;letter-spacing:.06em}.prose-mono h4{font-size:11px}.prose-mono p{margin:.8em 0}.prose-mono a{color:var(--color-warning,#ff4d00);text-decoration:underline;text-underline-offset:2px}.prose-mono code{font-family:JetBrains Mono,Menlo,monospace;font-size:.9em;background:var(--color-surface-alt,rgba(0,0,0,.06));padding:.15em .35em;border:1px solid var(--color-border-muted,rgba(0,0,0,.08))}.prose-mono pre{background:#1a1a1a;color:#e5e5e5;padding:1em;overflow-x:auto;font-size:11px;line-height:1.6;margin:1em 0;border:1px solid var(--color-border,rgba(0,0,0,.15))}[data-theme=dark] .prose-mono pre{background:#000000}.prose-mono pre code{background:none;border:none;padding:0;color:inherit;font-size:inherit}.prose-mono ol,.prose-mono ul{padding-left:1.4em;margin:.6em 0}.prose-mono li{margin:.25em 0}.prose-mono li::marker{color:var(--color-text-faint,rgba(0,0,0,.3))}.prose-mono table{width:100%;border-collapse:collapse;font-size:11px;margin:1em 0}.prose-mono th{text-align:left;font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:9px;color:var(--color-text-muted,rgba(0,0,0,.5));padding:.5em .75em;border-bottom:1px solid var(--color-border,rgba(0,0,0,.15))}.prose-mono td{padding:.4em .75em;border-bottom:1px solid var(--color-border-muted,rgba(0,0,0,.06))}.prose-mono blockquote{border-left:2px solid var(--color-border,rgba(0,0,0,.2));padding-left:1em;color:var(--color-text-muted,rgba(0,0,0,.6));margin:1em 0}.prose-mono hr{border:none;border-top:1px solid var(--color-border-muted,rgba(0,0,0,.1));margin:2em 0}.prose-mono img{max-width:100%;height:auto}@media (min-width:768px){.marketing-section-card{padding:1.5rem}}@media (hover:none) and (pointer:coarse){.tyvek-texture{opacity:.16;mix-blend-mode:normal}.thermal-bond{outline-width:6px;box-shadow:inset 0 0 8px rgba(0,0,0,.04)}.clip-mech-footer,.clip-mech-header,.clip-mech-modal,.clip-mech-panel{transform:translateZ(0);will-change:auto}.animate-fade-in-up{-webkit-transform:translateZ(0)}}@media (prefers-reduced-motion:reduce){.yo-sprite{animation:none}}.selection\:bg-voltage ::-moz-selection{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.selection\:bg-voltage ::selection{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.selection\:text-void ::-moz-selection{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.selection\:text-void ::selection{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.selection\:bg-voltage::-moz-selection{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.selection\:bg-voltage::selection{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.selection\:text-void::-moz-selection{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.selection\:text-void::selection{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.placeholder\:text-black\/35::-moz-placeholder{color:rgb(0 0 0/.35)}.placeholder\:text-black\/35::placeholder{color:rgb(0 0 0/.35)}.last\:mb-0:last-child{margin-bottom:0}.last\:border-0:last-child{border-width:0}.last\:border-b-0:last-child{border-bottom-width:0}.hover\:-translate-x-\[1px\]:hover{--tw-translate-x:-1px}.hover\:-translate-x-\[1px\]:hover,.hover\:-translate-y-\[1px\]:hover{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:-translate-y-\[1px\]:hover{--tw-translate-y:-1px}.hover\:border-\[var\(--color-accent\2c \#ccff00\)\]:hover{border-color:var(--color-accent,#ccff00)}.hover\:border-\[var\(--color-border\2c \#d4d4d8\)\]:hover{border-color:var(--color-border,#d4d4d8)}.hover\:border-\[var\(--color-border-focus\2c \#0a0a0a\)\]:hover{border-color:var(--color-border-focus,#0a0a0a)}.hover\:border-\[var\(--color-border-hover\2c \#d4d4d4\)\]:hover{border-color:var(--color-border-hover,#d4d4d4)}.hover\:border-\[var\(--color-border-muted\2c \#a1a1aa\)\]:hover{border-color:var(--color-border-muted,#a1a1aa)}.hover\:border-\[var\(--color-border-muted\2c \#e5e5e5\)\]:hover{border-color:var(--color-border-muted,#e5e5e5)}.hover\:border-\[var\(--color-text\2c \#0a0a0a\)\]:hover{border-color:var(--color-text,#0a0a0a)}.hover\:border-\[var\(--color-text-muted\2c \#6b7280\)\]:hover{border-color:var(--color-text-muted,#6b7280)}.hover\:border-\[var\(--color-warning\2c \#ff4d00\)\]:hover{border-color:var(--color-warning,#ff4d00)}.hover\:border-black:hover{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity,1))}.hover\:\!bg-\[var\(--color-warning\)\]:hover{background-color:var(--color-warning)!important}.hover\:bg-\[\#1b1b1b\]:hover{--tw-bg-opacity:1;background-color:rgb(27 27 27/var(--tw-bg-opacity,1))}.hover\:bg-\[var\(--color-accent\2c \#ccff00\)\]:hover{background-color:var(--color-accent,#ccff00)}.hover\:bg-\[var\(--color-background-alt\2c \#e0e0de\)\]:hover{background-color:var(--color-background-alt,#e0e0de)}.hover\:bg-\[var\(--color-background-alt\2c \#e5e5e5\)\]:hover{background-color:var(--color-background-alt,#e5e5e5)}.hover\:bg-\[var\(--color-background-alt\2c \#e8e8e6\)\]:hover{background-color:var(--color-background-alt,#e8e8e6)}.hover\:bg-\[var\(--color-background-alt\2c \#f4f4f5\)\]:hover{background-color:var(--color-background-alt,#f4f4f5)}.hover\:bg-\[var\(--color-surface\2c \#ffffff\)\]:hover{background-color:var(--color-surface,#ffffff)}.hover\:bg-\[var\(--color-surface-alt\2c \#d8d8d6\)\]:hover{background-color:var(--color-surface-alt,#d8d8d6)}.hover\:bg-\[var\(--color-surface-alt\2c \#f5f5f5\)\]:hover{background-color:var(--color-surface-alt,#f5f5f5)}.hover\:bg-\[var\(--color-surface-alt\2c \#fafafa\)\]:hover{background-color:var(--color-surface-alt,#fafafa)}.hover\:bg-\[var\(--color-warning\2c \#ff4d00\)\]:hover{background-color:var(--color-warning,#ff4d00)}.hover\:bg-black\/10:hover{background-color:rgb(0 0 0/.1)}.hover\:bg-transparent:hover{background-color:transparent}.hover\:bg-tyvek:hover{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.hover\:bg-void:hover{--tw-bg-opacity:1;background-color:rgb(10 10 10/var(--tw-bg-opacity,1))}.hover\:bg-white\/10:hover{background-color:rgb(255 255 255/.1)}.hover\:text-\[\#d4d4d4\]:hover{--tw-text-opacity:1;color:rgb(212 212 212/var(--tw-text-opacity,1))}.hover\:text-\[\#f5f5f5\]:hover{--tw-text-opacity:1;color:rgb(245 245 245/var(--tw-text-opacity,1))}.hover\:text-\[var\(--color-accent\2c \#ccff00\)\]:hover{color:var(--color-accent,#ccff00)}.hover\:text-\[var\(--color-accent-foreground\2c \#0a0a0a\)\]:hover{color:var(--color-accent-foreground,#0a0a0a)}.hover\:text-\[var\(--color-text\)\]:hover{color:var(--color-text)}.hover\:text-\[var\(--color-text\2c \#0a0a0a\)\]:hover{color:var(--color-text,#0a0a0a)}.hover\:text-\[var\(--color-text-hover\2c \#0a0a0a\)\]:hover{color:var(--color-text-hover,#0a0a0a)}.hover\:text-\[var\(--color-warning\)\]:hover{color:var(--color-warning)}.hover\:text-void:hover{--tw-text-opacity:1;color:rgb(10 10 10/var(--tw-text-opacity,1))}.hover\:text-voltage:hover{--tw-text-opacity:1;color:rgb(204 255 0/var(--tw-text-opacity,1))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:no-underline:hover{text-decoration-line:none}.hover\:opacity-70:hover{opacity:.7}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-90:hover{opacity:.9}.focus\:border-\[var\(--color-border-focus\2c \#0a0a0a\)\]:focus{border-color:var(--color-border-focus,#0a0a0a)}.focus\:border-\[var\(--color-danger\2c \#ef4444\)\]:focus{border-color:var(--color-danger,#ef4444)}.focus\:border-\[var\(--color-info\2c \#0047ff\)\]:focus{border-color:var(--color-info,#0047ff)}.focus\:border-\[var\(--color-text\2c \#0a0a0a\)\]:focus{border-color:var(--color-text,#0a0a0a)}.focus\:border-black:focus{--tw-border-opacity:1;border-color:rgb(0 0 0/var(--tw-border-opacity,1))}.focus\:bg-\[var\(--color-surface\2c \#ffffff\)\]:focus{background-color:var(--color-surface,#ffffff)}.focus\:opacity-100:focus{opacity:1}.focus\:shadow-\[2px_2px_0_rgba\(0\2c 0\2c 0\2c 0\.08\)\]:focus{--tw-shadow:2px 2px 0 rgba(0,0,0,0.08);--tw-shadow-colored:2px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus-visible\:opacity-100:focus-visible{opacity:1}.active\:translate-x-0:active{--tw-translate-x:0px}.active\:translate-x-0:active,.active\:translate-y-0:active{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:translate-y-0:active{--tw-translate-y:0px}.disabled\:cursor-default:disabled{cursor:default}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.group[open] .group-open\:rotate-180{--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:focus-within .group-focus-within\:text-\[var\(--color-text\2c \#0a0a0a\)\]{color:var(--color-text,#0a0a0a)}.group:focus-within .group-focus-within\:opacity-100{opacity:1}.group:hover .group-hover\:block{display:block}.group\/item:hover .group-hover\/item\:bg-\[var\(--color-text\2c \#0a0a0a\)\]{background-color:var(--color-text,#0a0a0a)}.group:hover .group-hover\:bg-voltage{--tw-bg-opacity:1;background-color:rgb(204 255 0/var(--tw-bg-opacity,1))}.group\/resize:hover .group-hover\/resize\:text-\[var\(--color-text-muted\2c \#6b7280\)\]{color:var(--color-text-muted,#6b7280)}.group:hover .group-hover\:text-\[var\(--color-accent\2c \#ccff00\)\]{color:var(--color-accent,#ccff00)}.group:hover .group-hover\:text-\[var\(--color-text\)\]{color:var(--color-text)}.group:hover .group-hover\:text-\[var\(--color-text\2c \#0a0a0a\)\]{color:var(--color-text,#0a0a0a)}.group:hover .group-hover\:opacity-100,.group\/title:hover .group-hover\/title\:opacity-100{opacity:1}@media (min-width:640px){.sm\:bottom-6{bottom:1.5rem}.sm\:left-6{left:1.5rem}.sm\:right-6{right:1.5rem}.sm\:top-24{top:6rem}.sm\:top-6{top:1.5rem}.sm\:top-7{top:1.75rem}.sm\:block{display:block}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:h-10{height:2.5rem}.sm\:max-h-\[calc\(100dvh-4rem\)\]{max-height:calc(100dvh - 4rem)}.sm\:max-h-\[calc\(100vh-4rem\)\]{max-height:calc(100vh - 4rem)}.sm\:w-10{width:2.5rem}.sm\:flex-col{flex-direction:column}.sm\:items-center{align-items:center}.sm\:gap-3{gap:.75rem}.sm\:p-\[var\(--space-4\)\]{padding:var(--space-4)}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.sm\:text-\[10px\]{font-size:10px}.sm\:text-\[12px\]{font-size:12px}.sm\:leading-tight{line-height:1.25}}@media (min-width:768px){.md\:sticky{position:sticky}.md\:bottom-16{bottom:4rem}.md\:left-16{left:4rem}.md\:right-16{right:4rem}.md\:top-20{top:5rem}.md\:mt-0{margin-top:0}.md\:mt-5{margin-top:1.25rem}.md\:block{display:block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:hidden{display:none}.md\:h-10{height:2.5rem}.md\:h-14{height:3.5rem}.md\:h-36{height:9rem}.md\:h-56{height:14rem}.md\:h-\[min\(74vh\2c 860px\)\]{height:min(74vh,860px)}.md\:max-h-\[calc\(100vh-6rem\)\]{max-height:calc(100vh - 6rem)}.md\:w-14{width:3.5rem}.md\:w-32{width:8rem}.md\:w-56{width:14rem}.md\:w-\[min\(112vw\2c 1720px\)\]{width:min(112vw,1720px)}.md\:w-auto{width:auto}.md\:max-w-xl{max-width:36rem}.md\:cursor-default{cursor:default}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-\[240px_minmax\(0\2c 1fr\)\]{grid-template-columns:240px minmax(0,1fr)}.md\:flex-row{flex-direction:row}.md\:items-end{align-items:flex-end}.md\:gap-2{gap:.5rem}.md\:space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.md\:overflow-y-auto{overflow-y:auto}.md\:p-10{padding:2.5rem}.md\:p-12{padding:3rem}.md\:p-6{padding:1.5rem}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-3{padding-top:.75rem;padding-bottom:.75rem}.md\:pl-12{padding-left:3rem}.md\:pt-10{padding-top:2.5rem}.md\:pt-32{padding-top:8rem}.md\:text-3xl{font-size:1.875rem;line-height:2.25rem}.md\:text-4xl{font-size:2.25rem;line-height:2.5rem}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-8xl{font-size:6rem;line-height:1}.md\:text-\[13px\]{font-size:13px}.md\:text-\[16rem\]{font-size:16rem}.md\:text-\[30rem\]{font-size:30rem}.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}.md\:text-xs{font-size:.75rem;line-height:1rem}}@media (min-width:1024px){.lg\:block{display:block}.lg\:flex-1{flex:1 1 0%}.lg\:basis-auto{flex-basis:auto}.lg\:flex-nowrap{flex-wrap:nowrap}}@media (min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}.dark\:border-\[var\(--color-text-inverse\2c \#ffffff\)\]:where([data-theme=dark],[data-theme=dark] *){border-color:var(--color-text-inverse,#ffffff)}.dark\:bg-\[var\(--color-text-inverse\2c \#ffffff\)\]:where([data-theme=dark],[data-theme=dark] *){background-color:var(--color-text-inverse,#ffffff)}.dark\:text-\[var\(--color-surface-inverse\2c \#000000\)\]:where([data-theme=dark],[data-theme=dark] *){color:var(--color-surface-inverse,#000000)}.dark\:text-\[var\(--color-text-inverse\2c \#ffffff\)\]:where([data-theme=dark],[data-theme=dark] *){color:var(--color-text-inverse,#ffffff)}.dark\:text-\[var\(--color-text-muted-inverse\2c \#a1a1aa\)\]:where([data-theme=dark],[data-theme=dark] *){color:var(--color-text-muted-inverse,#a1a1aa)}.dark\:hover\:text-\[var\(--color-text-inverse\2c \#ffffff\)\]:hover:where([data-theme=dark],[data-theme=dark] *){color:var(--color-text-inverse,#ffffff)}.group:hover .dark\:group-hover\:text-\[var\(--color-text-inverse\2c \#ffffff\)\]:where([data-theme=dark],[data-theme=dark] *){color:var(--color-text-inverse,#ffffff)}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}.\[\&\>\*\:first-child\]\:mt-0>:first-child{margin-top:0}.\[\&\>\*\:last-child\]\:mb-0>:last-child{margin-bottom:0}
@@ -1,81 +0,0 @@
1
- export interface AgentProfileInput {
2
- agentId: string;
3
- email?: string;
4
- phone?: string;
5
- address?: string;
6
- profileImage?: string;
7
- attributes?: Record<string, string>;
8
- }
9
-
10
- export interface AgentProfileRecord extends AgentProfileInput {
11
- createdAt: string;
12
- updatedAt: string;
13
- }
14
-
15
- function readOptionalString(input: Record<string, unknown>, key: string, aliases: string[] = []): string | undefined {
16
- const candidates = [key, ...aliases];
17
- for (const candidate of candidates) {
18
- const value = input[candidate];
19
- if (value === undefined || value === null) continue;
20
- if (typeof value !== 'string') {
21
- throw new Error(`agent profile field "${key}" must be a string`);
22
- }
23
- const trimmed = value.trim();
24
- if (!trimmed) return undefined;
25
- return trimmed;
26
- }
27
- return undefined;
28
- }
29
-
30
- function readAttributes(input: Record<string, unknown>): Record<string, string> | undefined {
31
- const raw = input.attributes ?? input.custom_attributes ?? input.customAttributes;
32
- if (raw === undefined || raw === null) return undefined;
33
- if (typeof raw !== 'object' || Array.isArray(raw)) {
34
- throw new Error('agent profile field "attributes" must be an object');
35
- }
36
-
37
- const attributes: Record<string, string> = {};
38
- for (const [rawKey, rawValue] of Object.entries(raw as Record<string, unknown>)) {
39
- const key = rawKey.trim();
40
- if (!key) {
41
- throw new Error('agent profile attribute keys must be non-empty');
42
- }
43
- if (typeof rawValue !== 'string') {
44
- throw new Error(`agent profile attribute "${key}" must be a string`);
45
- }
46
- attributes[key] = rawValue;
47
- }
48
-
49
- return Object.keys(attributes).length > 0 ? attributes : undefined;
50
- }
51
-
52
- export function normalizeAgentProfileInput(
53
- value: unknown,
54
- options: { fallbackAgentId?: string } = {},
55
- ): AgentProfileInput {
56
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
57
- throw new Error('agent profile payload must be an object');
58
- }
59
- const input = value as Record<string, unknown>;
60
-
61
- const rawAgentId = input.agentId ?? input.agent_id ?? options.fallbackAgentId;
62
- if (typeof rawAgentId !== 'string' || rawAgentId.trim().length === 0) {
63
- throw new Error('agent profile requires non-empty agentId');
64
- }
65
- const agentId = rawAgentId.trim();
66
-
67
- const email = readOptionalString(input, 'email');
68
- const phone = readOptionalString(input, 'phone');
69
- const address = readOptionalString(input, 'address');
70
- const profileImage = readOptionalString(input, 'profileImage', ['profile_image']);
71
- const attributes = readAttributes(input);
72
-
73
- return {
74
- agentId,
75
- ...(email ? { email } : {}),
76
- ...(phone ? { phone } : {}),
77
- ...(address ? { address } : {}),
78
- ...(profileImage ? { profileImage } : {}),
79
- ...(attributes ? { attributes } : {}),
80
- };
81
- }
@@ -1,206 +0,0 @@
1
- # Frontend/API Authorization & Consistency Audit (Task 458)
2
-
3
- ## Scope
4
- Static audit of frontend + Next.js API routes + Express API + MCP/CLI surface for:
5
- - auth/permission boundary correctness
6
- - UI/server interaction risks
7
- - MCP/API/CLI contract drift
8
- - duplicate or legacy logic with security impact
9
-
10
- No source files were modified (audit-only deliverable).
11
-
12
- ## Static checks run
13
- - `npm run -s typecheck:server` ✅ (no errors)
14
- - Targeted route/middleware/code inspection across:
15
- - `src/app/api/**`
16
- - `src/server/routes/**`
17
- - `src/server/middleware/**`
18
- - `src/server/mcp/**`
19
- - `src/server/cli/**`
20
- - `src/lib/**`, `src/context/**`
21
-
22
- ---
23
-
24
- ## System map (high-risk trust boundaries)
25
-
26
- 1. **Frontend (React/Next client)** stores and forwards bearer admin token (`AuthContext`, `api.ts`).
27
- 2. **Next.js API routes (`/api/*`)** include privileged local operations (restart/update/app install) and some proxy routes to Express.
28
- 3. **Express server (`:4242`)** is the primary auth/permission authority (`requireWalletAuth`, token validation, permission checks).
29
- 4. **MCP + CLI** are alternate control planes that call the same Express APIs with partially distinct contracts.
30
-
31
- Key risk: some Next routes currently bypass or dilute the Express authorization model.
32
-
33
- ---
34
-
35
- ## Findings
36
-
37
- ## 🚫 Blockers (must fix before ship)
38
-
39
- ### B1) Unauthenticated command execution surfaces in Next API (`/api/update`, `/api/restart`)
40
- **Severity:** Blocker
41
-
42
- **Evidence**
43
- - `src/app/api/update/route.ts` exports `POST()` and executes `exec(buildUpdateCommand())` with no auth gate.
44
- - `src/app/api/restart/route.ts` exports `POST()` and executes detached process restart with no auth gate.
45
-
46
- **Why this is critical**
47
- If dashboard is remotely reachable (tunnel/subdomain), any unauthenticated caller can trigger update/restart operations (remote DoS + operational takeover behavior).
48
-
49
- **Recommended fix**
50
- - Require admin auth on both endpoints using shared guard (`requireWorkspaceAdmin`).
51
- - Add explicit deny-by-default for all mutation routes in Next API.
52
- - Add tests asserting 401/403 without bearer token.
53
-
54
- ---
55
-
56
- ### B2) Unauthenticated sensitive token/approval data exposure through dashboard proxy chain
57
- **Severity:** Blocker
58
-
59
- **Evidence**
60
- - Express `src/server/routes/dashboard.ts` exposes pending actions/history + token metadata and **admin token hashes** (`getAdminTokenHashes()`), and route has no `requireWalletAuth`.
61
- - Next `src/app/api/agent-requests/route.ts` proxies `/dashboard` and explicitly comments “No authentication required”.
62
-
63
- **Why this is critical**
64
- Any unauthenticated caller can enumerate active tokens/requests and internal approval metadata. Even hashed token material and approval context are sensitive intelligence for attack planning.
65
-
66
- **Recommended fix**
67
- - Require admin auth for `/dashboard` (Express) and `/api/agent-requests` (Next).
68
- - Minimize payload: never expose admin token hashes in dashboard responses.
69
- - Add regression tests for unauthorized access rejection.
70
-
71
- ---
72
-
73
- ## ⚠️ Major issues
74
-
75
- ### M1) Unauthenticated event ingestion (`POST /api/events`) allows event stream spoofing
76
- **Severity:** Major
77
-
78
- **Evidence**
79
- - `src/app/api/events/route.ts` accepts arbitrary POST JSON and calls `broadcast(event)` without auth/signature verification.
80
-
81
- **Impact**
82
- Attackers can inject fake operational/security events into UI streams, creating social-engineering and operator confusion risk.
83
-
84
- **Recommended fix**
85
- - Require signed webhook secret or admin bearer on POST.
86
- - Validate origin and event schema strictly (type allowlist + signature timestamp).
87
-
88
- ---
89
-
90
- ### M2) Auth duplication drift risk in Next API (`validateAdmin` copied)
91
- **Severity:** Major
92
-
93
- **Evidence**
94
- - Duplicate `validateAdmin()` implementations:
95
- - `src/app/api/workspace/auth.ts`
96
- - `src/app/api/apps/install/route.ts`
97
-
98
- **Impact**
99
- Auth logic can diverge over time; one route may miss future hardening updates.
100
-
101
- **Recommended fix**
102
- - Centralize in one shared auth helper and import everywhere.
103
- - Add lint/test guard preventing route-local auth re-implementations.
104
-
105
- ---
106
-
107
- ## ◻ Medium issues
108
-
109
- ### MD1) Browser token persistence in `localStorage` by design (XSS blast-radius increase)
110
- **Severity:** Medium
111
-
112
- **Evidence**
113
- - `src/context/AuthContext.tsx` + `src/lib/api.ts` read/write `auramaxx_admin_token` in local/session storage.
114
-
115
- **Impact**
116
- Any XSS in dashboard can exfiltrate bearer admin token. `localStorage` persistence extends impact across restarts.
117
-
118
- **Recommended fix**
119
- - Prefer httpOnly secure cookies for session transport, or at minimum default to session-only + short TTL + CSP hardening.
120
- - Keep “trust device” opt-in explicit with warning.
121
-
122
- ---
123
-
124
- ### MD2) Overly broad unauthenticated read surface for event data (`GET /api/events`)
125
- **Severity:** Medium
126
-
127
- **Evidence**
128
- - `src/app/api/events/route.ts` comment and implementation indicate unauthenticated event query against DB.
129
-
130
- **Impact**
131
- Operational telemetry leakage (action types/categories/metadata) to unauthenticated clients.
132
-
133
- **Recommended fix**
134
- - Require auth for non-public event classes or redact by policy.
135
- - Apply data minimization on returned fields.
136
-
137
- ---
138
-
139
- ### MD3) MCP/CLI contract naming drift (`lifecycle` tool arg mapped to `location` query)
140
- **Severity:** Medium
141
-
142
- **Evidence**
143
- - MCP tool `list_secrets` takes `lifecycle` in `src/server/mcp/tools.ts`, then translates to query param `location`.
144
- - Credentials route semantics are location-based (`active|archive|recently_deleted`).
145
-
146
- **Impact**
147
- Cross-surface inconsistency increases integration bugs and authorization-policy misunderstanding in clients.
148
-
149
- **Recommended fix**
150
- - Standardize a canonical term (`location` or `lifecycle`) across API, MCP, CLI, docs.
151
- - Add contract tests for MCP↔API field parity.
152
-
153
- ---
154
-
155
- ## Authorization model gaps (cross-cutting)
156
-
157
- 1. **No global Next API auth middleware**: route-level auth is inconsistent; several sensitive endpoints are unauthenticated.
158
- 2. **Split authority confusion**: Express is the true policy engine, but Next routes execute privileged actions directly.
159
- 3. **Data minimization not enforced on admin-like dashboard surfaces**.
160
-
161
- ---
162
-
163
- ## Prioritized remediation plan
164
-
165
- ### Phase 0 (immediate, pre-release)
166
- 1. Add admin auth gates to:
167
- - `POST /api/update`
168
- - `POST /api/restart`
169
- - `GET /api/agent-requests`
170
- - `GET/POST /api/events` (at least POST immediately)
171
- 2. Lock down Express `/dashboard` with `requireWalletAuth + requireAdmin`.
172
- 3. Remove admin token hash material from any UI/API payload.
173
-
174
- ### Phase 1
175
- 1. Introduce shared Next API auth utility and ban duplicate auth implementations.
176
- 2. Define route classification: `public`, `authenticated`, `admin` and enforce in tests.
177
- 3. Add structured security tests for unauthorized access on all mutation endpoints.
178
-
179
- ### Phase 2
180
- 1. Unify MCP/API/CLI contract schema and naming; publish a single source-of-truth contract.
181
- 2. Migrate browser auth transport away from localStorage for admin sessions.
182
- 3. Add signed webhook protocol for event ingestion.
183
-
184
- ---
185
-
186
- ## Files inspected (key evidence set)
187
- - `src/app/api/update/route.ts`
188
- - `src/app/api/restart/route.ts`
189
- - `src/app/api/version/route.ts`
190
- - `src/app/api/agent-requests/route.ts`
191
- - `src/app/api/events/route.ts`
192
- - `src/app/api/workspace/auth.ts`
193
- - `src/app/api/apps/install/route.ts`
194
- - `src/server/routes/dashboard.ts`
195
- - `src/server/middleware/auth.ts`
196
- - `src/server/index.ts`
197
- - `src/context/AuthContext.tsx`
198
- - `src/lib/api.ts`
199
- - `src/server/mcp/tools.ts`
200
- - `src/server/routes/credentials.ts`
201
- - `src/server/cli/commands/api.ts`
202
-
203
- ---
204
-
205
- ## Go/No-Go recommendation
206
- **NO-GO** until Blockers B1 and B2 are fixed and verified with explicit unauthorized-access tests.
@@ -1,72 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { DATA_PATHS } from './config';
4
- import type { AgentProfileInput, AgentProfileRecord } from '../../../shared/agent-profile-schema';
5
-
6
- interface AgentProfilesFile {
7
- version: 1;
8
- profiles: Record<string, AgentProfileRecord>;
9
- }
10
-
11
- const AGENT_PROFILES_FILE = 'agent-profiles.json';
12
-
13
- function getAgentProfilesPath(): string {
14
- return path.join(DATA_PATHS.wallets, AGENT_PROFILES_FILE);
15
- }
16
-
17
- function defaultStore(): AgentProfilesFile {
18
- return { version: 1, profiles: {} };
19
- }
20
-
21
- function readStore(): AgentProfilesFile {
22
- const filePath = getAgentProfilesPath();
23
- if (!fs.existsSync(filePath)) return defaultStore();
24
-
25
- try {
26
- const raw = fs.readFileSync(filePath, 'utf8');
27
- const parsed = JSON.parse(raw) as Partial<AgentProfilesFile> | null;
28
- if (!parsed || typeof parsed !== 'object') return defaultStore();
29
- if (parsed.version !== 1 || !parsed.profiles || typeof parsed.profiles !== 'object') return defaultStore();
30
- return {
31
- version: 1,
32
- profiles: parsed.profiles as Record<string, AgentProfileRecord>,
33
- };
34
- } catch {
35
- return defaultStore();
36
- }
37
- }
38
-
39
- function writeStore(store: AgentProfilesFile): void {
40
- const filePath = getAgentProfilesPath();
41
- fs.writeFileSync(filePath, JSON.stringify(store, null, 2), { mode: 0o600 });
42
- }
43
-
44
- export function listAgentProfiles(): AgentProfileRecord[] {
45
- return Object.values(readStore().profiles).sort((a, b) => a.agentId.localeCompare(b.agentId));
46
- }
47
-
48
- export function getAgentProfile(agentId: string): AgentProfileRecord | null {
49
- return readStore().profiles[agentId] || null;
50
- }
51
-
52
- export function upsertAgentProfile(input: AgentProfileInput): AgentProfileRecord {
53
- const store = readStore();
54
- const existing = store.profiles[input.agentId];
55
- const now = new Date().toISOString();
56
- const next: AgentProfileRecord = {
57
- ...input,
58
- createdAt: existing?.createdAt || now,
59
- updatedAt: now,
60
- };
61
- store.profiles[input.agentId] = next;
62
- writeStore(store);
63
- return next;
64
- }
65
-
66
- export function deleteAgentProfile(agentId: string): boolean {
67
- const store = readStore();
68
- if (!store.profiles[agentId]) return false;
69
- delete store.profiles[agentId];
70
- writeStore(store);
71
- return true;
72
- }