zig-mobile-runner 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/CHANGELOG.md +484 -0
  2. package/CONTRIBUTING.md +42 -0
  3. package/FEATURES.md +112 -0
  4. package/LICENSE +21 -0
  5. package/README.md +255 -0
  6. package/SECURITY.md +34 -0
  7. package/build.zig +38 -0
  8. package/build.zig.zon +7 -0
  9. package/clients/README.md +144 -0
  10. package/clients/go/README.md +24 -0
  11. package/clients/go/examples/fake-session/main.go +93 -0
  12. package/clients/go/go.mod +3 -0
  13. package/clients/go/zmr/client.go +432 -0
  14. package/clients/kotlin/README.md +35 -0
  15. package/clients/kotlin/build.gradle.kts +35 -0
  16. package/clients/kotlin/settings.gradle.kts +15 -0
  17. package/clients/kotlin/src/main/kotlin/dev/zmr/FakeSession.kt +86 -0
  18. package/clients/kotlin/src/main/kotlin/dev/zmr/ZmrClient.kt +67 -0
  19. package/clients/python/README.md +29 -0
  20. package/clients/python/examples/fake_session.py +48 -0
  21. package/clients/python/pyproject.toml +13 -0
  22. package/clients/python/zmr_client.py +202 -0
  23. package/clients/rust/Cargo.lock +107 -0
  24. package/clients/rust/Cargo.toml +10 -0
  25. package/clients/rust/README.md +19 -0
  26. package/clients/rust/examples/fake_session.rs +70 -0
  27. package/clients/rust/src/lib.rs +461 -0
  28. package/clients/swift/Package.swift +16 -0
  29. package/clients/swift/README.md +36 -0
  30. package/clients/swift/Sources/ZMRClient/ZMRClient.swift +114 -0
  31. package/clients/swift/Sources/ZMRFakeSession/main.swift +86 -0
  32. package/clients/typescript/README.md +34 -0
  33. package/clients/typescript/examples/fake-session.mjs +36 -0
  34. package/clients/typescript/index.d.ts +144 -0
  35. package/clients/typescript/index.mjs +192 -0
  36. package/clients/typescript/package.json +8 -0
  37. package/docs/adr/0001-agent-native-runner-boundary.md +31 -0
  38. package/docs/adr/0002-app-local-zmr-contract.md +39 -0
  39. package/docs/adr/0003-ios-simulator-xctest-shim.md +41 -0
  40. package/docs/adr/0004-benchmark-claims-and-baseline-collection.md +37 -0
  41. package/docs/adr/README.md +12 -0
  42. package/docs/ai-agents.md +156 -0
  43. package/docs/app-integration.md +316 -0
  44. package/docs/benchmarking.md +275 -0
  45. package/docs/client-installation.md +141 -0
  46. package/docs/clients.md +98 -0
  47. package/docs/config.md +175 -0
  48. package/docs/demo.md +259 -0
  49. package/docs/dsl.md +57 -0
  50. package/docs/install.md +233 -0
  51. package/docs/market-positioning.md +70 -0
  52. package/docs/npm.md +359 -0
  53. package/docs/protocol-fixtures/README.md +8 -0
  54. package/docs/protocol-fixtures/core-session.requests.jsonl +8 -0
  55. package/docs/protocol-fixtures/core-session.responses.jsonl +8 -0
  56. package/docs/protocol-versioning.md +65 -0
  57. package/docs/protocol.md +560 -0
  58. package/docs/publication.md +77 -0
  59. package/docs/release-audit.md +99 -0
  60. package/docs/release-candidate.md +111 -0
  61. package/docs/release-evidence.md +188 -0
  62. package/docs/release-notes-template.md +58 -0
  63. package/docs/roadmap.md +334 -0
  64. package/docs/scenario-authoring.md +88 -0
  65. package/docs/shipping.md +170 -0
  66. package/docs/trace-privacy.md +88 -0
  67. package/docs/troubleshooting.md +256 -0
  68. package/examples/android-app-auth-probe.json +89 -0
  69. package/examples/android-app-error-state.json +13 -0
  70. package/examples/android-app-login-smoke.json +192 -0
  71. package/examples/android-app-onboarding.json +12 -0
  72. package/examples/android-app-referral-deep-link.json +12 -0
  73. package/examples/android-shim-smoke.json +19 -0
  74. package/examples/demo-failure.json +12 -0
  75. package/examples/demo-fake.json +14 -0
  76. package/examples/ios-dev-client-open-link.json +26 -0
  77. package/examples/ios-dev-client-route-snapshot.json +24 -0
  78. package/examples/ios-shim-smoke.json +23 -0
  79. package/examples/ios-smoke.json +9 -0
  80. package/go.work +3 -0
  81. package/npm/agents.mjs +183 -0
  82. package/npm/app-config.mjs +95 -0
  83. package/npm/build-zmr.mjs +21 -0
  84. package/npm/commands.mjs +104 -0
  85. package/npm/generated-files.mjs +50 -0
  86. package/npm/index.mjs +75 -0
  87. package/npm/init-app.mjs +80 -0
  88. package/npm/package-scripts.mjs +72 -0
  89. package/npm/postinstall.mjs +21 -0
  90. package/npm/scaffold.mjs +179 -0
  91. package/npm/scenarios.mjs +93 -0
  92. package/npm/setup.mjs +69 -0
  93. package/npm/wizard.mjs +117 -0
  94. package/npm/zmr.mjs +23 -0
  95. package/package.json +114 -0
  96. package/prebuilds/darwin-arm64/zmr +0 -0
  97. package/prebuilds/darwin-x64/zmr +0 -0
  98. package/prebuilds/linux-arm64/zmr +0 -0
  99. package/prebuilds/linux-x64/zmr +0 -0
  100. package/schemas/README.md +26 -0
  101. package/schemas/action-result.schema.json +27 -0
  102. package/schemas/capabilities-output.schema.json +98 -0
  103. package/schemas/devices-output.schema.json +25 -0
  104. package/schemas/doctor-output.schema.json +51 -0
  105. package/schemas/explain-output.schema.json +51 -0
  106. package/schemas/import-output.schema.json +23 -0
  107. package/schemas/init-output.schema.json +71 -0
  108. package/schemas/json-rpc.schema.json +55 -0
  109. package/schemas/release-manifest.schema.json +43 -0
  110. package/schemas/release-readiness-output.schema.json +127 -0
  111. package/schemas/run-output.schema.json +43 -0
  112. package/schemas/scenario.schema.json +128 -0
  113. package/schemas/schemas-output.schema.json +26 -0
  114. package/schemas/semantic-snapshot.schema.json +116 -0
  115. package/schemas/snapshot.schema.json +60 -0
  116. package/schemas/trace-event.schema.json +14 -0
  117. package/schemas/trace-manifest.schema.json +59 -0
  118. package/schemas/validate-output.schema.json +42 -0
  119. package/schemas/version-output.schema.json +23 -0
  120. package/schemas/zmr-config.schema.json +75 -0
  121. package/scripts/android-emulator.sh +126 -0
  122. package/scripts/assert-ios-physical-ready.sh +213 -0
  123. package/scripts/benchmark-command.sh +307 -0
  124. package/scripts/benchmark.sh +359 -0
  125. package/scripts/benchmark_gate.py +117 -0
  126. package/scripts/benchmark_result_row.py +88 -0
  127. package/scripts/compare-benchmarks.py +288 -0
  128. package/scripts/create-android-demo-app.sh +342 -0
  129. package/scripts/create-ios-demo-app.sh +261 -0
  130. package/scripts/demo-android-real.sh +232 -0
  131. package/scripts/demo-ios-real.sh +270 -0
  132. package/scripts/demo.sh +464 -0
  133. package/scripts/device-matrix.sh +338 -0
  134. package/scripts/ensure-ios-shim-target.rb +237 -0
  135. package/scripts/install-android-shim.sh +281 -0
  136. package/scripts/install-ios-shim.sh +589 -0
  137. package/scripts/pilot-gate.sh +560 -0
  138. package/scripts/release-readiness.py +838 -0
  139. package/scripts/release-readiness.sh +91 -0
  140. package/scripts/run-android-pilot.sh +561 -0
  141. package/scripts/run-ios-pilot.sh +509 -0
  142. package/shims/android/README.md +21 -0
  143. package/shims/android/ZMRShimInstrumentedTest.java +152 -0
  144. package/shims/android/protocol.md +18 -0
  145. package/shims/ios/README.md +50 -0
  146. package/shims/ios/ZMRShim.swift +110 -0
  147. package/shims/ios/ZMRShimUITestCase.swift +475 -0
  148. package/shims/ios/protocol.md +74 -0
  149. package/skills/zmr-mobile-testing/SKILL.md +127 -0
  150. package/src/android.zig +344 -0
  151. package/src/android_device_info.zig +99 -0
  152. package/src/android_emulator.zig +154 -0
  153. package/src/android_screen_recording.zig +112 -0
  154. package/src/android_shell.zig +112 -0
  155. package/src/bundle.zig +124 -0
  156. package/src/bundle_redaction.zig +272 -0
  157. package/src/bundle_tar.zig +123 -0
  158. package/src/cli_devices.zig +97 -0
  159. package/src/cli_doctor.zig +114 -0
  160. package/src/cli_import.zig +70 -0
  161. package/src/cli_info.zig +39 -0
  162. package/src/cli_init.zig +72 -0
  163. package/src/cli_output.zig +467 -0
  164. package/src/cli_run.zig +259 -0
  165. package/src/cli_serve.zig +287 -0
  166. package/src/cli_trace.zig +111 -0
  167. package/src/cli_validate.zig +41 -0
  168. package/src/command.zig +211 -0
  169. package/src/config.zig +305 -0
  170. package/src/config_diagnostics.zig +212 -0
  171. package/src/config_paths.zig +49 -0
  172. package/src/device_registry.zig +37 -0
  173. package/src/doctor.zig +412 -0
  174. package/src/doctor_hints.zig +52 -0
  175. package/src/errors.zig +55 -0
  176. package/src/fake_device.zig +163 -0
  177. package/src/health.zig +28 -0
  178. package/src/importer.zig +343 -0
  179. package/src/importer_json.zig +100 -0
  180. package/src/importer_model.zig +103 -0
  181. package/src/ios.zig +399 -0
  182. package/src/ios_devices.zig +219 -0
  183. package/src/ios_lifecycle.zig +72 -0
  184. package/src/ios_shim.zig +242 -0
  185. package/src/ios_snapshot.zig +20 -0
  186. package/src/json_fields.zig +80 -0
  187. package/src/json_rpc.zig +150 -0
  188. package/src/json_rpc_methods.zig +318 -0
  189. package/src/json_rpc_observation.zig +31 -0
  190. package/src/json_rpc_params.zig +52 -0
  191. package/src/json_rpc_protocol.zig +110 -0
  192. package/src/json_rpc_trace.zig +73 -0
  193. package/src/main.zig +135 -0
  194. package/src/mcp.zig +234 -0
  195. package/src/mcp_protocol.zig +64 -0
  196. package/src/mcp_trace.zig +83 -0
  197. package/src/report.zig +346 -0
  198. package/src/report_html.zig +63 -0
  199. package/src/report_values.zig +27 -0
  200. package/src/run_options.zig +152 -0
  201. package/src/runner.zig +280 -0
  202. package/src/runner_actions.zig +109 -0
  203. package/src/runner_config.zig +6 -0
  204. package/src/runner_diagnostics.zig +268 -0
  205. package/src/runner_events.zig +170 -0
  206. package/src/runner_native.zig +88 -0
  207. package/src/runner_waits.zig +300 -0
  208. package/src/scaffold.zig +472 -0
  209. package/src/scenario.zig +346 -0
  210. package/src/scenario_fields.zig +50 -0
  211. package/src/schema_registry.zig +53 -0
  212. package/src/selector.zig +84 -0
  213. package/src/semantic.zig +171 -0
  214. package/src/trace.zig +315 -0
  215. package/src/trace_json.zig +340 -0
  216. package/src/trace_summary.zig +218 -0
  217. package/src/trace_summary_diagnostic.zig +202 -0
  218. package/src/types.zig +120 -0
  219. package/src/uiautomator.zig +164 -0
  220. package/src/validation.zig +187 -0
  221. package/src/version.zig +22 -0
  222. package/viewer/app.js +373 -0
  223. package/viewer/index.html +126 -0
  224. package/viewer/parser.js +233 -0
  225. package/viewer/styles.css +585 -0
@@ -0,0 +1,585 @@
1
+ :root {
2
+ color-scheme: light;
3
+ --bg: #f5f7f6;
4
+ --surface: #ffffff;
5
+ --surface-2: #eef3f0;
6
+ --line: #d8e0dc;
7
+ --text: #18211e;
8
+ --muted: #66736d;
9
+ --accent: #155eef;
10
+ --accent-soft: #e8efff;
11
+ --ok: #147a3e;
12
+ --failed: #b42318;
13
+ --warn: #b54708;
14
+ --shadow: 0 12px 30px rgba(24, 33, 30, 0.08);
15
+ }
16
+
17
+ * {
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ html,
22
+ body {
23
+ min-height: 100%;
24
+ }
25
+
26
+ body {
27
+ margin: 0;
28
+ background: var(--bg);
29
+ color: var(--text);
30
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
31
+ letter-spacing: 0;
32
+ }
33
+
34
+ button,
35
+ input {
36
+ font: inherit;
37
+ }
38
+
39
+ .app-header {
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: space-between;
43
+ gap: 24px;
44
+ padding: 20px 28px;
45
+ border-bottom: 1px solid var(--line);
46
+ background: rgba(255, 255, 255, 0.92);
47
+ position: sticky;
48
+ top: 0;
49
+ z-index: 10;
50
+ }
51
+
52
+ .app-header h1 {
53
+ margin: 0;
54
+ font-size: 20px;
55
+ line-height: 1.2;
56
+ font-weight: 750;
57
+ }
58
+
59
+ .app-header p {
60
+ margin: 4px 0 0;
61
+ color: var(--muted);
62
+ font-size: 13px;
63
+ }
64
+
65
+ .app-header p.failed {
66
+ color: var(--failed);
67
+ }
68
+
69
+ .file-button {
70
+ display: inline-flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ min-height: 36px;
74
+ padding: 0 14px;
75
+ border: 1px solid #114bc2;
76
+ border-radius: 6px;
77
+ background: var(--accent);
78
+ color: #fff;
79
+ font-size: 14px;
80
+ font-weight: 650;
81
+ cursor: pointer;
82
+ }
83
+
84
+ .file-button input {
85
+ position: absolute;
86
+ inline-size: 1px;
87
+ block-size: 1px;
88
+ opacity: 0;
89
+ pointer-events: none;
90
+ }
91
+
92
+ .app-shell {
93
+ max-width: 1680px;
94
+ margin: 0 auto;
95
+ padding: 20px 28px 32px;
96
+ }
97
+
98
+ .summary-band {
99
+ display: grid;
100
+ grid-template-columns: minmax(220px, 2fr) repeat(4, minmax(110px, 1fr));
101
+ gap: 1px;
102
+ overflow: hidden;
103
+ border: 1px solid var(--line);
104
+ border-radius: 8px;
105
+ background: var(--line);
106
+ }
107
+
108
+ .summary-band > div {
109
+ min-width: 0;
110
+ padding: 14px 16px;
111
+ background: var(--surface);
112
+ }
113
+
114
+ .label {
115
+ display: block;
116
+ margin-bottom: 5px;
117
+ color: var(--muted);
118
+ font-size: 12px;
119
+ line-height: 1.2;
120
+ font-weight: 700;
121
+ text-transform: uppercase;
122
+ }
123
+
124
+ .summary-band strong {
125
+ display: block;
126
+ min-width: 0;
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ white-space: nowrap;
130
+ font-size: 16px;
131
+ line-height: 1.3;
132
+ }
133
+
134
+ .status {
135
+ text-transform: capitalize;
136
+ }
137
+
138
+ .status.passed {
139
+ color: var(--ok);
140
+ }
141
+
142
+ .status.failed {
143
+ color: var(--failed);
144
+ }
145
+
146
+ .status.running,
147
+ .status.neutral {
148
+ color: var(--warn);
149
+ }
150
+
151
+ .empty-state {
152
+ display: grid;
153
+ min-height: calc(100vh - 190px);
154
+ place-items: center;
155
+ }
156
+
157
+ .drop-target {
158
+ width: min(520px, 100%);
159
+ padding: 44px;
160
+ border: 1px dashed #94a39b;
161
+ border-radius: 8px;
162
+ background: var(--surface);
163
+ box-shadow: var(--shadow);
164
+ text-align: center;
165
+ }
166
+
167
+ .drop-target.dragging {
168
+ border-color: var(--accent);
169
+ background: var(--accent-soft);
170
+ }
171
+
172
+ .drop-icon {
173
+ display: inline-grid;
174
+ place-items: center;
175
+ width: 54px;
176
+ height: 54px;
177
+ margin-bottom: 18px;
178
+ border-radius: 8px;
179
+ background: #17202a;
180
+ color: #fff;
181
+ font-size: 13px;
182
+ font-weight: 800;
183
+ }
184
+
185
+ .drop-target h2 {
186
+ margin: 0;
187
+ font-size: 24px;
188
+ line-height: 1.2;
189
+ }
190
+
191
+ .drop-target p {
192
+ margin: 10px auto 0;
193
+ max-width: 360px;
194
+ color: var(--muted);
195
+ font-size: 14px;
196
+ line-height: 1.5;
197
+ }
198
+
199
+ .viewer-grid {
200
+ display: grid;
201
+ grid-template-columns: minmax(300px, 0.8fr) minmax(520px, 1.5fr) minmax(260px, 0.7fr);
202
+ gap: 16px;
203
+ margin-top: 18px;
204
+ align-items: start;
205
+ }
206
+
207
+ .timeline-panel,
208
+ .detail-panel,
209
+ .artifact-panel {
210
+ min-width: 0;
211
+ border: 1px solid var(--line);
212
+ border-radius: 8px;
213
+ background: var(--surface);
214
+ box-shadow: var(--shadow);
215
+ }
216
+
217
+ .panel-heading {
218
+ display: flex;
219
+ align-items: center;
220
+ justify-content: space-between;
221
+ gap: 12px;
222
+ padding: 14px 14px 12px;
223
+ border-bottom: 1px solid var(--line);
224
+ }
225
+
226
+ .panel-heading h2 {
227
+ margin: 0;
228
+ font-size: 15px;
229
+ line-height: 1.25;
230
+ }
231
+
232
+ .panel-heading p {
233
+ margin: 3px 0 0;
234
+ color: var(--muted);
235
+ font-size: 12px;
236
+ }
237
+
238
+ #eventFilter {
239
+ width: min(180px, 48%);
240
+ min-height: 32px;
241
+ padding: 0 10px;
242
+ border: 1px solid var(--line);
243
+ border-radius: 6px;
244
+ color: var(--text);
245
+ font-size: 13px;
246
+ }
247
+
248
+ .replay-panel {
249
+ display: grid;
250
+ gap: 10px;
251
+ padding: 12px 14px;
252
+ border-bottom: 1px solid var(--line);
253
+ background: #fbfcfc;
254
+ }
255
+
256
+ .replay-controls {
257
+ display: grid;
258
+ grid-template-columns: 34px 34px 34px minmax(70px, 1fr);
259
+ gap: 8px;
260
+ align-items: center;
261
+ }
262
+
263
+ .replay-controls button {
264
+ display: inline-grid;
265
+ place-items: center;
266
+ width: 34px;
267
+ height: 34px;
268
+ border: 1px solid var(--line);
269
+ border-radius: 6px;
270
+ background: var(--surface);
271
+ color: var(--text);
272
+ cursor: pointer;
273
+ font-size: 15px;
274
+ line-height: 1;
275
+ }
276
+
277
+ .replay-controls button:disabled {
278
+ color: #9aa8a2;
279
+ cursor: default;
280
+ }
281
+
282
+ #replayPosition {
283
+ justify-self: end;
284
+ color: var(--muted);
285
+ font-size: 12px;
286
+ font-weight: 700;
287
+ }
288
+
289
+ #replaySlider {
290
+ width: 100%;
291
+ min-height: 24px;
292
+ accent-color: var(--accent);
293
+ }
294
+
295
+ .replay-meta {
296
+ display: flex;
297
+ justify-content: space-between;
298
+ gap: 10px;
299
+ color: var(--muted);
300
+ font-size: 12px;
301
+ }
302
+
303
+ #replayFrameKind {
304
+ min-width: 0;
305
+ overflow: hidden;
306
+ text-overflow: ellipsis;
307
+ white-space: nowrap;
308
+ font-weight: 700;
309
+ }
310
+
311
+ .event-list,
312
+ .artifact-list {
313
+ list-style: none;
314
+ margin: 0;
315
+ padding: 0;
316
+ }
317
+
318
+ .event-list {
319
+ max-height: calc(100vh - 250px);
320
+ overflow: auto;
321
+ }
322
+
323
+ .event-row {
324
+ display: grid;
325
+ grid-template-columns: 46px minmax(120px, 0.9fr) minmax(120px, 1fr);
326
+ gap: 10px;
327
+ width: 100%;
328
+ min-height: 42px;
329
+ padding: 8px 12px;
330
+ border: 0;
331
+ border-bottom: 1px solid var(--line);
332
+ background: transparent;
333
+ color: var(--text);
334
+ text-align: left;
335
+ cursor: pointer;
336
+ }
337
+
338
+ .event-row:hover,
339
+ .event-row.selected {
340
+ background: var(--accent-soft);
341
+ }
342
+
343
+ .event-seq,
344
+ .event-summary {
345
+ color: var(--muted);
346
+ font-size: 12px;
347
+ }
348
+
349
+ .event-kind {
350
+ overflow: hidden;
351
+ text-overflow: ellipsis;
352
+ white-space: nowrap;
353
+ font-size: 13px;
354
+ font-weight: 700;
355
+ }
356
+
357
+ .detail-panel {
358
+ padding-bottom: 14px;
359
+ }
360
+
361
+ .detail-grid {
362
+ display: grid;
363
+ grid-template-columns: minmax(260px, 0.9fr) minmax(320px, 1.1fr);
364
+ gap: 14px;
365
+ padding: 14px;
366
+ }
367
+
368
+ .artifact-preview,
369
+ .tree-preview,
370
+ .snapshot-preview,
371
+ .payload-block {
372
+ min-width: 0;
373
+ border: 1px solid var(--line);
374
+ border-radius: 8px;
375
+ background: #fbfcfc;
376
+ }
377
+
378
+ .preview-header {
379
+ display: flex;
380
+ justify-content: space-between;
381
+ gap: 12px;
382
+ padding: 10px 12px;
383
+ border-bottom: 1px solid var(--line);
384
+ color: var(--muted);
385
+ font-size: 12px;
386
+ font-weight: 700;
387
+ }
388
+
389
+ .preview-header a {
390
+ color: var(--accent);
391
+ text-decoration: none;
392
+ }
393
+
394
+ .screenshot-mount {
395
+ display: grid;
396
+ min-height: 360px;
397
+ place-items: center;
398
+ overflow: hidden;
399
+ color: var(--muted);
400
+ font-size: 13px;
401
+ background: var(--surface-2);
402
+ }
403
+
404
+ .screenshot-mount img {
405
+ display: block;
406
+ max-width: 100%;
407
+ max-height: 72vh;
408
+ object-fit: contain;
409
+ }
410
+
411
+ pre {
412
+ margin: 0;
413
+ overflow: auto;
414
+ color: #15201b;
415
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
416
+ font-size: 12px;
417
+ line-height: 1.45;
418
+ white-space: pre-wrap;
419
+ word-break: break-word;
420
+ }
421
+
422
+ #snapshotJson {
423
+ max-height: 260px;
424
+ padding: 12px;
425
+ }
426
+
427
+ .tree-preview {
428
+ display: grid;
429
+ grid-template-rows: auto minmax(180px, 1fr) minmax(120px, 0.7fr);
430
+ min-height: 360px;
431
+ }
432
+
433
+ .node-list {
434
+ min-height: 0;
435
+ max-height: 300px;
436
+ margin: 0;
437
+ padding: 0;
438
+ overflow: auto;
439
+ list-style: none;
440
+ }
441
+
442
+ .node-list li {
443
+ border-bottom: 1px solid var(--line);
444
+ }
445
+
446
+ .node-list li > span {
447
+ display: block;
448
+ padding: 12px;
449
+ color: var(--muted);
450
+ font-size: 13px;
451
+ }
452
+
453
+ .node-row {
454
+ display: grid;
455
+ width: 100%;
456
+ gap: 3px;
457
+ min-height: 46px;
458
+ padding: 8px 10px;
459
+ border: 0;
460
+ background: transparent;
461
+ color: var(--text);
462
+ text-align: left;
463
+ cursor: pointer;
464
+ }
465
+
466
+ .node-row:hover,
467
+ .node-row.selected {
468
+ background: var(--accent-soft);
469
+ }
470
+
471
+ .node-label,
472
+ .node-meta {
473
+ min-width: 0;
474
+ overflow: hidden;
475
+ text-overflow: ellipsis;
476
+ white-space: nowrap;
477
+ }
478
+
479
+ .node-label {
480
+ font-size: 13px;
481
+ font-weight: 700;
482
+ }
483
+
484
+ .node-meta {
485
+ color: var(--muted);
486
+ font-size: 12px;
487
+ }
488
+
489
+ #selectedNodeJson {
490
+ max-height: 180px;
491
+ padding: 10px;
492
+ border-top: 1px solid var(--line);
493
+ }
494
+
495
+ .payload-block {
496
+ margin: 0 14px;
497
+ }
498
+
499
+ .payload-block h3 {
500
+ margin: 0;
501
+ padding: 10px 12px;
502
+ border-bottom: 1px solid var(--line);
503
+ color: var(--muted);
504
+ font-size: 12px;
505
+ line-height: 1.2;
506
+ text-transform: uppercase;
507
+ }
508
+
509
+ #payloadJson {
510
+ max-height: 260px;
511
+ padding: 12px;
512
+ }
513
+
514
+ .artifact-list {
515
+ max-height: calc(100vh - 250px);
516
+ overflow: auto;
517
+ }
518
+
519
+ .artifact-list li {
520
+ border-bottom: 1px solid var(--line);
521
+ }
522
+
523
+ .artifact-list a {
524
+ display: block;
525
+ padding: 10px 12px;
526
+ color: var(--accent);
527
+ font-size: 12px;
528
+ line-height: 1.35;
529
+ text-decoration: none;
530
+ word-break: break-word;
531
+ }
532
+
533
+ .artifact-list a:hover {
534
+ background: var(--accent-soft);
535
+ }
536
+
537
+ .hidden {
538
+ display: none !important;
539
+ }
540
+
541
+ @media (max-width: 1180px) {
542
+ .viewer-grid {
543
+ grid-template-columns: 340px minmax(0, 1fr);
544
+ }
545
+
546
+ .artifact-panel {
547
+ grid-column: 1 / -1;
548
+ }
549
+ }
550
+
551
+ @media (max-width: 760px) {
552
+ .app-header {
553
+ position: static;
554
+ align-items: flex-start;
555
+ flex-direction: column;
556
+ padding: 18px;
557
+ }
558
+
559
+ .app-shell {
560
+ padding: 14px;
561
+ }
562
+
563
+ .summary-band,
564
+ .viewer-grid,
565
+ .detail-grid {
566
+ grid-template-columns: 1fr;
567
+ }
568
+
569
+ .event-list,
570
+ .artifact-list {
571
+ max-height: none;
572
+ }
573
+
574
+ .event-row {
575
+ grid-template-columns: 40px minmax(0, 1fr);
576
+ }
577
+
578
+ .event-summary {
579
+ grid-column: 2;
580
+ }
581
+
582
+ #eventFilter {
583
+ width: 100%;
584
+ }
585
+ }