@yiaany/ghostapi 0.1.6 → 0.1.8

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 (323) hide show
  1. package/CHANGELOG.md +48 -2
  2. package/CONTRIBUTING.md +119 -117
  3. package/LICENSE +21 -21
  4. package/README.md +208 -185
  5. package/SECURITY.md +53 -37
  6. package/dist/actions/gateway.d.ts +179 -0
  7. package/dist/actions/gateway.js +514 -0
  8. package/dist/actions/gateway.js.map +1 -0
  9. package/dist/actions/index.d.ts +2 -0
  10. package/dist/actions/index.js +2 -0
  11. package/dist/actions/index.js.map +1 -0
  12. package/dist/ai/aiClient.js +4 -4
  13. package/dist/ai/aiClient.js.map +1 -1
  14. package/dist/ai/aiGenerator.d.ts +2 -2
  15. package/dist/ai/aiGenerator.js +21 -72
  16. package/dist/ai/aiGenerator.js.map +1 -1
  17. package/dist/ai/prompts.js +51 -51
  18. package/dist/ai/prompts.js.map +1 -1
  19. package/dist/approvals/approvalInbox.d.ts +150 -0
  20. package/dist/approvals/approvalInbox.js +412 -0
  21. package/dist/approvals/approvalInbox.js.map +1 -0
  22. package/dist/approvals/index.d.ts +2 -0
  23. package/dist/approvals/index.js +2 -0
  24. package/dist/approvals/index.js.map +1 -0
  25. package/dist/behavior/behaviorStore.d.ts +2 -0
  26. package/dist/behavior/behaviorStore.js +50 -46
  27. package/dist/behavior/behaviorStore.js.map +1 -1
  28. package/dist/cache/index.d.ts +2 -0
  29. package/dist/cache/index.js +58 -14
  30. package/dist/cache/index.js.map +1 -1
  31. package/dist/cli/index.js +438 -58
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/openUrl.d.ts +10 -0
  34. package/dist/cli/openUrl.js +31 -0
  35. package/dist/cli/openUrl.js.map +1 -0
  36. package/dist/cli/parser.d.ts +155 -0
  37. package/dist/cli/parser.js +504 -2
  38. package/dist/cli/parser.js.map +1 -1
  39. package/dist/config/dataPaths.d.ts +31 -0
  40. package/dist/config/dataPaths.js +45 -0
  41. package/dist/config/dataPaths.js.map +1 -0
  42. package/dist/config/localConfig.d.ts +1 -2
  43. package/dist/config/localConfig.js +27 -21
  44. package/dist/config/localConfig.js.map +1 -1
  45. package/dist/config/serverConfig.d.ts +2 -0
  46. package/dist/config/serverConfig.js +8 -1
  47. package/dist/config/serverConfig.js.map +1 -1
  48. package/dist/contracts/contract.d.ts +76 -0
  49. package/dist/contracts/contract.js +603 -0
  50. package/dist/contracts/contract.js.map +1 -0
  51. package/dist/contracts/index.d.ts +2 -0
  52. package/dist/contracts/index.js +2 -0
  53. package/dist/contracts/index.js.map +1 -0
  54. package/dist/credentials/credentialBroker.d.ts +207 -0
  55. package/dist/credentials/credentialBroker.js +588 -0
  56. package/dist/credentials/credentialBroker.js.map +1 -0
  57. package/dist/credentials/index.d.ts +2 -0
  58. package/dist/credentials/index.js +2 -0
  59. package/dist/credentials/index.js.map +1 -0
  60. package/dist/dashboard/app.js +685 -615
  61. package/dist/dashboard/index.html +13 -7
  62. package/dist/dashboard/styles.css +349 -349
  63. package/dist/egress/capabilities.d.ts +32 -0
  64. package/dist/egress/capabilities.js +165 -0
  65. package/dist/egress/capabilities.js.map +1 -0
  66. package/dist/egress/linuxBootstrap.d.ts +1 -0
  67. package/dist/egress/linuxBootstrap.js +121 -0
  68. package/dist/egress/linuxBootstrap.js.map +1 -0
  69. package/dist/egress/run.d.ts +18 -0
  70. package/dist/egress/run.js +305 -0
  71. package/dist/egress/run.js.map +1 -0
  72. package/dist/errors/errorEngine.d.ts +2 -2
  73. package/dist/errors/errorEngine.js +3 -40
  74. package/dist/errors/errorEngine.js.map +1 -1
  75. package/dist/evals/evals.d.ts +126 -0
  76. package/dist/evals/evals.js +466 -0
  77. package/dist/evals/evals.js.map +1 -0
  78. package/dist/evals/index.d.ts +2 -0
  79. package/dist/evals/index.js +2 -0
  80. package/dist/evals/index.js.map +1 -0
  81. package/dist/evidence/index.d.ts +2 -0
  82. package/dist/evidence/index.js +2 -0
  83. package/dist/evidence/index.js.map +1 -0
  84. package/dist/evidence/report.d.ts +143 -0
  85. package/dist/evidence/report.js +556 -0
  86. package/dist/evidence/report.js.map +1 -0
  87. package/dist/fault/faultLab.d.ts +5 -4
  88. package/dist/fault/faultLab.js +66 -24
  89. package/dist/fault/faultLab.js.map +1 -1
  90. package/dist/index.d.ts +46 -0
  91. package/dist/index.js +23 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/inventory/analysis.d.ts +12 -0
  94. package/dist/inventory/analysis.js +457 -0
  95. package/dist/inventory/analysis.js.map +1 -0
  96. package/dist/inventory/index.d.ts +5 -0
  97. package/dist/inventory/index.js +4 -0
  98. package/dist/inventory/index.js.map +1 -0
  99. package/dist/inventory/inventoryController.d.ts +53 -0
  100. package/dist/inventory/inventoryController.js +1044 -0
  101. package/dist/inventory/inventoryController.js.map +1 -0
  102. package/dist/inventory/types.d.ts +579 -0
  103. package/dist/inventory/types.js +787 -0
  104. package/dist/inventory/types.js.map +1 -0
  105. package/dist/landing/assets/index-CxWsopzP.css +1 -0
  106. package/dist/landing/assets/index-DZlpyhqd.js +55 -0
  107. package/dist/landing/assets/index-Dk-Xezs3.js +55 -0
  108. package/dist/landing/index.html +15 -15
  109. package/dist/ledger/actionLedger.d.ts +125 -0
  110. package/dist/ledger/actionLedger.js +594 -0
  111. package/dist/ledger/actionLedger.js.map +1 -0
  112. package/dist/ledger/index.d.ts +2 -0
  113. package/dist/ledger/index.js +2 -0
  114. package/dist/ledger/index.js.map +1 -0
  115. package/dist/mcp/server.js +4 -3
  116. package/dist/mcp/server.js.map +1 -1
  117. package/dist/policy/index.d.ts +3 -0
  118. package/dist/policy/index.js +2 -0
  119. package/dist/policy/index.js.map +1 -0
  120. package/dist/policy/policy.d.ts +14 -0
  121. package/dist/policy/policy.js +282 -0
  122. package/dist/policy/policy.js.map +1 -0
  123. package/dist/policy/types.d.ts +52 -0
  124. package/dist/policy/types.js +2 -0
  125. package/dist/policy/types.js.map +1 -0
  126. package/dist/productTelemetry/index.d.ts +16 -0
  127. package/dist/productTelemetry/index.js +142 -0
  128. package/dist/productTelemetry/index.js.map +1 -0
  129. package/dist/providers/conformance.d.ts +7 -0
  130. package/dist/providers/conformance.js +48 -0
  131. package/dist/providers/conformance.js.map +1 -0
  132. package/dist/providers/index.d.ts +4 -2
  133. package/dist/providers/index.js +3 -1
  134. package/dist/providers/index.js.map +1 -1
  135. package/dist/providers/packs/resendPack.d.ts +2 -0
  136. package/dist/providers/packs/resendPack.js +147 -0
  137. package/dist/providers/packs/resendPack.js.map +1 -0
  138. package/dist/providers/packs/stripePack.d.ts +2 -0
  139. package/dist/providers/packs/stripePack.js +852 -0
  140. package/dist/providers/packs/stripePack.js.map +1 -0
  141. package/dist/providers/registry.d.ts +7 -3
  142. package/dist/providers/registry.js +55 -4
  143. package/dist/providers/registry.js.map +1 -1
  144. package/dist/providers/resend.js +2 -11
  145. package/dist/providers/resend.js.map +1 -1
  146. package/dist/providers/runtime.d.ts +8 -0
  147. package/dist/providers/runtime.js +48 -0
  148. package/dist/providers/runtime.js.map +1 -0
  149. package/dist/providers/stripeWebhook.d.ts +13 -0
  150. package/dist/providers/stripeWebhook.js +50 -0
  151. package/dist/providers/stripeWebhook.js.map +1 -0
  152. package/dist/providers/types.d.ts +153 -0
  153. package/dist/proxy/cacheKey.js +3 -3
  154. package/dist/proxy/cacheKey.js.map +1 -1
  155. package/dist/proxy/providerDetector.d.ts +2 -7
  156. package/dist/proxy/providerDetector.js +4 -4
  157. package/dist/proxy/providerDetector.js.map +1 -1
  158. package/dist/proxy/proxyHandler.js +116 -12
  159. package/dist/proxy/proxyHandler.js.map +1 -1
  160. package/dist/proxy/requestNormalizer.d.ts +0 -1
  161. package/dist/proxy/requestNormalizer.js +2 -5
  162. package/dist/proxy/requestNormalizer.js.map +1 -1
  163. package/dist/reliability/costGovernance.d.ts +175 -0
  164. package/dist/reliability/costGovernance.js +515 -0
  165. package/dist/reliability/costGovernance.js.map +1 -0
  166. package/dist/reliability/index.d.ts +8 -0
  167. package/dist/reliability/index.js +5 -0
  168. package/dist/reliability/index.js.map +1 -0
  169. package/dist/reliability/reconciliation.d.ts +157 -0
  170. package/dist/reliability/reconciliation.js +522 -0
  171. package/dist/reliability/reconciliation.js.map +1 -0
  172. package/dist/reliability/runtimeHealth.d.ts +60 -0
  173. package/dist/reliability/runtimeHealth.js +356 -0
  174. package/dist/reliability/runtimeHealth.js.map +1 -0
  175. package/dist/reliability/slo.d.ts +131 -0
  176. package/dist/reliability/slo.js +375 -0
  177. package/dist/reliability/slo.js.map +1 -0
  178. package/dist/report/safetyReport.js +7 -3
  179. package/dist/report/safetyReport.js.map +1 -1
  180. package/dist/safety/index.d.ts +2 -0
  181. package/dist/safety/index.js +2 -0
  182. package/dist/safety/index.js.map +1 -0
  183. package/dist/safety/safetyController.d.ts +187 -0
  184. package/dist/safety/safetyController.js +477 -0
  185. package/dist/safety/safetyController.js.map +1 -0
  186. package/dist/scenarios/scenarioBundle.d.ts +75 -0
  187. package/dist/scenarios/scenarioBundle.js +750 -0
  188. package/dist/scenarios/scenarioBundle.js.map +1 -0
  189. package/dist/scenarios/scenarioStore.d.ts +1 -0
  190. package/dist/scenarios/scenarioStore.js +47 -32
  191. package/dist/scenarios/scenarioStore.js.map +1 -1
  192. package/dist/security/headerSanitizer.d.ts +2 -0
  193. package/dist/security/headerSanitizer.js +36 -1
  194. package/dist/security/headerSanitizer.js.map +1 -1
  195. package/dist/security/secrets.js +24 -4
  196. package/dist/security/secrets.js.map +1 -1
  197. package/dist/server/accessControl.d.ts +5 -0
  198. package/dist/server/accessControl.js +100 -0
  199. package/dist/server/accessControl.js.map +1 -0
  200. package/dist/server/createServer.d.ts +0 -5
  201. package/dist/server/createServer.js +9 -29
  202. package/dist/server/createServer.js.map +1 -1
  203. package/dist/server/eventsStore.d.ts +6 -1
  204. package/dist/server/eventsStore.js +83 -15
  205. package/dist/server/eventsStore.js.map +1 -1
  206. package/dist/server/routes.js +36 -10
  207. package/dist/server/routes.js.map +1 -1
  208. package/dist/server/sse.d.ts +2 -1
  209. package/dist/server/sse.js +15 -3
  210. package/dist/server/sse.js.map +1 -1
  211. package/dist/setup/setupGenerator.js +53 -6
  212. package/dist/setup/setupGenerator.js.map +1 -1
  213. package/dist/state/stateStore.d.ts +5 -0
  214. package/dist/state/stateStore.js +48 -62
  215. package/dist/state/stateStore.js.map +1 -1
  216. package/dist/storage/fileStore.d.ts +10 -0
  217. package/dist/storage/fileStore.js +131 -0
  218. package/dist/storage/fileStore.js.map +1 -0
  219. package/dist/teamControl/controlPlane.d.ts +255 -0
  220. package/dist/teamControl/controlPlane.js +918 -0
  221. package/dist/teamControl/controlPlane.js.map +1 -0
  222. package/dist/teamControl/deployment.d.ts +33 -0
  223. package/dist/teamControl/deployment.js +67 -0
  224. package/dist/teamControl/deployment.js.map +1 -0
  225. package/dist/teamControl/index.d.ts +4 -0
  226. package/dist/teamControl/index.js +3 -0
  227. package/dist/teamControl/index.js.map +1 -0
  228. package/dist/tests/testGenerator.js +4 -1
  229. package/dist/tests/testGenerator.js.map +1 -1
  230. package/dist/trust/index.d.ts +2 -0
  231. package/dist/trust/index.js +2 -0
  232. package/dist/trust/index.js.map +1 -0
  233. package/dist/trust/trustLadder.d.ts +182 -0
  234. package/dist/trust/trustLadder.js +560 -0
  235. package/dist/trust/trustLadder.js.map +1 -0
  236. package/dist/worlds/index.d.ts +2 -0
  237. package/dist/worlds/index.js +2 -0
  238. package/dist/worlds/index.js.map +1 -0
  239. package/dist/worlds/worlds.d.ts +160 -0
  240. package/dist/worlds/worlds.js +491 -0
  241. package/dist/worlds/worlds.js.map +1 -0
  242. package/docs/assets/dashboard.png +0 -0
  243. package/docs/ci.md +49 -0
  244. package/docs/commercial/README.md +29 -0
  245. package/docs/commercial/data-inventory.md +36 -0
  246. package/docs/commercial/manual-invoicing.md +44 -0
  247. package/docs/commercial/metrics.md +51 -0
  248. package/docs/commercial/pricing.md +103 -0
  249. package/docs/commercial/privacy-policy-draft.md +41 -0
  250. package/docs/commercial/terms-topics-for-counsel.md +51 -0
  251. package/docs/design-partners/README.md +52 -0
  252. package/docs/design-partners/demo-narratives.md +33 -0
  253. package/docs/design-partners/design-partner-offer.md +39 -0
  254. package/docs/design-partners/discovery-questions.md +28 -0
  255. package/docs/design-partners/feedback-capture-template.md +48 -0
  256. package/docs/design-partners/icp-one-pager.md +43 -0
  257. package/docs/design-partners/onboarding-checklist.md +33 -0
  258. package/docs/design-partners/pilot-success-criteria.md +27 -0
  259. package/docs/design-partners/pricing-interview-script.md +18 -0
  260. package/docs/design-partners/telemetry-plan.md +48 -0
  261. package/docs/development/baseline.md +114 -0
  262. package/docs/development/onboarding-smoke.md +37 -0
  263. package/docs/development/verification-0.1.8.md +25 -0
  264. package/docs/enterprise-product-roadmap-ru.md +1879 -0
  265. package/docs/fundraising/README.md +87 -0
  266. package/docs/fundraising/data-room-checklist.md +72 -0
  267. package/docs/fundraising/demo-script.md +52 -0
  268. package/docs/fundraising/design-partners-50.md +74 -0
  269. package/docs/fundraising/launch-posts.md +37 -0
  270. package/docs/fundraising/metrics-and-evidence.md +30 -0
  271. package/docs/fundraising/roadmap-12-month.md +25 -0
  272. package/docs/fundraising/technical-due-diligence-index.md +37 -0
  273. package/docs/fundraising/yc-application.md +25 -0
  274. package/docs/github-actions.md +84 -0
  275. package/docs/hosted-pilot.md +111 -0
  276. package/docs/mcp.md +52 -50
  277. package/docs/operations/disaster-recovery-runbook.md +81 -0
  278. package/docs/operations/kill-switch-runbook.md +32 -0
  279. package/docs/policy.md +61 -0
  280. package/docs/providers/authoring-packs.md +175 -0
  281. package/docs/providers/stripe-core-pack.md +82 -0
  282. package/docs/release-checklist.md +83 -71
  283. package/docs/release-migration-and-rollback.md +63 -0
  284. package/docs/release-readiness.md +39 -0
  285. package/docs/security/action-gateway-threat-model.md +34 -0
  286. package/docs/security/action-ledger-incident-replay-threat-model.md +42 -0
  287. package/docs/security/approval-inbox-threat-model.md +35 -0
  288. package/docs/security/credential-broker-threat-model.md +52 -0
  289. package/docs/security/egress-threat-model.md +126 -0
  290. package/docs/security/inventory-threat-model.md +104 -0
  291. package/docs/security/kill-switch-budgets-threat-model.md +37 -0
  292. package/docs/security/reliability-threat-model.md +111 -0
  293. package/docs/security/trust-ladder-threat-model.md +33 -0
  294. package/docs/team-control-plane.md +72 -0
  295. package/docs/usage.md +571 -57
  296. package/examples/README.md +10 -0
  297. package/examples/agent-instructions/README.md +39 -39
  298. package/examples/ci-smoke/README.md +21 -0
  299. package/examples/ci-smoke/ghostapi.policy.yaml +22 -0
  300. package/examples/ci-smoke/package.json +9 -0
  301. package/examples/ci-smoke/production-egress.mjs +2 -0
  302. package/examples/ci-smoke/safe.mjs +17 -0
  303. package/examples/evals/README.md +24 -0
  304. package/examples/evals/retry-after.eval.json +52 -0
  305. package/examples/generic-rest/README.md +27 -27
  306. package/examples/github-fetch/README.md +35 -35
  307. package/examples/openai-streaming/README.md +16 -0
  308. package/examples/openai-streaming/streaming-tool-call.mjs +31 -0
  309. package/examples/policy/ghostapi.policy.yaml +27 -0
  310. package/examples/record-replay/README.md +19 -0
  311. package/examples/record-replay/replay-requests.json +22 -0
  312. package/examples/record-replay/stripe-checkout.har.json +30 -0
  313. package/examples/resend-node/README.md +22 -22
  314. package/examples/stripe-node/README.md +35 -29
  315. package/examples/stripe-node/checkout-flow.mjs +61 -0
  316. package/examples/twilio-node/README.md +21 -21
  317. package/examples/worlds/README.md +19 -0
  318. package/examples/worlds/subscription-recovery.mjs +12 -0
  319. package/package.json +26 -11
  320. package/dist/providers/stripe.d.ts +0 -2
  321. package/dist/providers/stripe.js +0 -15
  322. package/dist/providers/stripe.js.map +0 -1
  323. package/docs/assets/ghostapi-avatar.png +0 -0
@@ -1,349 +1,349 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
2
-
3
- :root {
4
- --background: #09090b; /* zinc-950 */
5
- --foreground: #fafafa;
6
- --card: #09090b;
7
- --card-foreground: #fafafa;
8
- --popover: #09090b;
9
- --popover-foreground: #fafafa;
10
- --primary: #fafafa;
11
- --primary-foreground: #18181b;
12
- --secondary: #27272a;
13
- --secondary-foreground: #fafafa;
14
- --muted: #27272a;
15
- --muted-foreground: #a1a1aa; /* zinc-400 */
16
- --accent: #27272a;
17
- --accent-foreground: #fafafa;
18
- --border: rgba(255, 255, 255, 0.1);
19
- --input: #27272a;
20
- --ring: #d4d4d8;
21
-
22
- --radius: 0.5rem;
23
-
24
- --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
25
- --font-mono: 'JetBrains Mono', "Geist Mono", "Fira Code", monospace;
26
-
27
- --sys-green: #4ade80;
28
- --sys-blue: #60a5fa;
29
- --sys-red: #f87171;
30
- --sys-orange: #fbbf24;
31
- }
32
-
33
- * {
34
- box-sizing: border-box;
35
- margin: 0;
36
- padding: 0;
37
- }
38
-
39
- body {
40
- background-color: var(--background);
41
- color: var(--foreground);
42
- font-family: var(--font-sans);
43
- -webkit-font-smoothing: antialiased;
44
- font-size: 13px;
45
- overflow: hidden;
46
- }
47
-
48
- /* Layout Wrappers */
49
- .app-wrapper {
50
- display: flex;
51
- width: 100vw;
52
- height: 100vh;
53
- background: var(--background);
54
- }
55
-
56
- /* Sidebar */
57
- .sidebar {
58
- width: 260px;
59
- height: 100%;
60
- background-color: rgba(255, 255, 255, 0.02);
61
- border-right: 1px solid var(--border);
62
- padding: 12px;
63
- display: flex;
64
- flex-direction: column;
65
- flex-shrink: 0;
66
- transition: width 0.3s ease, opacity 0.3s ease;
67
- overflow: hidden;
68
- }
69
-
70
- .sidebar.closed {
71
- width: 0;
72
- padding-left: 0;
73
- padding-right: 0;
74
- opacity: 0;
75
- border-right: none;
76
- }
77
-
78
- /* Workspace Switcher */
79
- .ws-switcher {
80
- position: relative;
81
- margin-bottom: 24px;
82
- }
83
- .ws-btn {
84
- display: flex;
85
- align-items: center;
86
- justify-content: space-between;
87
- padding: 8px;
88
- border-radius: var(--radius);
89
- user-select: none;
90
- }
91
- .ws-btn-content { display: flex; align-items: center; gap: 12px; }
92
- .ws-avatar {
93
- width: 32px; height: 32px;
94
- border-radius: 6px;
95
- background: var(--primary);
96
- color: var(--primary-foreground);
97
- display: flex; align-items: center; justify-content: center;
98
- font-weight: 600; font-size: 13px;
99
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
100
- }
101
- .ws-info { display: flex; flex-direction: column; overflow: hidden; }
102
- .ws-title { font-size: 13px; font-weight: 500; line-height: 1; margin-bottom: 4px; color: var(--foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; }
103
- .ws-subtitle { font-size: 11px; color: var(--muted-foreground); line-height: 1; }
104
- .ws-icon { color: rgba(161, 161, 170, 0.5); width: 16px; height: 16px; transition: color 0.2s; }
105
- .ws-btn:hover .ws-icon { color: rgba(250, 250, 250, 0.7); }
106
-
107
- /* Sidebar Nav Groups */
108
- .nav-scroll-area {
109
- flex: 1;
110
- overflow-y: auto;
111
- display: flex;
112
- flex-direction: column;
113
- gap: 16px;
114
- margin-top: 8px;
115
- }
116
- .nav-scroll-area::-webkit-scrollbar { display: none; }
117
- .nav-group { display: flex; flex-direction: column; gap: 2px; }
118
- .nav-heading {
119
- padding: 0 10px; margin-bottom: 4px;
120
- font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
121
- color: rgba(161, 161, 170, 0.5); text-transform: uppercase;
122
- }
123
-
124
- /* Nav Item */
125
- .nav-item {
126
- display: flex; align-items: center; justify-content: space-between;
127
- padding: 7px 10px;
128
- border-radius: 6px;
129
- cursor: pointer;
130
- transition: all 0.2s;
131
- user-select: none;
132
- color: var(--muted-foreground);
133
- }
134
- .nav-item:hover { color: rgba(250, 250, 250, 0.9); background: rgba(255, 255, 255, 0.05); }
135
- .nav-item.active { background: rgba(255, 255, 255, 0.1); color: var(--foreground); font-weight: 500; }
136
- .nav-item-left { display: flex; align-items: center; gap: 10px; }
137
- .nav-item-icon { width: 16px; height: 16px; color: rgba(161, 161, 170, 0.7); transition: color 0.2s; }
138
- .nav-item:hover .nav-item-icon { color: rgba(250, 250, 250, 0.7); }
139
- .nav-item.active .nav-item-icon { color: var(--foreground); }
140
- .nav-item-title { font-size: 13px; tracking-wide; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
141
- .nav-item-right { display: flex; align-items: center; gap: 8px; }
142
-
143
- /* Status Badge/Shortcuts injected via JS natively */
144
- .sc-badge { display: none; align-items: center; justify-content: center; height: 20px; padding: 0 6px; font-size: 10px; font-weight: 500; font-family: var(--font-mono); color: rgba(161, 161, 170, 0.6); background: rgba(0, 0, 0, 0.5); border: 1px solid var(--border); border-radius: 4px; }
145
- .nav-item:hover .sc-badge { display: flex; }
146
- .num-badge { display: flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; font-size: 10px; font-weight: 500; border-radius: 99px; background: rgba(250, 250, 250, 0.1); color: var(--primary); }
147
- .fault-toggle.active { color: #fef3c7; background: rgba(251, 191, 36, 0.1); }
148
- .fault-toggle.active .nav-item-icon { color: var(--sys-orange); }
149
- .fault-state { font-family: var(--font-mono); font-size: 10px; color: var(--muted-foreground); border: 1px solid var(--border); border-radius: 99px; padding: 2px 6px; }
150
- .fault-toggle.active .fault-state { color: var(--sys-orange); border-color: rgba(251, 191, 36, 0.25); background: rgba(251, 191, 36, 0.08); }
151
-
152
- .nav-bottom {
153
- margin-top: auto;
154
- padding-top: 16px;
155
- border-top: 1px solid var(--border);
156
- display: flex;
157
- flex-direction: column;
158
- gap: 2px;
159
- }
160
-
161
- /* Main Content Area */
162
- .main {
163
- flex: 1;
164
- display: flex;
165
- flex-direction: column;
166
- background: rgba(255, 255, 255, 0.01);
167
- min-width: 0;
168
- transition: all 0.3s;
169
- }
170
-
171
- /* Topbar */
172
- .topbar {
173
- height: 56px;
174
- border-bottom: 1px solid var(--border);
175
- display: flex;
176
- align-items: center;
177
- justify-content: space-between;
178
- padding: 0 16px;
179
- background: var(--card);
180
- flex-shrink: 0;
181
- }
182
- .topbar-left { display: flex; align-items: center; gap: 12px; }
183
- .toggle-btn {
184
- padding: 6px; border-radius: 6px; color: var(--muted-foreground); cursor: pointer; transition: all 0.2s; background: transparent; border: none; outline: none;
185
- }
186
- .toggle-btn:hover { background: rgba(255,255,255,0.05); color: var(--foreground); }
187
-
188
- .breadcrumb { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted-foreground); }
189
- .breadcrumb-active { font-weight: 500; color: var(--foreground); }
190
-
191
- .topbar-right { display: flex; align-items: center; gap: 12px; }
192
- .status-indicator {
193
- display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 6px; font-size: 12px; background: rgba(255,255,255,0.03); color: var(--muted-foreground); border: 1px solid var(--border);
194
- }
195
- .status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted-foreground); }
196
- .status-indicator.connected .status-dot { background: var(--sys-green); box-shadow: 0 0 10px rgba(74, 222, 128, 0.4); }
197
- .status-indicator.connected { color: var(--foreground); }
198
-
199
- /* Main Split View: Event List (Left) + Event Details (Right) */
200
- .content-wrapper {
201
- flex: 1;
202
- display: flex;
203
- overflow: hidden;
204
- }
205
-
206
- /* Event List Pane */
207
- .event-list-pane {
208
- width: 340px;
209
- border-right: 1px solid var(--border);
210
- display: flex;
211
- flex-direction: column;
212
- background: var(--background);
213
- }
214
- .event-list-header {
215
- padding: 12px 16px;
216
- border-bottom: 1px solid var(--border);
217
- display: flex; justify-content: space-between; align-items: center;
218
- }
219
- .event-list-header h2 { font-size: 13px; font-weight: 600; color: var(--foreground); }
220
- .event-count { font-family: var(--font-mono); font-size: 11px; color: var(--muted-foreground); background: rgba(255,255,255,0.05); padding: 2px 6px; border-radius: 4px;}
221
-
222
- .events-scroll { flex: 1; overflow-y: auto; }
223
- .events-scroll::-webkit-scrollbar { display: none; }
224
-
225
- .event-card {
226
- padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.2s;
227
- }
228
- .event-card:hover { background: rgba(255,255,255,0.02); }
229
- .event-card.active { background: rgba(255,255,255,0.04); border-left: 2px solid var(--sys-blue); padding-left: 14px; }
230
-
231
- .ec-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
232
- .ec-method { font-family: var(--font-mono); font-size: 11px; font-weight: 600; padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,0.05); color: var(--foreground);}
233
- .ec-time { font-size: 11px; color: var(--muted-foreground); }
234
- .ec-path { font-family: var(--font-mono); font-size: 12px; color: var(--foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 8px;}
235
- .ec-bottom { display: flex; align-items: center; gap: 8px; font-size: 11px; }
236
- .provider-pill { margin-left: auto; }
237
-
238
- .pill { padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,0.05); color: var(--muted-foreground); border: 1px solid var(--border); font-family: var(--font-mono); }
239
- .pill-status-200 { color: var(--sys-green); border-color: rgba(74, 222, 128, 0.2); background: rgba(74, 222, 128, 0.05); }
240
- .pill-status-400, .pill-status-500 { color: var(--sys-red); border-color: rgba(248, 113, 113, 0.2); background: rgba(248, 113, 113, 0.05); }
241
-
242
- /* Details Pane */
243
- .details-pane {
244
- flex: 1;
245
- display: flex;
246
- flex-direction: column;
247
- background: var(--background);
248
- min-width: 0;
249
- }
250
- .empty-view {
251
- flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--muted-foreground); gap: 12px;
252
- }
253
- .empty-view svg { opacity: 0.3; }
254
-
255
- .details-content { flex: 1; display: flex; flex-direction: column; display: none; }
256
- .details-content.visible { display: flex; }
257
-
258
- .dep-header {
259
- padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; background: rgba(255,255,255,0.01);
260
- }
261
- .dep-title { display: flex; align-items: center; gap: 12px; font-family: var(--font-mono); font-size: 14px; }
262
- .dep-badges { display: flex; gap: 8px; }
263
- .mini-action { border: 1px solid var(--border); background: rgba(255,255,255,0.04); color: var(--foreground); border-radius: 6px; padding: 3px 8px; font: 500 11px var(--font-sans); cursor: pointer; }
264
- .mini-action:hover { background: rgba(255,255,255,0.08); }
265
-
266
- .json-split {
267
- flex: 1; display: flex; overflow: hidden;
268
- }
269
- .json-pane {
270
- flex: 1; display: flex; flex-direction: column; border-right: 1px solid var(--border); min-width: 0;
271
- }
272
- .json-pane:last-child { border-right: none; }
273
-
274
- .json-header {
275
- padding: 8px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between;
276
- font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; color: var(--muted-foreground); background: var(--background);
277
- }
278
- .json-body {
279
- flex: 1; overflow: auto; padding: 16px; background: rgba(255,255,255,0.01);
280
- }
281
- .json-body pre { font-family: var(--font-mono); font-size: 12px; line-height: 1.6; color: var(--foreground); white-space: pre-wrap; word-wrap: break-word; }
282
-
283
- /* Modal / Search */
284
- .modal-overlay {
285
- position: fixed; inset: 0; z-index: 50; display: none; align-items: flex-start; justify-content: center; padding: 12vh 16px 24px; background: rgba(0,0,0,0.4); backdrop-filter: blur(2px); overflow: auto;
286
- }
287
- .modal-overlay.open { display: flex; }
288
- .modal-content {
289
- position: relative; width: 100%; max-width: 600px; max-height: calc(100vh - 48px); background: var(--card); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 24px 48px rgba(0,0,0,0.4); overflow: hidden; animation: zoomIn 0.15s ease-out;
290
- }
291
- .modal-header {
292
- display: flex; align-items: center; padding: 0 16px; border-bottom: 1px solid var(--border);
293
- }
294
- .modal-header svg { color: var(--muted-foreground); margin-right: 12px; }
295
- .modal-input {
296
- flex: 1; background: transparent; border: none; padding: 16px 0; outline: none; font-size: 14px; color: var(--foreground); font-family: var(--font-sans);
297
- }
298
- .modal-input::placeholder { color: rgba(161, 161, 170, 0.5); }
299
- .modal-body { padding: 32px 16px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--muted-foreground); gap: 8px; }
300
- .rules-modal-content { max-width: 860px; }
301
- .rules-modal-header { gap: 12px; padding: 12px 16px; }
302
- .rules-title-block { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
303
- .rules-title-block strong { font-size: 13px; color: var(--foreground); }
304
- .rules-title-block span { font-size: 11px; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
305
- .modal-action { border: 1px solid rgba(250,250,250,0.16); background: rgba(250,250,250,0.92); color: #18181b; border-radius: 6px; padding: 6px 10px; font: 500 12px var(--font-sans); cursor: pointer; }
306
- .modal-action.ghost { background: rgba(255,255,255,0.04); color: var(--muted-foreground); }
307
- .modal-action:hover { filter: brightness(1.08); }
308
- .rules-body { max-height: 70vh; overflow: auto; padding: 16px; background: radial-gradient(circle at top left, rgba(96,165,250,0.08), transparent 28%), rgba(255,255,255,0.01); }
309
- .rules-body pre { font-family: var(--font-mono); font-size: 12px; line-height: 1.7; white-space: pre-wrap; color: var(--foreground); }
310
- .setup-modal-content { max-width: 980px; }
311
- .setup-grid, .scenario-shell { display: grid; grid-template-columns: 300px minmax(0, 1fr); min-height: 560px; max-height: 74vh; }
312
- .setup-list, .scenario-list { border-right: 1px solid var(--border); overflow: auto; padding: 10px; background: rgba(255,255,255,0.01); }
313
- .setup-output, .scenario-output { max-height: none; height: 100%; }
314
- .setup-item { width: 100%; border: 1px solid transparent; background: transparent; color: var(--muted-foreground); border-radius: 8px; padding: 10px; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: 4px; }
315
- .setup-item:hover, .setup-item.active { background: rgba(255,255,255,0.05); border-color: var(--border); color: var(--foreground); }
316
- .setup-item strong { font: 600 12px var(--font-sans); color: inherit; }
317
- .setup-item span { font-size: 11px; line-height: 1.4; color: var(--muted-foreground); }
318
- .scenario-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px; margin-bottom: 10px; background: rgba(255,255,255,0.02); }
319
- .scenario-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
320
- .scenario-card strong { font-size: 13px; color: var(--foreground); }
321
- .scenario-card p { font-size: 12px; line-height: 1.5; color: var(--muted-foreground); margin-bottom: 12px; }
322
- .scenario-actions { display: flex; gap: 6px; }
323
- .scenario-actions button { flex: 1; border: 1px solid var(--border); background: rgba(255,255,255,0.04); color: var(--foreground); border-radius: 6px; padding: 6px; font: 500 11px var(--font-sans); cursor: pointer; }
324
- .scenario-actions button:hover { background: rgba(255,255,255,0.08); }
325
-
326
- @media (max-width: 900px) {
327
- .modal-overlay { padding-top: 24px; }
328
- .setup-grid, .scenario-shell { grid-template-columns: 1fr; min-height: auto; }
329
- .setup-list, .scenario-list { border-right: none; border-bottom: 1px solid var(--border); max-height: 260px; }
330
- }
331
-
332
- @media (max-height: 720px) {
333
- .setup-grid, .scenario-shell { min-height: 0; }
334
- }
335
-
336
- @keyframes zoomIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }
337
-
338
- /* Method Colors */
339
- .m-get { color: var(--sys-blue); }
340
- .m-post { color: var(--sys-green); }
341
- .m-delete { color: var(--sys-red); }
342
- .m-put, .m-patch { color: var(--sys-orange); }
343
-
344
- /* Syntax Highlight */
345
- .j-key { color: #86efac; opacity: 0.9; }
346
- .j-str { color: #fca5a5; opacity: 0.9; }
347
- .j-num { color: #7dd3fc; opacity: 0.9; }
348
- .j-bool { color: #c4b5fd; opacity: 0.9; }
349
- .j-null { color: var(--muted-foreground); font-style: italic; }
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
2
+
3
+ :root {
4
+ --background: #09090b; /* zinc-950 */
5
+ --foreground: #fafafa;
6
+ --card: #09090b;
7
+ --card-foreground: #fafafa;
8
+ --popover: #09090b;
9
+ --popover-foreground: #fafafa;
10
+ --primary: #fafafa;
11
+ --primary-foreground: #18181b;
12
+ --secondary: #27272a;
13
+ --secondary-foreground: #fafafa;
14
+ --muted: #27272a;
15
+ --muted-foreground: #a1a1aa; /* zinc-400 */
16
+ --accent: #27272a;
17
+ --accent-foreground: #fafafa;
18
+ --border: rgba(255, 255, 255, 0.1);
19
+ --input: #27272a;
20
+ --ring: #d4d4d8;
21
+
22
+ --radius: 0.5rem;
23
+
24
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
25
+ --font-mono: 'JetBrains Mono', "Geist Mono", "Fira Code", monospace;
26
+
27
+ --sys-green: #4ade80;
28
+ --sys-blue: #60a5fa;
29
+ --sys-red: #f87171;
30
+ --sys-orange: #fbbf24;
31
+ }
32
+
33
+ * {
34
+ box-sizing: border-box;
35
+ margin: 0;
36
+ padding: 0;
37
+ }
38
+
39
+ body {
40
+ background-color: var(--background);
41
+ color: var(--foreground);
42
+ font-family: var(--font-sans);
43
+ -webkit-font-smoothing: antialiased;
44
+ font-size: 13px;
45
+ overflow: hidden;
46
+ }
47
+
48
+ /* Layout Wrappers */
49
+ .app-wrapper {
50
+ display: flex;
51
+ width: 100vw;
52
+ height: 100vh;
53
+ background: var(--background);
54
+ }
55
+
56
+ /* Sidebar */
57
+ .sidebar {
58
+ width: 260px;
59
+ height: 100%;
60
+ background-color: rgba(255, 255, 255, 0.02);
61
+ border-right: 1px solid var(--border);
62
+ padding: 12px;
63
+ display: flex;
64
+ flex-direction: column;
65
+ flex-shrink: 0;
66
+ transition: width 0.3s ease, opacity 0.3s ease;
67
+ overflow: hidden;
68
+ }
69
+
70
+ .sidebar.closed {
71
+ width: 0;
72
+ padding-left: 0;
73
+ padding-right: 0;
74
+ opacity: 0;
75
+ border-right: none;
76
+ }
77
+
78
+ /* Workspace Switcher */
79
+ .ws-switcher {
80
+ position: relative;
81
+ margin-bottom: 24px;
82
+ }
83
+ .ws-btn {
84
+ display: flex;
85
+ align-items: center;
86
+ justify-content: space-between;
87
+ padding: 8px;
88
+ border-radius: var(--radius);
89
+ user-select: none;
90
+ }
91
+ .ws-btn-content { display: flex; align-items: center; gap: 12px; }
92
+ .ws-avatar {
93
+ width: 32px; height: 32px;
94
+ border-radius: 6px;
95
+ background: var(--primary);
96
+ color: var(--primary-foreground);
97
+ display: flex; align-items: center; justify-content: center;
98
+ font-weight: 600; font-size: 13px;
99
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
100
+ }
101
+ .ws-info { display: flex; flex-direction: column; overflow: hidden; }
102
+ .ws-title { font-size: 13px; font-weight: 500; line-height: 1; margin-bottom: 4px; color: var(--foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; }
103
+ .ws-subtitle { font-size: 11px; color: var(--muted-foreground); line-height: 1; }
104
+ .ws-icon { color: rgba(161, 161, 170, 0.5); width: 16px; height: 16px; transition: color 0.2s; }
105
+ .ws-btn:hover .ws-icon { color: rgba(250, 250, 250, 0.7); }
106
+
107
+ /* Sidebar Nav Groups */
108
+ .nav-scroll-area {
109
+ flex: 1;
110
+ overflow-y: auto;
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 16px;
114
+ margin-top: 8px;
115
+ }
116
+ .nav-scroll-area::-webkit-scrollbar { display: none; }
117
+ .nav-group { display: flex; flex-direction: column; gap: 2px; }
118
+ .nav-heading {
119
+ padding: 0 10px; margin-bottom: 4px;
120
+ font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
121
+ color: rgba(161, 161, 170, 0.5); text-transform: uppercase;
122
+ }
123
+
124
+ /* Nav Item */
125
+ .nav-item {
126
+ display: flex; align-items: center; justify-content: space-between;
127
+ padding: 7px 10px;
128
+ border-radius: 6px;
129
+ cursor: pointer;
130
+ transition: all 0.2s;
131
+ user-select: none;
132
+ color: var(--muted-foreground);
133
+ }
134
+ .nav-item:hover { color: rgba(250, 250, 250, 0.9); background: rgba(255, 255, 255, 0.05); }
135
+ .nav-item.active { background: rgba(255, 255, 255, 0.1); color: var(--foreground); font-weight: 500; }
136
+ .nav-item-left { display: flex; align-items: center; gap: 10px; }
137
+ .nav-item-icon { width: 16px; height: 16px; color: rgba(161, 161, 170, 0.7); transition: color 0.2s; }
138
+ .nav-item:hover .nav-item-icon { color: rgba(250, 250, 250, 0.7); }
139
+ .nav-item.active .nav-item-icon { color: var(--foreground); }
140
+ .nav-item-title { font-size: 13px; tracking-wide; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
141
+ .nav-item-right { display: flex; align-items: center; gap: 8px; }
142
+
143
+ /* Status Badge/Shortcuts injected via JS natively */
144
+ .sc-badge { display: none; align-items: center; justify-content: center; height: 20px; padding: 0 6px; font-size: 10px; font-weight: 500; font-family: var(--font-mono); color: rgba(161, 161, 170, 0.6); background: rgba(0, 0, 0, 0.5); border: 1px solid var(--border); border-radius: 4px; }
145
+ .nav-item:hover .sc-badge { display: flex; }
146
+ .num-badge { display: flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; font-size: 10px; font-weight: 500; border-radius: 99px; background: rgba(250, 250, 250, 0.1); color: var(--primary); }
147
+ .fault-toggle.active { color: #fef3c7; background: rgba(251, 191, 36, 0.1); }
148
+ .fault-toggle.active .nav-item-icon { color: var(--sys-orange); }
149
+ .fault-state { font-family: var(--font-mono); font-size: 10px; color: var(--muted-foreground); border: 1px solid var(--border); border-radius: 99px; padding: 2px 6px; }
150
+ .fault-toggle.active .fault-state { color: var(--sys-orange); border-color: rgba(251, 191, 36, 0.25); background: rgba(251, 191, 36, 0.08); }
151
+
152
+ .nav-bottom {
153
+ margin-top: auto;
154
+ padding-top: 16px;
155
+ border-top: 1px solid var(--border);
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 2px;
159
+ }
160
+
161
+ /* Main Content Area */
162
+ .main {
163
+ flex: 1;
164
+ display: flex;
165
+ flex-direction: column;
166
+ background: rgba(255, 255, 255, 0.01);
167
+ min-width: 0;
168
+ transition: all 0.3s;
169
+ }
170
+
171
+ /* Topbar */
172
+ .topbar {
173
+ height: 56px;
174
+ border-bottom: 1px solid var(--border);
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ padding: 0 16px;
179
+ background: var(--card);
180
+ flex-shrink: 0;
181
+ }
182
+ .topbar-left { display: flex; align-items: center; gap: 12px; }
183
+ .toggle-btn {
184
+ padding: 6px; border-radius: 6px; color: var(--muted-foreground); cursor: pointer; transition: all 0.2s; background: transparent; border: none; outline: none;
185
+ }
186
+ .toggle-btn:hover { background: rgba(255,255,255,0.05); color: var(--foreground); }
187
+
188
+ .breadcrumb { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted-foreground); }
189
+ .breadcrumb-active { font-weight: 500; color: var(--foreground); }
190
+
191
+ .topbar-right { display: flex; align-items: center; gap: 12px; }
192
+ .status-indicator {
193
+ display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 6px; font-size: 12px; background: rgba(255,255,255,0.03); color: var(--muted-foreground); border: 1px solid var(--border);
194
+ }
195
+ .status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted-foreground); }
196
+ .status-indicator.connected .status-dot { background: var(--sys-green); box-shadow: 0 0 10px rgba(74, 222, 128, 0.4); }
197
+ .status-indicator.connected { color: var(--foreground); }
198
+
199
+ /* Main Split View: Event List (Left) + Event Details (Right) */
200
+ .content-wrapper {
201
+ flex: 1;
202
+ display: flex;
203
+ overflow: hidden;
204
+ }
205
+
206
+ /* Event List Pane */
207
+ .event-list-pane {
208
+ width: 340px;
209
+ border-right: 1px solid var(--border);
210
+ display: flex;
211
+ flex-direction: column;
212
+ background: var(--background);
213
+ }
214
+ .event-list-header {
215
+ padding: 12px 16px;
216
+ border-bottom: 1px solid var(--border);
217
+ display: flex; justify-content: space-between; align-items: center;
218
+ }
219
+ .event-list-header h2 { font-size: 13px; font-weight: 600; color: var(--foreground); }
220
+ .event-count { font-family: var(--font-mono); font-size: 11px; color: var(--muted-foreground); background: rgba(255,255,255,0.05); padding: 2px 6px; border-radius: 4px;}
221
+
222
+ .events-scroll { flex: 1; overflow-y: auto; }
223
+ .events-scroll::-webkit-scrollbar { display: none; }
224
+
225
+ .event-card {
226
+ padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background 0.2s;
227
+ }
228
+ .event-card:hover { background: rgba(255,255,255,0.02); }
229
+ .event-card.active { background: rgba(255,255,255,0.04); border-left: 2px solid var(--sys-blue); padding-left: 14px; }
230
+
231
+ .ec-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
232
+ .ec-method { font-family: var(--font-mono); font-size: 11px; font-weight: 600; padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,0.05); color: var(--foreground);}
233
+ .ec-time { font-size: 11px; color: var(--muted-foreground); }
234
+ .ec-path { font-family: var(--font-mono); font-size: 12px; color: var(--foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 8px;}
235
+ .ec-bottom { display: flex; align-items: center; gap: 8px; font-size: 11px; }
236
+ .provider-pill { margin-left: auto; }
237
+
238
+ .pill { padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,0.05); color: var(--muted-foreground); border: 1px solid var(--border); font-family: var(--font-mono); }
239
+ .pill-status-200 { color: var(--sys-green); border-color: rgba(74, 222, 128, 0.2); background: rgba(74, 222, 128, 0.05); }
240
+ .pill-status-400, .pill-status-500 { color: var(--sys-red); border-color: rgba(248, 113, 113, 0.2); background: rgba(248, 113, 113, 0.05); }
241
+
242
+ /* Details Pane */
243
+ .details-pane {
244
+ flex: 1;
245
+ display: flex;
246
+ flex-direction: column;
247
+ background: var(--background);
248
+ min-width: 0;
249
+ }
250
+ .empty-view {
251
+ flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--muted-foreground); gap: 12px;
252
+ }
253
+ .empty-view svg { opacity: 0.3; }
254
+
255
+ .details-content { flex: 1; display: flex; flex-direction: column; display: none; }
256
+ .details-content.visible { display: flex; }
257
+
258
+ .dep-header {
259
+ padding: 16px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; background: rgba(255,255,255,0.01);
260
+ }
261
+ .dep-title { display: flex; align-items: center; gap: 12px; font-family: var(--font-mono); font-size: 14px; }
262
+ .dep-badges { display: flex; gap: 8px; }
263
+ .mini-action { border: 1px solid var(--border); background: rgba(255,255,255,0.04); color: var(--foreground); border-radius: 6px; padding: 3px 8px; font: 500 11px var(--font-sans); cursor: pointer; }
264
+ .mini-action:hover { background: rgba(255,255,255,0.08); }
265
+
266
+ .json-split {
267
+ flex: 1; display: flex; overflow: hidden;
268
+ }
269
+ .json-pane {
270
+ flex: 1; display: flex; flex-direction: column; border-right: 1px solid var(--border); min-width: 0;
271
+ }
272
+ .json-pane:last-child { border-right: none; }
273
+
274
+ .json-header {
275
+ padding: 8px 16px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between;
276
+ font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; color: var(--muted-foreground); background: var(--background);
277
+ }
278
+ .json-body {
279
+ flex: 1; overflow: auto; padding: 16px; background: rgba(255,255,255,0.01);
280
+ }
281
+ .json-body pre { font-family: var(--font-mono); font-size: 12px; line-height: 1.6; color: var(--foreground); white-space: pre-wrap; word-wrap: break-word; }
282
+
283
+ /* Modal / Search */
284
+ .modal-overlay {
285
+ position: fixed; inset: 0; z-index: 50; display: none; align-items: flex-start; justify-content: center; padding: 12vh 16px 24px; background: rgba(0,0,0,0.4); backdrop-filter: blur(2px); overflow: auto;
286
+ }
287
+ .modal-overlay.open { display: flex; }
288
+ .modal-content {
289
+ position: relative; width: 100%; max-width: 600px; max-height: calc(100vh - 48px); background: var(--card); border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 24px 48px rgba(0,0,0,0.4); overflow: hidden; animation: zoomIn 0.15s ease-out;
290
+ }
291
+ .modal-header {
292
+ display: flex; align-items: center; padding: 0 16px; border-bottom: 1px solid var(--border);
293
+ }
294
+ .modal-header svg { color: var(--muted-foreground); margin-right: 12px; }
295
+ .modal-input {
296
+ flex: 1; background: transparent; border: none; padding: 16px 0; outline: none; font-size: 14px; color: var(--foreground); font-family: var(--font-sans);
297
+ }
298
+ .modal-input::placeholder { color: rgba(161, 161, 170, 0.5); }
299
+ .modal-body { padding: 32px 16px; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--muted-foreground); gap: 8px; }
300
+ .rules-modal-content { max-width: 860px; }
301
+ .rules-modal-header { gap: 12px; padding: 12px 16px; }
302
+ .rules-title-block { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
303
+ .rules-title-block strong { font-size: 13px; color: var(--foreground); }
304
+ .rules-title-block span { font-size: 11px; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
305
+ .modal-action { border: 1px solid rgba(250,250,250,0.16); background: rgba(250,250,250,0.92); color: #18181b; border-radius: 6px; padding: 6px 10px; font: 500 12px var(--font-sans); cursor: pointer; }
306
+ .modal-action.ghost { background: rgba(255,255,255,0.04); color: var(--muted-foreground); }
307
+ .modal-action:hover { filter: brightness(1.08); }
308
+ .rules-body { max-height: 70vh; overflow: auto; padding: 16px; background: radial-gradient(circle at top left, rgba(96,165,250,0.08), transparent 28%), rgba(255,255,255,0.01); }
309
+ .rules-body pre { font-family: var(--font-mono); font-size: 12px; line-height: 1.7; white-space: pre-wrap; color: var(--foreground); }
310
+ .setup-modal-content { max-width: 980px; height: min(74vh, 680px); display: flex; flex-direction: column; }
311
+ .setup-grid, .scenario-shell { display: grid; grid-template-columns: 300px minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
312
+ .setup-list, .scenario-list { min-height: 0; border-right: 1px solid var(--border); overflow: auto; padding: 10px; background: rgba(255,255,255,0.01); }
313
+ .setup-output, .scenario-output { min-height: 0; max-height: none; height: 100%; overflow: auto; }
314
+ .setup-item { width: 100%; border: 1px solid transparent; background: transparent; color: var(--muted-foreground); border-radius: 8px; padding: 10px; text-align: left; cursor: pointer; display: flex; flex-direction: column; gap: 4px; }
315
+ .setup-item:hover, .setup-item.active { background: rgba(255,255,255,0.05); border-color: var(--border); color: var(--foreground); }
316
+ .setup-item strong { font: 600 12px var(--font-sans); color: inherit; }
317
+ .setup-item span { font-size: 11px; line-height: 1.4; color: var(--muted-foreground); }
318
+ .scenario-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px; margin-bottom: 10px; background: rgba(255,255,255,0.02); }
319
+ .scenario-card-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
320
+ .scenario-card strong { font-size: 13px; color: var(--foreground); }
321
+ .scenario-card p { font-size: 12px; line-height: 1.5; color: var(--muted-foreground); margin-bottom: 12px; }
322
+ .scenario-actions { display: flex; gap: 6px; }
323
+ .scenario-actions button { flex: 1; border: 1px solid var(--border); background: rgba(255,255,255,0.04); color: var(--foreground); border-radius: 6px; padding: 6px; font: 500 11px var(--font-sans); cursor: pointer; }
324
+ .scenario-actions button:hover { background: rgba(255,255,255,0.08); }
325
+
326
+ @media (max-width: 900px) {
327
+ .modal-overlay { padding-top: 24px; }
328
+ .setup-grid, .scenario-shell { grid-template-columns: 1fr; grid-template-rows: minmax(0, 260px) minmax(0, 1fr); }
329
+ .setup-list, .scenario-list { border-right: none; border-bottom: 1px solid var(--border); max-height: none; }
330
+ }
331
+
332
+ @media (max-height: 720px) {
333
+ .setup-modal-content { height: calc(100vh - 48px); }
334
+ }
335
+
336
+ @keyframes zoomIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }
337
+
338
+ /* Method Colors */
339
+ .m-get { color: var(--sys-blue); }
340
+ .m-post { color: var(--sys-green); }
341
+ .m-delete { color: var(--sys-red); }
342
+ .m-put, .m-patch { color: var(--sys-orange); }
343
+
344
+ /* Syntax Highlight */
345
+ .j-key { color: #86efac; opacity: 0.9; }
346
+ .j-str { color: #fca5a5; opacity: 0.9; }
347
+ .j-num { color: #7dd3fc; opacity: 0.9; }
348
+ .j-bool { color: #c4b5fd; opacity: 0.9; }
349
+ .j-null { color: var(--muted-foreground); font-style: italic; }