@zktx.io/sui-mcp 0.5.0 → 0.6.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 (87) hide show
  1. package/README.md +6 -6
  2. package/dist/adapters/deepbook/deepbookTransactionMaterialProducer.js +3 -3
  3. package/dist/core/activity/localDataService.js +71 -52
  4. package/dist/core/activity/localDataValidation.js +1 -3
  5. package/dist/core/activity/sqliteActivityStore.js +24 -16
  6. package/dist/core/activity/sqliteActivityStoreSchema.js +83 -12
  7. package/dist/core/preferences/sqlitePreferencesRepository.js +5 -3
  8. package/dist/core/session/cardSession.js +1 -1
  9. package/dist/core/session/cardSessionStore.js +53 -3
  10. package/dist/core/session/sessionStore.js +0 -17
  11. package/dist/core/session/settingsFileIdentity.js +11 -0
  12. package/dist/core/session/settingsFileProtocol.js +25 -0
  13. package/dist/core/session/settingsFileStore.js +346 -0
  14. package/dist/core/session/settingsInputError.js +34 -0
  15. package/dist/core/session/settingsOperation.js +224 -0
  16. package/dist/core/session/settingsPreparationSql.js +15 -0
  17. package/dist/core/session/settingsWorkflow.js +1219 -0
  18. package/dist/core/session/sqliteSessionStore.js +0 -40
  19. package/dist/core/session/sqliteSettingsWorkflowStore.js +463 -0
  20. package/dist/core/session/sqliteWalletWorkflowStore.js +164 -41
  21. package/dist/core/session/status.js +2 -2
  22. package/dist/core/session/walletConnection.js +27 -8
  23. package/dist/core/session/walletWorkflow.js +73 -15
  24. package/dist/core/session/workflowState.js +16 -8
  25. package/dist/core/session/workflowView.js +18 -2
  26. package/dist/mcp/responseGuidance.js +10 -5
  27. package/dist/mcp/serverInfo.js +3 -4
  28. package/dist/mcp/toolNames.js +2 -2
  29. package/dist/mcp/tools/account/index.js +1 -19
  30. package/dist/mcp/tools/read/readToolHelpers.js +5 -4
  31. package/dist/mcp/tools/session/executionResultTools.js +2 -2
  32. package/dist/mcp/tools/session/shared.js +1 -0
  33. package/dist/mcp/tools/session/statusTools.js +4 -3
  34. package/dist/mcp/tools/settings/index.js +8 -28
  35. package/dist/mcp-app/account.html +14 -14
  36. package/dist/mcp-app/account.notices.txt +1 -1
  37. package/dist/mcp-app/chart.html +9 -9
  38. package/dist/mcp-app/chart.notices.txt +1 -1
  39. package/dist/mcp-app/connect.html +14 -14
  40. package/dist/mcp-app/connect.notices.txt +1 -1
  41. package/dist/mcp-app/receipt.html +1298 -1463
  42. package/dist/mcp-app/receipt.notices.txt +226 -1204
  43. package/dist/mcp-app/review.html +1298 -1463
  44. package/dist/mcp-app/review.notices.txt +226 -1204
  45. package/dist/mcp-app/settings.html +3133 -0
  46. package/dist/mcp-app/settings.notices.txt +973 -0
  47. package/dist/mcp-ui/contracts.js +8 -2
  48. package/dist/mcp-ui/readCards.js +1 -1
  49. package/dist/mcp-ui/tools.js +33 -2
  50. package/dist/review-server/server.js +5 -51
  51. package/dist/runtime/application.js +41 -14
  52. package/dist/runtime/localSettingsService.js +26 -2
  53. package/dist/runtime/shared/authenticatedFetch.js +6 -2
  54. package/dist/runtime/shared/control.js +5 -6
  55. package/dist/runtime/shared/http.js +14 -0
  56. package/dist/runtime/shared/mcpHttp.js +9 -4
  57. package/dist/runtime/shared/server.js +1 -1
  58. package/dist/runtime/smokeMainnetRead.js +0 -1
  59. package/dist/runtime/walletConnectStorage.js +2 -4
  60. package/dist/runtime/walletSdkChildRuntime.js +2 -1
  61. package/dist/runtime/walletSdkIpc.js +2 -1
  62. package/dist/runtime/walletSdkProcess.js +3 -2
  63. package/docs/AGENT_BEHAVIOR.md +44 -10
  64. package/docs/AGENT_DEVELOPMENT_POLICY.md +16 -12
  65. package/docs/FRONTEND_POLICY.md +105 -28
  66. package/docs/LOCAL_DB_ARCHITECTURE.md +143 -20
  67. package/docs/MCP_SETUP.md +99 -39
  68. package/docs/MCP_TOOLS.md +273 -24
  69. package/docs/SDK_API.md +51 -10
  70. package/docs/UTILITY_INDEX.md +9 -6
  71. package/docs/WALLET_CONNECTION.md +30 -9
  72. package/package.json +13 -7
  73. package/dist/core/activity/schemaVersion.js +0 -2
  74. package/dist/core/session/keyedRecordStore.js +0 -18
  75. package/dist/core/session/settingsSession.js +0 -1
  76. package/dist/core/session/settingsSessions.js +0 -45
  77. package/dist/review-app/brand-dark.svg +0 -1
  78. package/dist/review-app/brand-light.svg +0 -1
  79. package/dist/review-app/favicon.svg +0 -1
  80. package/dist/review-app/settings.css +0 -1
  81. package/dist/review-app/settings.js +0 -1
  82. package/dist/review-app/ui.css +0 -809
  83. package/dist/review-server/assets.js +0 -48
  84. package/dist/review-server/html.js +0 -45
  85. package/dist/review-server/http.js +0 -47
  86. package/dist/review-server/middleware/reviewToken.js +0 -7
  87. package/dist/review-server/settingsApi.js +0 -158
@@ -1,809 +0,0 @@
1
- /* Shared design tokens and atomic components for every Sui MCP page.
2
- This file is the only place that declares `.ui-*` rules and the only place that
3
- styles the bare interactive elements button/input/select/textarea. Pages keep
4
- only their own layout, containers, third-party sizing, and compositions.
5
- No inline styles are used anywhere, so the strictest page CSP (style-src 'self'
6
- on the chart page) is satisfied. Colors come from the tokens below; the active
7
- theme is the `data-theme` attribute on <html>. */
8
-
9
- :root[data-theme="light"] {
10
- --ui-bg: #f6f8fa;
11
- --ui-surface: #ffffff;
12
- --ui-surface-2: #eef1f5;
13
- --ui-border: #e3e8ef;
14
- --ui-border-strong: #cdd5e0;
15
- --ui-text: #18202b;
16
- --ui-text-muted: #5b6675;
17
- --ui-accent: #1565c0;
18
- --ui-accent-hover: #0d47a1;
19
- --ui-on-accent: #ffffff;
20
- --ui-focus: rgba(21, 101, 192, 0.25);
21
- --ui-ok-bg: #e2f3e9;
22
- --ui-ok-text: #1b6b43;
23
- --ui-warn-bg: #fbeeda;
24
- --ui-warn-text: #8a5a08;
25
- --ui-danger: #b3261e;
26
- --ui-danger-bg: #fbe9e7;
27
- --ui-up: #1b7f43;
28
- --ui-down: #b3261e;
29
- }
30
-
31
- :root[data-theme="dark"] {
32
- --ui-bg: #0e141b;
33
- --ui-surface: #161d26;
34
- --ui-surface-2: #1e2733;
35
- --ui-border: #28323f;
36
- --ui-border-strong: #3a4859;
37
- --ui-text: #e7edf4;
38
- --ui-text-muted: #9aa7b6;
39
- --ui-accent: #4da2ff;
40
- --ui-accent-hover: #6fb8ff;
41
- --ui-on-accent: #06243f;
42
- --ui-focus: rgba(77, 162, 255, 0.32);
43
- --ui-ok-bg: #10362a;
44
- --ui-ok-text: #7fe0b0;
45
- --ui-warn-bg: #3a2e16;
46
- --ui-warn-text: #f0c97a;
47
- --ui-danger: #ff8a80;
48
- --ui-danger-bg: #3a1f1d;
49
- --ui-up: #46c79e;
50
- --ui-down: #ff8a80;
51
- }
52
-
53
- :root {
54
- --ui-r: 10px;
55
- --ui-font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
56
- --ui-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
57
- }
58
-
59
- *,
60
- *::before,
61
- *::after {
62
- box-sizing: border-box;
63
- }
64
-
65
- body {
66
- margin: 0;
67
- background: var(--ui-bg);
68
- color: var(--ui-text);
69
- font-family: var(--ui-font-sans);
70
- font-weight: 400;
71
- -webkit-font-smoothing: antialiased;
72
- }
73
-
74
- .ui-mono {
75
- font-family: var(--ui-font-mono);
76
- font-size: 12.5px;
77
- overflow-wrap: anywhere;
78
- }
79
-
80
- /* Shell: the outer page structure every page renders into. */
81
- .ui-shell {
82
- position: relative;
83
- min-height: 100vh;
84
- }
85
-
86
- .ui-header {
87
- display: flex;
88
- align-items: center;
89
- gap: 12px;
90
- padding: 12px 20px;
91
- background: var(--ui-surface);
92
- border-bottom: 0.5px solid var(--ui-border);
93
- }
94
-
95
- .ui-brand {
96
- display: inline-flex;
97
- align-items: center;
98
- gap: 8px;
99
- font-size: 15px;
100
- font-weight: 500;
101
- color: var(--ui-text);
102
- text-decoration: none;
103
- white-space: nowrap;
104
- }
105
-
106
- .ui-brand img {
107
- display: block;
108
- width: 24px;
109
- height: 24px;
110
- }
111
-
112
- /* The brand mark is two theme-specific files; CSS shows the one for the active
113
- theme so the swap needs no script. */
114
- :root[data-theme="light"] .ui-brand-dark {
115
- display: none;
116
- }
117
- :root[data-theme="dark"] .ui-brand-light {
118
- display: none;
119
- }
120
-
121
- .ui-header-spacer {
122
- margin-left: auto;
123
- }
124
-
125
- .ui-main {
126
- max-width: 920px;
127
- margin: 0 auto;
128
- padding: 22px 20px 48px;
129
- }
130
-
131
- /* Buttons. Every state has hover, active, and focus feedback; the only inert
132
- state is the deliberate async lock. */
133
- .ui-btn {
134
- min-height: 38px;
135
- border: 0.5px solid var(--ui-border-strong);
136
- border-radius: var(--ui-r);
137
- background: var(--ui-surface);
138
- color: var(--ui-text);
139
- font: inherit;
140
- font-size: 14px;
141
- font-weight: 500;
142
- padding: 0 16px;
143
- cursor: pointer;
144
- display: inline-flex;
145
- align-items: center;
146
- justify-content: center;
147
- gap: 7px;
148
- transition: background 0.12s, border-color 0.12s, transform 0.06s;
149
- }
150
-
151
- .ui-btn:hover {
152
- background: var(--ui-surface-2);
153
- border-color: var(--ui-accent);
154
- }
155
-
156
- .ui-btn:active {
157
- transform: scale(0.975);
158
- }
159
-
160
- .ui-btn:focus-visible {
161
- outline: none;
162
- box-shadow: 0 0 0 3px var(--ui-focus);
163
- }
164
-
165
- .ui-btn--primary {
166
- background: var(--ui-accent);
167
- border-color: var(--ui-accent);
168
- color: var(--ui-on-accent);
169
- }
170
-
171
- .ui-btn--primary:hover {
172
- background: var(--ui-accent-hover);
173
- border-color: var(--ui-accent-hover);
174
- }
175
-
176
- .ui-btn--danger {
177
- border-color: var(--ui-danger);
178
- color: var(--ui-danger);
179
- }
180
-
181
- .ui-btn--danger:hover {
182
- background: var(--ui-danger-bg);
183
- }
184
-
185
- .ui-btn:disabled {
186
- cursor: not-allowed;
187
- color: var(--ui-text-muted);
188
- background: var(--ui-surface-2);
189
- border-color: var(--ui-border);
190
- }
191
-
192
- /* A group of buttons that share one width. Each button takes an equal share of the
193
- row (flex-basis 0) so a short and a long label render at the same width; the
194
- min-width makes the group wrap to full-width stacked rows when it gets too narrow
195
- (mobile), instead of squeezing labels. */
196
- .ui-btn-row {
197
- display: flex;
198
- flex-wrap: wrap;
199
- gap: 10px;
200
- margin-top: 12px;
201
- }
202
-
203
- .ui-btn-row > .ui-btn {
204
- flex: 1 1 0;
205
- min-width: 12rem;
206
- }
207
-
208
- /* A card action row holding a single standalone button: right-aligned and content-sized,
209
- not stretched to fill the row like a multi-button group. */
210
- .ui-btn-row--end {
211
- justify-content: flex-end;
212
- }
213
-
214
- .ui-btn-row--end > .ui-btn {
215
- flex: 0 0 auto;
216
- min-width: 0;
217
- }
218
-
219
- .ui-icon-btn {
220
- width: 34px;
221
- height: 34px;
222
- flex: none;
223
- padding: 0;
224
- border-radius: 9px;
225
- border: 0.5px solid var(--ui-border-strong);
226
- background: var(--ui-surface);
227
- color: var(--ui-text);
228
- cursor: pointer;
229
- display: inline-flex;
230
- align-items: center;
231
- justify-content: center;
232
- transition: background 0.12s, border-color 0.12s, transform 0.06s;
233
- }
234
-
235
- .ui-icon-btn:hover {
236
- background: var(--ui-surface-2);
237
- border-color: var(--ui-accent);
238
- }
239
-
240
- .ui-icon-btn:active {
241
- transform: scale(0.94);
242
- }
243
-
244
- .ui-icon-btn:focus-visible {
245
- outline: none;
246
- box-shadow: 0 0 0 3px var(--ui-focus);
247
- }
248
-
249
- .ui-icon-btn svg {
250
- width: 18px;
251
- height: 18px;
252
- }
253
-
254
- /* Links. */
255
- .ui-link {
256
- color: var(--ui-accent);
257
- text-decoration: none;
258
- cursor: pointer;
259
- }
260
-
261
- .ui-link:hover {
262
- color: var(--ui-accent-hover);
263
- text-decoration: underline;
264
- }
265
-
266
- /* Form controls: one family on the shared tokens. */
267
- .ui-field {
268
- display: flex;
269
- flex-direction: column;
270
- gap: 5px;
271
- font-size: 12px;
272
- color: var(--ui-text-muted);
273
- }
274
-
275
- .ui-input,
276
- input.ui-input {
277
- height: 38px;
278
- border: 0.5px solid var(--ui-border-strong);
279
- border-radius: var(--ui-r);
280
- background: var(--ui-surface);
281
- color: var(--ui-text);
282
- font: inherit;
283
- font-size: 14px;
284
- padding: 0 12px;
285
- outline: none;
286
- transition: border-color 0.12s, box-shadow 0.12s;
287
- }
288
-
289
- .ui-input {
290
- width: 100%;
291
- }
292
-
293
- .ui-input::placeholder {
294
- color: var(--ui-text-muted);
295
- }
296
-
297
- .ui-select {
298
- height: 38px;
299
- width: 100%;
300
- border: 0.5px solid var(--ui-border-strong);
301
- border-radius: var(--ui-r);
302
- background: var(--ui-surface);
303
- color: var(--ui-text);
304
- font: inherit;
305
- font-size: 14px;
306
- padding: 0 12px;
307
- outline: none;
308
- cursor: pointer;
309
- transition: border-color 0.12s, box-shadow 0.12s;
310
- }
311
-
312
- .ui-select:focus {
313
- border-color: var(--ui-accent);
314
- box-shadow: 0 0 0 3px var(--ui-focus);
315
- }
316
-
317
- .ui-input:focus {
318
- border-color: var(--ui-accent);
319
- box-shadow: 0 0 0 3px var(--ui-focus);
320
- }
321
-
322
- /* Cards and key/value rows. */
323
- .ui-card {
324
- background: var(--ui-surface);
325
- border: 0.5px solid var(--ui-border);
326
- border-radius: 12px;
327
- padding: var(--ui-card-padding-block, 16px) var(--ui-card-padding-inline, 18px);
328
- margin: 0 0 14px;
329
- }
330
-
331
- .ui-section { min-width: 0; margin-block: 0 16px; }
332
- .ui-section-title { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 14px; font-weight: 500; margin: 0 0 10px; }
333
-
334
- .ui-card-title {
335
- font-size: 14px;
336
- font-weight: 500;
337
- margin: 0 0 10px;
338
- }
339
-
340
- /* Card header bar: a slightly raised title strip (surface-2) so the title reads as
341
- distinct from the card body (surface). Spans the card's padding via negative
342
- margins. Used by the cards built with the card() helper; the homepage keeps the
343
- plain .ui-card-title for its icon tiles. */
344
- .ui-card-head {
345
- display: flex;
346
- align-items: center;
347
- justify-content: space-between;
348
- gap: 10px;
349
- margin: calc(-1 * var(--ui-card-padding-block, 16px)) calc(-1 * var(--ui-card-padding-inline, 18px)) 14px;
350
- padding: 9px var(--ui-card-padding-inline, 18px);
351
- background: var(--ui-surface-2);
352
- border-bottom: 0.5px solid var(--ui-border);
353
- border-radius: 12px 12px 0 0;
354
- font-size: 14px;
355
- font-weight: 500;
356
- }
357
-
358
- /* The header bar already separates itself; drop the first content item's own top
359
- border so the two lines do not double up. */
360
- .ui-card-head + .ui-detail-item,
361
- .ui-card-head + .ui-row {
362
- border-top: 0;
363
- }
364
-
365
- .ui-row {
366
- display: grid;
367
- grid-template-columns: minmax(140px, 0.34fr) minmax(0, 1fr);
368
- gap: 12px;
369
- padding: 9px 0;
370
- border-top: 0.5px solid var(--ui-border);
371
- font-size: 14px;
372
- }
373
-
374
- .ui-row:first-child {
375
- border-top: 0;
376
- }
377
-
378
- .ui-row-label {
379
- color: var(--ui-text-muted);
380
- }
381
-
382
- .ui-row-value {
383
- color: var(--ui-text);
384
- overflow-wrap: anywhere;
385
- font-variant-numeric: tabular-nums;
386
- text-align: right;
387
- }
388
-
389
- /* Signer-readiness dot (the review header): ready = matches the bound account,
390
- settling = reconnecting, idle = no browser signer. Colour is a cue, not the only
391
- signal — the signing section states readiness in text. */
392
-
393
- /* Result banner: a prominent outcome with an icon and color (not color alone). */
394
- .ui-status-banner {
395
- display: flex;
396
- align-items: center;
397
- gap: 9px;
398
- padding: 11px 0;
399
- border-radius: var(--ui-r);
400
- border: 0.5px solid var(--ui-border-strong);
401
- background: var(--ui-surface-2);
402
- color: var(--ui-text);
403
- font-size: 14px;
404
- font-weight: 500;
405
- }
406
-
407
- .ui-status-icon {
408
- display: inline-flex;
409
- flex: none;
410
- }
411
-
412
- .ui-status-icon svg {
413
- width: 18px;
414
- height: 18px;
415
- }
416
-
417
- .ui-status-banner--success {
418
- background: var(--ui-ok-bg);
419
- color: var(--ui-ok-text);
420
- border-color: transparent;
421
- }
422
-
423
- .ui-status-banner--failure {
424
- background: var(--ui-danger-bg);
425
- color: var(--ui-danger);
426
- border-color: transparent;
427
- }
428
-
429
- .ui-status-banner--pending {
430
- color: var(--ui-text-muted);
431
- }
432
-
433
- /* Transaction-fact block: headline + optional trailing value + muted meta lines. */
434
- .ui-detail-item {
435
- padding: 9px 0;
436
- border-top: 0.5px solid var(--ui-border);
437
- }
438
-
439
- .ui-detail-head {
440
- display: flex;
441
- justify-content: space-between;
442
- align-items: baseline;
443
- gap: 12px;
444
- flex-wrap: wrap;
445
- }
446
-
447
- .ui-detail-title {
448
- font-weight: 500;
449
- color: var(--ui-text);
450
- overflow-wrap: anywhere;
451
- }
452
-
453
- .ui-detail-trailing {
454
- color: var(--ui-text);
455
- overflow-wrap: anywhere;
456
- }
457
-
458
- /* Signed amount tint: a gain (up) or loss (down), so a balance change reads at a
459
- glance, not by sign alone. */
460
- .ui-detail-trailing--up {
461
- color: var(--ui-up);
462
- }
463
-
464
- .ui-detail-trailing--down {
465
- color: var(--ui-down);
466
- }
467
-
468
- .ui-detail-meta {
469
- display: flex;
470
- gap: 8px;
471
- margin-top: 3px;
472
- font-size: 12.5px;
473
- color: var(--ui-text-muted);
474
- overflow-wrap: anywhere;
475
- }
476
-
477
- .ui-detail-metalabel {
478
- flex: none;
479
- color: var(--ui-text-muted);
480
- }
481
-
482
- /* Feedback block: tied to an action, persistent, diagnosable. */
483
- .ui-feedback {
484
- border: 0.5px solid var(--ui-border);
485
- border-left-width: 3px;
486
- border-radius: 8px;
487
- padding: 11px 13px;
488
- margin: 0 0 14px;
489
- font-size: 13.5px;
490
- background: var(--ui-surface);
491
- color: var(--ui-text);
492
- }
493
-
494
- .ui-feedback--ok {
495
- border-left-color: var(--ui-ok-text);
496
- }
497
-
498
- .ui-feedback--error {
499
- border-left-color: var(--ui-danger);
500
- }
501
-
502
- /* Inline feedback inside a card (a settings section's result line) follows the section's
503
- controls, so it needs a top gap from them instead of sitting flush against the buttons;
504
- when it is the section's last child the card's own padding gives its bottom space. The
505
- page-level feedback (not inside a card) keeps the default spacing above. */
506
- .ui-card > .ui-feedback {
507
- margin: 14px 0;
508
- }
509
-
510
- .ui-card > .ui-feedback:last-child {
511
- margin-bottom: 0;
512
- }
513
-
514
- .ui-feedback-detail {
515
- display: block;
516
- margin-top: 4px;
517
- font-size: 12.5px;
518
- color: var(--ui-text-muted);
519
- overflow-wrap: anywhere;
520
- }
521
-
522
- /* Placeholder card: shown in a slot whose content is empty, unsupported, or
523
- unavailable, stating why. Keeps the slot's position; the layout never collapses. */
524
- .ui-placeholder {
525
- border: 0.5px dashed var(--ui-border-strong);
526
- border-radius: 12px;
527
- padding: 18px;
528
- margin: 0 0 14px;
529
- font-size: 13.5px;
530
- color: var(--ui-text-muted);
531
- text-align: center;
532
- }
533
-
534
- /* Full-page loading overlay: set aria-busy="true" on the shell to lock the page
535
- and show the overlay; clear it when the async action finishes. */
536
- .ui-overlay {
537
- position: fixed;
538
- inset: 0;
539
- display: none;
540
- align-items: center;
541
- justify-content: center;
542
- background: color-mix(in srgb, var(--ui-bg) 70%, transparent);
543
- z-index: 50;
544
- }
545
-
546
- .ui-shell[aria-busy="true"] .ui-overlay {
547
- display: flex;
548
- }
549
-
550
- .ui-shell[aria-busy="true"] .ui-header,
551
- .ui-shell[aria-busy="true"] .ui-main {
552
- filter: opacity(0.55);
553
- pointer-events: none;
554
- }
555
-
556
- .ui-overlay-box {
557
- display: flex;
558
- flex-direction: column;
559
- align-items: center;
560
- gap: 11px;
561
- background: var(--ui-surface);
562
- border: 0.5px solid var(--ui-border-strong);
563
- border-radius: 14px;
564
- padding: 20px 26px;
565
- }
566
-
567
- .ui-spinner {
568
- width: 30px;
569
- height: 30px;
570
- border-radius: 50%;
571
- border: 3px solid var(--ui-border-strong);
572
- border-top-color: var(--ui-accent);
573
- animation: ui-spin 0.8s linear infinite;
574
- }
575
-
576
- .ui-overlay-label {
577
- font-size: 14px;
578
- font-weight: 500;
579
- }
580
-
581
- @keyframes ui-spin {
582
- to {
583
- transform: rotate(360deg);
584
- }
585
- }
586
-
587
- /* Quiet boundary/scope note (T4): present but low-emphasis. */
588
- .ui-note {
589
- font-size: 12.5px;
590
- color: var(--ui-text-muted);
591
- line-height: 1.6;
592
- margin: 12px 0 0;
593
- }
594
-
595
- /* Inline info marker: minimal label stays visible, the detail is a tooltip. */
596
- .ui-info {
597
- display: inline-flex;
598
- align-items: center;
599
- justify-content: center;
600
- width: 1.3em;
601
- height: 1.3em;
602
- margin-left: 0.3em;
603
- border: 0.5px solid var(--ui-border-strong);
604
- border-radius: 50%;
605
- font-size: 0.72em;
606
- font-weight: 500;
607
- font-style: normal;
608
- line-height: 1;
609
- color: var(--ui-text-muted);
610
- cursor: help;
611
- vertical-align: middle;
612
- }
613
-
614
- .ui-info:hover,
615
- .ui-info:focus-visible {
616
- outline: none;
617
- border-color: var(--ui-accent);
618
- color: var(--ui-accent);
619
- }
620
-
621
- /* PTB graph: the rendered Mermaid SVG container. Mermaid's own injected \3c style>
622
- does not apply in this page context (SVG defaults to black fills), so the
623
- flowchart is painted from these always-applied token rules, theming it for both
624
- light and dark. The same render mechanism feeds the review and receipt pages. */
625
- .ui-ptb-graph {
626
- overflow-x: auto;
627
- min-height: 60px;
628
- color: var(--ui-text-muted);
629
- font-size: 13px;
630
- }
631
-
632
- .ui-ptb-graph svg {
633
- max-width: 100%;
634
- height: auto;
635
- }
636
-
637
- .ui-ptb-graph--error {
638
- color: var(--ui-danger);
639
- }
640
-
641
- /* Shared chain-receipt view (the Receipt page and the review Result state). */
642
- .ui-chain-receipt-gas {
643
- margin-bottom: 6px;
644
- }
645
-
646
- /* The graph occupies the document width. It has no enclosing card padding to
647
- cancel; its contents and background use the same theme tokens as the text. */
648
- .ui-chain-receipt-ptb {
649
- background: var(--ui-surface);
650
- min-width: 0;
651
- overflow: hidden;
652
- }
653
-
654
- /* Name/address toggle in the shared transaction-graph card's title bar. */
655
- .ui-ptb-actions {
656
- display: flex;
657
- align-items: center;
658
- gap: 4px;
659
- }
660
-
661
- /* Pan/zoom controls overlay the graph, so they sit on a slightly raised themed
662
- surface with a shadow to stand out from the themed graph behind them. */
663
- .ui-ptb-graph-controls .ui-icon-btn {
664
- background: var(--ui-surface-2);
665
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
666
- }
667
-
668
- /* The graph's node/edge/label/text colours are NOT set here: Mermaid injects an
669
- id-scoped \3c style> into the SVG that beats external rules, so the whole palette is
670
- driven from the app's design tokens through Mermaid's themeVariables in
671
- ptbDiagram.ts (theme "base"), re-rendered on theme toggle. */
672
-
673
- /* Pan/zoom mode: a fixed-height clipping viewport with a transformed content
674
- layer (wheel zooms toward the cursor, drag pans) and a controls overlay. */
675
- .ui-ptb-graph--interactive {
676
- position: relative;
677
- height: 420px;
678
- overflow: hidden;
679
- cursor: grab;
680
- user-select: none;
681
- touch-action: none;
682
- }
683
-
684
- .ui-ptb-graph--grabbing {
685
- cursor: grabbing;
686
- }
687
-
688
- .ui-ptb-graph-content {
689
- width: 100%;
690
- transform-origin: 0 0;
691
- }
692
-
693
- .ui-ptb-graph-controls {
694
- position: absolute;
695
- top: 8px;
696
- right: 8px;
697
- z-index: 2;
698
- display: flex;
699
- flex-direction: column;
700
- gap: 5px;
701
- }
702
-
703
- /* Compact controls so they do not crowd the graph. */
704
- .ui-ptb-graph-controls .ui-icon-btn {
705
- width: 28px;
706
- height: 28px;
707
- }
708
-
709
- .ui-ptb-graph-controls .ui-icon-btn svg {
710
- width: 15px;
711
- height: 15px;
712
- }
713
-
714
- /* Accordion: a collapsed-by-default disclosure for secondary fact groups
715
- (inputs, Move calls, object changes, events). Native <details>/<summary> with
716
- a custom chevron; no script. */
717
- .ui-accordion {
718
- border-block-start: 1px solid var(--ui-border);
719
- margin-block: 12px;
720
- }
721
-
722
- .ui-accordion-summary {
723
- display: flex;
724
- align-items: center;
725
- justify-content: space-between;
726
- gap: 10px;
727
- padding: 11px 0;
728
- cursor: pointer;
729
- font-size: 13px;
730
- font-weight: 500;
731
- color: var(--ui-text);
732
- list-style: none;
733
-
734
- }
735
-
736
- .ui-accordion-summary::-webkit-details-marker {
737
- display: none;
738
- }
739
-
740
- .ui-accordion-summary:hover {
741
- color: var(--ui-accent);
742
- }
743
-
744
- .ui-accordion-summary:focus-visible {
745
- outline: none;
746
- box-shadow: 0 0 0 3px var(--ui-focus);
747
- border-radius: var(--ui-r);
748
- }
749
-
750
- .ui-accordion-summary::after {
751
- content: "";
752
- flex: none;
753
- width: 7px;
754
- height: 7px;
755
- border-right: 1.5px solid var(--ui-text-muted);
756
- border-bottom: 1.5px solid var(--ui-text-muted);
757
- transform: rotate(45deg);
758
- transition: transform 0.15s;
759
- }
760
-
761
- .ui-accordion[open] .ui-accordion-summary::after {
762
- transform: rotate(-135deg);
763
- }
764
-
765
- .ui-accordion[open] .ui-accordion-summary {
766
- color: var(--ui-accent);
767
- }
768
-
769
- .ui-accordion-body {
770
- padding: 4px 0 12px;
771
- }
772
-
773
- /* Secondary content slides into the same document; no nested panels. */
774
- .ui-accordion[open] > .ui-accordion-body { animation: ui-reveal .18s ease-out; }
775
- @keyframes ui-reveal { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
776
- @media (prefers-reduced-motion: reduce) { .ui-accordion[open] > .ui-accordion-body { animation: none; } }
777
-
778
- /* Respond to the embedded card's available width, not the desktop window.
779
- Below 28rem, the 140px label column plus a readable value column and card
780
- gutters no longer fit comfortably. Keep full values in a stacked layout. */
781
- @container mcp-card (max-width: 28rem) {
782
- .ui-card {
783
- --ui-card-padding-block: 12px;
784
- --ui-card-padding-inline: 12px;
785
- }
786
- .ui-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
787
- .ui-row-value { text-align: left; }
788
- .ui-detail-meta { flex-wrap: wrap; }
789
- }
790
-
791
- @container mcp-card (min-width: 0px) {
792
- .ui-card, .ui-card-head > :first-child, .ui-detail-head > *, .ui-detail-meta > * { min-width: 0; }
793
- .ui-ptb-actions { flex: none; }
794
- /* Retain room for the controls without a tall empty graph on narrow cards. */
795
- .ui-ptb-graph--interactive { height: clamp(280px, 75cqi, 420px); }
796
- }
797
-
798
- /* Shared failure text and compact timestamp/identifier disclosures. */
799
- .ui-error:not(:empty) { color: var(--ui-danger); }
800
- .ui-note:empty, .ui-error:empty { display: none; }
801
-
802
- /* Shared form controls compose consistently in narrow embedded cards. */
803
- .ui-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
804
- .ui-form > * { min-width: 0; max-width: 100%; }
805
- .ui-form > input, .ui-form > select, .ui-form > label { flex: 1 1 14rem; }
806
- .ui-form label { display: flex; flex-direction: column; gap: 6px; }
807
- .ui-form label > input, .ui-form label > select { width: 100%; }
808
- .ui-form > details, .ui-form > p, .ui-form > .card-actions { flex-basis: 100%; }
809
- @container mcp-card (max-width: 28rem) { .ui-form > button { width: 100%; } }