@blendviewer/vision-scope 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 (87) hide show
  1. package/README.md +95 -0
  2. package/dist/index.js +187288 -0
  3. package/dist/nestcad-envmaps/citadella/negx.jpg +0 -0
  4. package/dist/nestcad-envmaps/citadella/negy.jpg +0 -0
  5. package/dist/nestcad-envmaps/citadella/negz.jpg +0 -0
  6. package/dist/nestcad-envmaps/citadella/posx.jpg +0 -0
  7. package/dist/nestcad-envmaps/citadella/posy.jpg +0 -0
  8. package/dist/nestcad-envmaps/citadella/posz.jpg +0 -0
  9. package/dist/nestcad-envmaps/citadella/readme.txt +13 -0
  10. package/dist/nestcad-envmaps/citadella.jpg +0 -0
  11. package/dist/nestcad-envmaps/fishermans_bastion/negx.jpg +0 -0
  12. package/dist/nestcad-envmaps/fishermans_bastion/negy.jpg +0 -0
  13. package/dist/nestcad-envmaps/fishermans_bastion/negz.jpg +0 -0
  14. package/dist/nestcad-envmaps/fishermans_bastion/posx.jpg +0 -0
  15. package/dist/nestcad-envmaps/fishermans_bastion/posy.jpg +0 -0
  16. package/dist/nestcad-envmaps/fishermans_bastion/posz.jpg +0 -0
  17. package/dist/nestcad-envmaps/fishermans_bastion/readme.txt +13 -0
  18. package/dist/nestcad-envmaps/fishermans_bastion.jpg +0 -0
  19. package/dist/nestcad-envmaps/ice_river/negx.jpg +0 -0
  20. package/dist/nestcad-envmaps/ice_river/negy.jpg +0 -0
  21. package/dist/nestcad-envmaps/ice_river/negz.jpg +0 -0
  22. package/dist/nestcad-envmaps/ice_river/posx.jpg +0 -0
  23. package/dist/nestcad-envmaps/ice_river/posy.jpg +0 -0
  24. package/dist/nestcad-envmaps/ice_river/posz.jpg +0 -0
  25. package/dist/nestcad-envmaps/ice_river/readme.txt +13 -0
  26. package/dist/nestcad-envmaps/ice_river.jpg +0 -0
  27. package/dist/nestcad-envmaps/maskonaive/negx.jpg +0 -0
  28. package/dist/nestcad-envmaps/maskonaive/negy.jpg +0 -0
  29. package/dist/nestcad-envmaps/maskonaive/negz.jpg +0 -0
  30. package/dist/nestcad-envmaps/maskonaive/posx.jpg +0 -0
  31. package/dist/nestcad-envmaps/maskonaive/posy.jpg +0 -0
  32. package/dist/nestcad-envmaps/maskonaive/posz.jpg +0 -0
  33. package/dist/nestcad-envmaps/maskonaive/readme.txt +13 -0
  34. package/dist/nestcad-envmaps/maskonaive.jpg +0 -0
  35. package/dist/nestcad-envmaps/noimage.jpg +0 -0
  36. package/dist/nestcad-envmaps/park/1.png +0 -0
  37. package/dist/nestcad-envmaps/park/2.png +0 -0
  38. package/dist/nestcad-envmaps/park/3.png +0 -0
  39. package/dist/nestcad-envmaps/park/4.png +0 -0
  40. package/dist/nestcad-envmaps/park/5.png +0 -0
  41. package/dist/nestcad-envmaps/park/6.png +0 -0
  42. package/dist/nestcad-envmaps/park/7.png +0 -0
  43. package/dist/nestcad-envmaps/park/negx.jpg +0 -0
  44. package/dist/nestcad-envmaps/park/negy.jpg +0 -0
  45. package/dist/nestcad-envmaps/park/negz.jpg +0 -0
  46. package/dist/nestcad-envmaps/park/posx.jpg +0 -0
  47. package/dist/nestcad-envmaps/park/posy.jpg +0 -0
  48. package/dist/nestcad-envmaps/park/posz.jpg +0 -0
  49. package/dist/nestcad-envmaps/park/readme.txt +13 -0
  50. package/dist/nestcad-envmaps/park.jpg +0 -0
  51. package/dist/nestcad-envmaps/teide/negx.jpg +0 -0
  52. package/dist/nestcad-envmaps/teide/negy.jpg +0 -0
  53. package/dist/nestcad-envmaps/teide/negz.jpg +0 -0
  54. package/dist/nestcad-envmaps/teide/posx.jpg +0 -0
  55. package/dist/nestcad-envmaps/teide/posy.jpg +0 -0
  56. package/dist/nestcad-envmaps/teide/posz.jpg +0 -0
  57. package/dist/nestcad-envmaps/teide/readme.txt +13 -0
  58. package/dist/nestcad-envmaps/teide.jpg +0 -0
  59. package/dist/nestcad-loaders/draco.license.md +252 -0
  60. package/dist/nestcad-loaders/draco_decoder.js +118 -0
  61. package/dist/nestcad-loaders/draco_decoder.wasm +0 -0
  62. package/dist/nestcad-loaders/occt-import-js-worker.js +15 -0
  63. package/dist/nestcad-loaders/occt-import-js.js +21 -0
  64. package/dist/nestcad-loaders/occt-import-js.license.md +504 -0
  65. package/dist/nestcad-loaders/occt-import-js.wasm +0 -0
  66. package/dist/nestcad-loaders/rhino3dm.license.md +21 -0
  67. package/dist/nestcad-loaders/rhino3dm.min.js +21 -0
  68. package/dist/nestcad-loaders/rhino3dm.wasm +0 -0
  69. package/dist/nestcad-loaders/web-ifc-api-browser.js +54925 -0
  70. package/dist/nestcad-loaders/web-ifc.license.md +375 -0
  71. package/dist/nestcad-loaders/web-ifc.wasm +0 -0
  72. package/dist/samples/.gitkeep +3 -0
  73. package/dist/samples/config-sample.json +6 -0
  74. package/dist/samples/logo-sample.svg +4 -0
  75. package/dist/samples/readme-sample.md +10 -0
  76. package/dist/styles/archive.css +431 -0
  77. package/dist/styles/code.css +119 -0
  78. package/dist/styles/document.css +1158 -0
  79. package/dist/styles/image.css +77 -0
  80. package/dist/styles/loading.css +124 -0
  81. package/dist/styles/media.css +99 -0
  82. package/dist/styles/native-three.css +54 -0
  83. package/dist/styles/spatial.css +39 -0
  84. package/dist/styles/tabular.css +157 -0
  85. package/dist/ui-styles/ui.css +1171 -0
  86. package/dist/vision-scope.css +1 -0
  87. package/package.json +80 -0
@@ -0,0 +1,1171 @@
1
+ /**
2
+ * VisionScope UI Styles
3
+ * Toolbar and Branding components
4
+ */
5
+
6
+ /* Host container: clip layout overflow; inner panels (e.g. .pdf-main-viewer) scroll */
7
+ .vision-scope-root {
8
+ position: relative;
9
+ width: 100%;
10
+ height: 100%;
11
+ max-width: 100%;
12
+ max-height: 100%;
13
+ overflow: hidden;
14
+ }
15
+
16
+ /* Renderer output layer — siblings (toolbar, bottom bar) stay outside this node */
17
+ .vision-scope-viewport {
18
+ position: absolute;
19
+ inset: 0;
20
+ width: 100%;
21
+ height: 100%;
22
+ overflow: hidden;
23
+ z-index: 0;
24
+ }
25
+
26
+ /* Hub scope extensions (e.g. HDF5) — fill viewport for nested React roots */
27
+ .vision-scope-viewport.vision-scope-scope-host {
28
+ display: flex;
29
+ flex-direction: column;
30
+ min-height: 0;
31
+ }
32
+
33
+ .vision-scope-viewport.vision-scope-scope-host > * {
34
+ flex: 1 1 auto;
35
+ min-height: 0;
36
+ width: 100%;
37
+ }
38
+
39
+ /* ============================================
40
+ Toolbar (Top-Right)
41
+ ============================================ */
42
+ .vision-scope-toolbar {
43
+ position: absolute;
44
+ top: 10px;
45
+ right: 10px;
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: 8px;
49
+ z-index: 1000;
50
+ pointer-events: none;
51
+ isolation: isolate;
52
+ color-scheme: light;
53
+ }
54
+
55
+ .vision-scope-toolbar > * {
56
+ pointer-events: auto;
57
+ }
58
+
59
+ /* Native <button> defaults (esp. focus / WebKit) can look like a dark tile — reset explicitly */
60
+ button.vsui-btn {
61
+ appearance: none;
62
+ -webkit-appearance: none;
63
+ font: inherit;
64
+ line-height: 1;
65
+ }
66
+
67
+ button.vsui-btn::-moz-focus-inner {
68
+ border: 0;
69
+ padding: 0;
70
+ }
71
+
72
+ .vsui-btn {
73
+ width: 36px;
74
+ height: 36px;
75
+ padding: 0;
76
+ margin: 0;
77
+ background: transparent;
78
+ border: none;
79
+ border-radius: 0;
80
+ color: rgba(26, 26, 26, 0.88);
81
+ font-size: 20px;
82
+ cursor: pointer;
83
+ transition:
84
+ color 0.15s ease,
85
+ opacity 0.15s ease,
86
+ background-color 0.15s ease, border-radius 0.15s ease;
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ box-shadow: none;
91
+ backdrop-filter: none;
92
+ -webkit-tap-highlight-color: transparent;
93
+ }
94
+
95
+ /* Keep focus ring off; avoid OS dark fill after click (still show gray when open or hovered) */
96
+ .vsui-btn:focus {
97
+ outline: none;
98
+ }
99
+
100
+ .vsui-btn:focus-visible {
101
+ outline: 2px solid rgba(0, 0, 0, 0.2);
102
+ outline-offset: 2px;
103
+ }
104
+
105
+ .vsui-btn:focus:not(:hover):not(.vsui-btn--active) {
106
+ background: transparent;
107
+ border-radius: 0;
108
+ }
109
+
110
+ /* Floating surface — stays visible over dark code/HTML (Prism okaidia) and light viewers */
111
+ .vision-scope-toolbar button.vsui-btn {
112
+ appearance: none;
113
+ -webkit-appearance: none;
114
+ color-scheme: light;
115
+ background-color: rgba(255, 255, 255, 0.94);
116
+ border: 1px solid rgba(0, 0, 0, 0.12);
117
+ border-radius: 8px;
118
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
119
+ color: rgba(26, 26, 26, 0.88);
120
+ }
121
+
122
+ .vision-scope-toolbar button.vsui-btn:focus,
123
+ .vision-scope-toolbar button.vsui-btn:focus:not(:hover):not(.vsui-btn--active),
124
+ .vision-scope-toolbar button.vsui-btn:hover,
125
+ .vision-scope-toolbar button.vsui-btn:active,
126
+ .vision-scope-toolbar button.vsui-btn.vsui-btn--active {
127
+ background-color: rgba(255, 255, 255, 1);
128
+ border-color: rgba(0, 0, 0, 0.16);
129
+ border-radius: 8px;
130
+ color: #111;
131
+ }
132
+
133
+ .vision-scope-toolbar button.vsui-btn svg {
134
+ filter: none;
135
+ }
136
+
137
+ /* ============================================
138
+ Bottom View Bar (Explode, etc.)
139
+ ============================================ */
140
+ .vision-scope-bottom-bar {
141
+ position: absolute;
142
+ left: 50%;
143
+ bottom: 16px;
144
+ transform: translateX(-50%);
145
+ z-index: 1000;
146
+ pointer-events: none;
147
+ display: flex;
148
+ justify-content: center;
149
+ max-width: calc(100% - 24px);
150
+ }
151
+
152
+ .vision-scope-bottom-bar > * {
153
+ pointer-events: auto;
154
+ }
155
+
156
+ .vsui-explode-control {
157
+ display: flex;
158
+ flex-direction: row;
159
+ align-items: center;
160
+ gap: 10px;
161
+ padding: 8px 14px;
162
+ min-width: 260px;
163
+ max-width: min(420px, calc(100vw - 32px));
164
+ background: rgba(255, 255, 255, 0.94);
165
+ border: 1px solid rgba(0, 0, 0, 0.12);
166
+ border-radius: 999px;
167
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
168
+ }
169
+
170
+ .vsui-explode-label {
171
+ display: flex;
172
+ align-items: center;
173
+ gap: 6px;
174
+ flex-shrink: 0;
175
+ color: rgba(26, 26, 26, 0.88);
176
+ font-size: 12px;
177
+ font-weight: 600;
178
+ white-space: nowrap;
179
+ }
180
+
181
+ .vsui-explode-slider {
182
+ flex: 1;
183
+ min-width: 80px;
184
+ height: 4px;
185
+ margin: 0;
186
+ accent-color: rgba(26, 26, 26, 0.75);
187
+ }
188
+
189
+ .vsui-explode-slider:disabled {
190
+ opacity: 0.45;
191
+ cursor: not-allowed;
192
+ }
193
+
194
+ .vsui-explode-value {
195
+ min-width: 36px;
196
+ text-align: right;
197
+ font-size: 11px;
198
+ color: rgba(26, 26, 26, 0.72);
199
+ font-variant-numeric: tabular-nums;
200
+ flex-shrink: 0;
201
+ }
202
+
203
+ .vsui-btn svg {
204
+ display: block;
205
+ flex-shrink: 0;
206
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.18));
207
+ }
208
+
209
+ .vsui-btn:hover {
210
+ color: #111;
211
+ opacity: 1;
212
+ background: rgba(0, 0, 0, 0.08);
213
+ border-radius: 8px;
214
+ }
215
+
216
+ .vsui-btn:active {
217
+ color: #111;
218
+ opacity: 1;
219
+ background: rgba(0, 0, 0, 0.08);
220
+ border-radius: 8px;
221
+ }
222
+
223
+ /** Menu open: same surface as hover */
224
+ .vsui-btn.vsui-btn--active {
225
+ color: #111;
226
+ opacity: 1;
227
+ background: rgba(0, 0, 0, 0.08);
228
+ border-radius: 8px;
229
+ }
230
+
231
+ .vision-scope-branding .vsui-branding-btn {
232
+ background: rgba(255, 255, 255, 0.94);
233
+ border: 1px solid rgba(0, 0, 0, 0.12);
234
+ border-radius: 8px;
235
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
236
+ }
237
+
238
+ .vision-scope-branding .vsui-branding-btn:hover,
239
+ .vision-scope-branding .vsui-branding-btn:active {
240
+ background: rgba(255, 255, 255, 1);
241
+ border-color: rgba(0, 0, 0, 0.16);
242
+ }
243
+
244
+ /* ============================================
245
+ Branding (Bottom-Right)
246
+ ============================================ */
247
+ .vision-scope-branding {
248
+ position: absolute;
249
+ bottom: 10px;
250
+ right: 10px;
251
+ display: flex;
252
+ flex-direction: column;
253
+ gap: 8px;
254
+ z-index: 999;
255
+ pointer-events: none;
256
+ }
257
+
258
+ .vsui-branding-btn {
259
+ width: 36px;
260
+ height: 36px;
261
+ padding: 0;
262
+ margin: 0;
263
+ background: transparent;
264
+ border: none;
265
+ border-radius: 0;
266
+ color: rgba(26, 26, 26, 0.88);
267
+ font-size: 16px;
268
+ display: flex;
269
+ align-items: center;
270
+ justify-content: center;
271
+ cursor: pointer;
272
+ transition:
273
+ color 0.15s ease,
274
+ opacity 0.15s ease,
275
+ background-color 0.15s ease, border-radius 0.15s ease;
276
+ text-decoration: none;
277
+ pointer-events: auto;
278
+ box-shadow: none;
279
+ backdrop-filter: none;
280
+ -webkit-tap-highlight-color: transparent;
281
+ }
282
+
283
+ .vsui-branding-btn svg {
284
+ display: block;
285
+ flex-shrink: 0;
286
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.18));
287
+ }
288
+
289
+ .vsui-branding-btn:hover {
290
+ color: #111;
291
+ opacity: 1;
292
+ background: rgba(0, 0, 0, 0.08);
293
+ border-radius: 8px;
294
+ }
295
+
296
+ .vsui-branding-btn:active {
297
+ color: #111;
298
+ opacity: 1;
299
+ background: rgba(0, 0, 0, 0.08);
300
+ border-radius: 8px;
301
+ }
302
+
303
+ /* ============================================
304
+ Modal
305
+ ============================================ */
306
+ .vsui-modal-backdrop {
307
+ position: fixed;
308
+ top: 0;
309
+ left: 0;
310
+ width: 100%;
311
+ height: 100%;
312
+ background: rgba(0, 0, 0, 0.7);
313
+ backdrop-filter: blur(4px);
314
+ display: flex;
315
+ align-items: center;
316
+ justify-content: center;
317
+ z-index: 10000;
318
+ animation: fadeIn 0.2s ease;
319
+ }
320
+
321
+ @keyframes fadeIn {
322
+ from {
323
+ opacity: 0;
324
+ }
325
+ to {
326
+ opacity: 1;
327
+ }
328
+ }
329
+
330
+ .vsui-modal-content {
331
+ background: rgba(255, 255, 255, 0.98);
332
+ border: 1px solid rgba(0, 0, 0, 0.1);
333
+ border-radius: 12px;
334
+ width: 90%;
335
+ max-width: 500px;
336
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
337
+ animation: slideUp 0.3s ease;
338
+ }
339
+
340
+ @keyframes slideUp {
341
+ from {
342
+ transform: translateY(20px);
343
+ opacity: 0;
344
+ }
345
+ to {
346
+ transform: translateY(0);
347
+ opacity: 1;
348
+ }
349
+ }
350
+
351
+ .vsui-modal-header {
352
+ padding: 20px 24px;
353
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: space-between;
357
+ }
358
+
359
+ .vsui-modal-header h3 {
360
+ margin: 0;
361
+ font-size: 18px;
362
+ font-weight: 600;
363
+ color: #1a1a1a;
364
+ }
365
+
366
+ .vsui-modal-close {
367
+ background: transparent;
368
+ border: none;
369
+ color: #666;
370
+ font-size: 24px;
371
+ cursor: pointer;
372
+ width: 32px;
373
+ height: 32px;
374
+ display: flex;
375
+ align-items: center;
376
+ justify-content: center;
377
+ border-radius: 6px;
378
+ transition: all 0.2s;
379
+ }
380
+
381
+ .vsui-modal-close:hover {
382
+ background: rgba(0, 0, 0, 0.05);
383
+ color: #1a1a1a;
384
+ }
385
+
386
+ .vsui-modal-body {
387
+ padding: 24px;
388
+ }
389
+
390
+ /* ============================================
391
+ Form Elements
392
+ ============================================ */
393
+ .vsui-form-group {
394
+ margin-bottom: 20px;
395
+ }
396
+
397
+ .vsui-form-group:last-child {
398
+ margin-bottom: 0;
399
+ }
400
+
401
+ .vsui-form-group label {
402
+ display: block;
403
+ margin-bottom: 8px;
404
+ color: #666;
405
+ font-size: 14px;
406
+ font-weight: 500;
407
+ }
408
+
409
+ .vsui-input {
410
+ width: 100%;
411
+ padding: 10px 12px;
412
+ background: rgba(0, 0, 0, 0.02);
413
+ border: 1px solid rgba(0, 0, 0, 0.15);
414
+ border-radius: 6px;
415
+ color: #1a1a1a;
416
+ font-size: 14px;
417
+ font-family: inherit;
418
+ transition: all 0.2s;
419
+ }
420
+
421
+ .vsui-input:focus {
422
+ outline: none;
423
+ border-color: #3b82f6;
424
+ background: white;
425
+ }
426
+
427
+ .vsui-input::placeholder {
428
+ color: #999;
429
+ }
430
+
431
+ .vsui-file-input {
432
+ width: 100%;
433
+ padding: 10px 12px;
434
+ background: rgba(0, 0, 0, 0.02);
435
+ border: 1px solid rgba(0, 0, 0, 0.15);
436
+ border-radius: 6px;
437
+ color: #1a1a1a;
438
+ font-size: 14px;
439
+ cursor: pointer;
440
+ transition: all 0.2s;
441
+ }
442
+
443
+ .vsui-icon-btn {
444
+ display: inline-flex;
445
+ align-items: center;
446
+ justify-content: center;
447
+ width: 32px;
448
+ height: 32px;
449
+ background: rgba(0, 0, 0, 0.05);
450
+ border: 1px solid rgba(0, 0, 0, 0.15);
451
+ border-radius: 6px;
452
+ color: #1a1a1a;
453
+ cursor: pointer;
454
+ transition: all 0.2s;
455
+ }
456
+
457
+ .vsui-icon-btn:hover {
458
+ background: rgba(0, 0, 0, 0.08);
459
+ border-color: rgba(0, 0, 0, 0.2);
460
+ }
461
+
462
+ .vsui-icon-btn:active {
463
+ background: rgba(0, 0, 0, 0.03);
464
+ transform: scale(0.95);
465
+ }
466
+
467
+ .vsui-icon-btn svg {
468
+ display: block;
469
+ flex-shrink: 0;
470
+ }
471
+
472
+ .vsui-file-input::-webkit-file-upload-button {
473
+ background: rgba(0, 0, 0, 0.05);
474
+ border: none;
475
+ padding: 6px 12px;
476
+ border-radius: 4px;
477
+ color: #1a1a1a;
478
+ cursor: pointer;
479
+ margin-right: 10px;
480
+ transition: all 0.2s;
481
+ }
482
+
483
+ .vsui-file-input::-webkit-file-upload-button:hover {
484
+ background: rgba(0, 0, 0, 0.1);
485
+ }
486
+
487
+ .vsui-btn-primary {
488
+ width: 100%;
489
+ padding: 12px;
490
+ background: #3b82f6;
491
+ border: none;
492
+ border-radius: 6px;
493
+ color: #fff;
494
+ font-size: 15px;
495
+ font-weight: 600;
496
+ cursor: pointer;
497
+ transition: all 0.2s;
498
+ }
499
+
500
+ .vsui-btn-primary:hover {
501
+ background: #2563eb;
502
+ transform: translateY(-1px);
503
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
504
+ }
505
+
506
+ .vsui-btn-primary:active {
507
+ transform: translateY(0);
508
+ }
509
+
510
+ /* ============================================
511
+ PDF Controls (Compact Design)
512
+ ============================================ */
513
+ .vsui-pdf-controls {
514
+ display: flex;
515
+ flex-direction: column;
516
+ gap: 12px;
517
+ margin-top: 12px;
518
+ }
519
+
520
+ .vsui-pdf-control-row {
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: space-between;
524
+ gap: 12px;
525
+ }
526
+
527
+ .vsui-pdf-label {
528
+ font-size: 13px;
529
+ font-weight: 500;
530
+ color: #666;
531
+ min-width: 45px;
532
+ }
533
+
534
+ .vsui-pdf-control-group {
535
+ display: flex;
536
+ align-items: center;
537
+ gap: 6px;
538
+ flex: 1;
539
+ justify-content: flex-end;
540
+ }
541
+
542
+ .vsui-pdf-btn {
543
+ display: inline-flex;
544
+ align-items: center;
545
+ justify-content: center;
546
+ width: 32px;
547
+ height: 32px;
548
+ background: rgba(0, 0, 0, 0.03);
549
+ border: 1px solid rgba(0, 0, 0, 0.1);
550
+ border-radius: 6px;
551
+ color: #1a1a1a;
552
+ cursor: pointer;
553
+ transition: all 0.15s ease;
554
+ }
555
+
556
+ .vsui-pdf-btn:hover {
557
+ background: rgba(0, 0, 0, 0.06);
558
+ border-color: rgba(0, 0, 0, 0.15);
559
+ transform: translateY(-1px);
560
+ }
561
+
562
+ .vsui-pdf-btn:active {
563
+ background: rgba(0, 0, 0, 0.08);
564
+ transform: translateY(0);
565
+ }
566
+
567
+ .vsui-pdf-btn svg {
568
+ display: block;
569
+ flex-shrink: 0;
570
+ }
571
+
572
+ .vsui-pdf-value {
573
+ font-size: 13px;
574
+ font-weight: 500;
575
+ color: #333;
576
+ min-width: 50px;
577
+ text-align: center;
578
+ font-variant-numeric: tabular-nums;
579
+ }
580
+
581
+ .vsui-pdf-reading-mode-row {
582
+ margin-top: 4px;
583
+ }
584
+
585
+ .vsui-pdf-reading-btn {
586
+ display: flex;
587
+ align-items: center;
588
+ justify-content: center;
589
+ gap: 8px;
590
+ width: 100%;
591
+ padding: 10px 16px;
592
+ background: rgba(0, 0, 0, 0.02);
593
+ border: 1px solid rgba(0, 0, 0, 0.1);
594
+ border-radius: 6px;
595
+ color: #1a1a1a;
596
+ font-size: 13px;
597
+ font-weight: 500;
598
+ cursor: pointer;
599
+ transition: all 0.2s ease;
600
+ }
601
+
602
+ .vsui-pdf-reading-btn:hover {
603
+ background: rgba(0, 0, 0, 0.04);
604
+ border-color: rgba(0, 0, 0, 0.15);
605
+ transform: translateY(-1px);
606
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
607
+ }
608
+
609
+ .vsui-pdf-reading-btn:active {
610
+ transform: translateY(0);
611
+ }
612
+
613
+ .vsui-pdf-reading-btn.active {
614
+ background: rgba(59, 130, 246, 0.08);
615
+ border-color: rgba(59, 130, 246, 0.3);
616
+ color: #3b82f6;
617
+ }
618
+
619
+ .vsui-pdf-reading-btn svg {
620
+ display: block;
621
+ flex-shrink: 0;
622
+ }
623
+
624
+ .vsui-pdf-hint {
625
+ font-size: 11px;
626
+ color: #999;
627
+ text-align: center;
628
+ margin-top: -4px;
629
+ line-height: 1.4;
630
+ }
631
+
632
+ /* ============================================
633
+ Mobile Responsive
634
+ ============================================ */
635
+ @media (max-width: 768px) {
636
+ .vision-scope-toolbar {
637
+ top: 8px;
638
+ right: 8px;
639
+ gap: 6px;
640
+ }
641
+
642
+ .vision-scope-bottom-bar {
643
+ bottom: 12px;
644
+ max-width: calc(100% - 16px);
645
+ }
646
+
647
+ .vsui-explode-control {
648
+ min-width: 0;
649
+ width: min(360px, calc(100vw - 16px));
650
+ padding: 7px 12px;
651
+ gap: 8px;
652
+ }
653
+
654
+ .vsui-btn {
655
+ width: 32px;
656
+ height: 32px;
657
+ font-size: 18px;
658
+ }
659
+
660
+ .vision-scope-branding {
661
+ bottom: 60px;
662
+ right: 8px;
663
+ gap: 6px;
664
+ }
665
+
666
+ .vsui-branding-btn {
667
+ width: 32px;
668
+ height: 32px;
669
+ font-size: 14px;
670
+ }
671
+
672
+ .vsui-modal-content {
673
+ width: 95%;
674
+ max-width: none;
675
+ margin: 0 10px;
676
+ }
677
+
678
+ .vsui-modal-header {
679
+ padding: 16px 20px;
680
+ }
681
+
682
+ .vsui-modal-body {
683
+ padding: 20px;
684
+ }
685
+
686
+ .vsui-settings-panel {
687
+ width: calc(100vw - 60px);
688
+ max-width: 320px;
689
+ }
690
+ }
691
+
692
+ /* ============================================
693
+ Settings Panel
694
+ ============================================ */
695
+ .vsui-settings-panel {
696
+ position: absolute;
697
+ width: 280px;
698
+ background: #ffffff;
699
+ border: 1px solid rgba(0, 0, 0, 0.1);
700
+ border-radius: 8px;
701
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
702
+ z-index: 1001;
703
+ animation: vsuiSettingsFadeIn 0.2s ease;
704
+ -webkit-font-smoothing: antialiased;
705
+ -moz-osx-font-smoothing: grayscale;
706
+ text-rendering: optimizeLegibility;
707
+ font-family:
708
+ -apple-system,
709
+ BlinkMacSystemFont,
710
+ 'Segoe UI',
711
+ Roboto,
712
+ 'Helvetica Neue',
713
+ Arial,
714
+ 'PingFang SC',
715
+ 'Hiragino Sans GB',
716
+ 'Microsoft YaHei',
717
+ sans-serif;
718
+ }
719
+
720
+ @keyframes vsuiSettingsFadeIn {
721
+ from {
722
+ opacity: 0;
723
+ }
724
+ to {
725
+ opacity: 1;
726
+ }
727
+ }
728
+
729
+ .vsui-settings-header {
730
+ display: flex;
731
+ align-items: center;
732
+ justify-content: space-between;
733
+ gap: 12px;
734
+ padding: 12px 12px 12px 16px;
735
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
736
+ }
737
+
738
+ .vsui-settings-header h4 {
739
+ margin: 0;
740
+ font-size: 14px;
741
+ font-weight: 600;
742
+ color: #1a1a1a;
743
+ }
744
+
745
+ .vsui-settings-close {
746
+ display: inline-flex;
747
+ align-items: center;
748
+ justify-content: center;
749
+ width: 28px;
750
+ height: 28px;
751
+ padding: 0;
752
+ background: transparent;
753
+ border: none;
754
+ border-radius: 6px;
755
+ color: #666;
756
+ cursor: pointer;
757
+ transition: background-color 0.15s ease, color 0.15s ease;
758
+ appearance: none;
759
+ -webkit-appearance: none;
760
+ flex-shrink: 0;
761
+ }
762
+
763
+ .vsui-settings-close:hover {
764
+ background: rgba(0, 0, 0, 0.06);
765
+ color: #1a1a1a;
766
+ }
767
+
768
+ .vsui-settings-close:focus {
769
+ outline: none;
770
+ }
771
+
772
+ .vsui-settings-close:focus-visible {
773
+ outline: 2px solid rgba(0, 0, 0, 0.2);
774
+ outline-offset: 2px;
775
+ }
776
+
777
+ .vsui-settings-body {
778
+ padding: 16px;
779
+ max-height: min(70vh, 520px);
780
+ overflow-y: auto;
781
+ }
782
+
783
+ .vsui-settings-body::-webkit-scrollbar {
784
+ width: 6px;
785
+ }
786
+
787
+ .vsui-settings-body::-webkit-scrollbar-track {
788
+ background: rgba(0, 0, 0, 0.05);
789
+ border-radius: 3px;
790
+ }
791
+
792
+ .vsui-settings-body::-webkit-scrollbar-thumb {
793
+ background: rgba(0, 0, 0, 0.2);
794
+ border-radius: 3px;
795
+ }
796
+
797
+ .vsui-settings-body::-webkit-scrollbar-thumb:hover {
798
+ background: rgba(0, 0, 0, 0.3);
799
+ }
800
+
801
+ .vsui-settings-section {
802
+ margin-bottom: 20px;
803
+ padding-bottom: 16px;
804
+ border-bottom: 1px solid rgba(0, 0, 0, 0.08);
805
+ }
806
+
807
+ .vsui-settings-section:last-child {
808
+ margin-bottom: 0;
809
+ padding-bottom: 0;
810
+ border-bottom: none;
811
+ }
812
+
813
+ .vsui-section-title {
814
+ margin: 0 0 12px 0;
815
+ font-size: 11px;
816
+ font-weight: 700;
817
+ color: #666;
818
+ letter-spacing: 0.5px;
819
+ text-transform: uppercase;
820
+ }
821
+
822
+ .vsui-action-btn {
823
+ width: 100%;
824
+ padding: 10px 12px;
825
+ margin-bottom: 6px;
826
+ background: transparent;
827
+ border: none;
828
+ border-radius: 8px;
829
+ color: #1a1a1a;
830
+ font-size: 14px;
831
+ text-align: left;
832
+ cursor: pointer;
833
+ transition:
834
+ color 0.15s ease,
835
+ background-color 0.15s ease;
836
+ display: flex;
837
+ align-items: center;
838
+ gap: 12px;
839
+ appearance: none;
840
+ -webkit-appearance: none;
841
+ font: inherit;
842
+ box-shadow: none;
843
+ }
844
+
845
+ .vsui-action-btn:last-child {
846
+ margin-bottom: 0;
847
+ }
848
+
849
+ .vsui-action-btn:hover {
850
+ background: rgba(0, 0, 0, 0.08);
851
+ }
852
+
853
+ .vsui-action-btn:active {
854
+ background: rgba(0, 0, 0, 0.08);
855
+ }
856
+
857
+ .vsui-action-btn:focus {
858
+ outline: none;
859
+ }
860
+
861
+ .vsui-action-btn:focus-visible {
862
+ outline: 2px solid rgba(0, 0, 0, 0.2);
863
+ outline-offset: 2px;
864
+ }
865
+
866
+ .vsui-action-icon {
867
+ display: inline-flex;
868
+ align-items: center;
869
+ justify-content: center;
870
+ width: 18px;
871
+ height: 18px;
872
+ }
873
+
874
+ .vsui-action-icon svg {
875
+ display: block;
876
+ flex-shrink: 0;
877
+ }
878
+
879
+ .vsui-import-url-row {
880
+ display: flex;
881
+ gap: 8px;
882
+ margin-bottom: 8px;
883
+ }
884
+
885
+ .vsui-text-input {
886
+ flex: 1;
887
+ min-width: 0;
888
+ height: 34px;
889
+ padding: 0 10px;
890
+ background: rgba(0, 0, 0, 0.02);
891
+ border: 1px solid rgba(0, 0, 0, 0.12);
892
+ border-radius: 6px;
893
+ color: #1a1a1a;
894
+ font-size: 13px;
895
+ font: inherit;
896
+ }
897
+
898
+ .vsui-text-input::placeholder {
899
+ color: #999;
900
+ }
901
+
902
+ .vsui-text-input:focus {
903
+ outline: none;
904
+ border-color: rgba(59, 130, 246, 0.5);
905
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.12);
906
+ }
907
+
908
+ .vsui-import-submit-btn {
909
+ flex-shrink: 0;
910
+ height: 34px;
911
+ padding: 0 12px;
912
+ background: #3b82f6;
913
+ border: none;
914
+ border-radius: 6px;
915
+ color: #fff;
916
+ font-size: 13px;
917
+ font-weight: 600;
918
+ cursor: pointer;
919
+ transition: background-color 0.15s ease;
920
+ appearance: none;
921
+ -webkit-appearance: none;
922
+ font: inherit;
923
+ }
924
+
925
+ .vsui-import-submit-btn:hover {
926
+ background: #2563eb;
927
+ }
928
+
929
+ .vsui-import-submit-btn:focus {
930
+ outline: none;
931
+ }
932
+
933
+ .vsui-import-submit-btn:focus-visible {
934
+ outline: 2px solid rgba(59, 130, 246, 0.45);
935
+ outline-offset: 2px;
936
+ }
937
+
938
+ .vsui-control-row {
939
+ display: flex;
940
+ align-items: center;
941
+ justify-content: space-between;
942
+ gap: 12px;
943
+ margin-bottom: 10px;
944
+ }
945
+
946
+ .vsui-control-row:last-child {
947
+ margin-bottom: 0;
948
+ }
949
+
950
+ .vsui-control-label {
951
+ font-size: 13px;
952
+ font-weight: 500;
953
+ color: #666;
954
+ min-width: 88px;
955
+ flex-shrink: 0;
956
+ }
957
+
958
+ .vsui-control-value {
959
+ display: flex;
960
+ align-items: center;
961
+ justify-content: flex-end;
962
+ flex: 1;
963
+ min-width: 0;
964
+ }
965
+
966
+ .vsui-control-value--slider {
967
+ gap: 10px;
968
+ }
969
+
970
+ .vsui-control-value input[type='color'] {
971
+ width: 56px;
972
+ height: 28px;
973
+ padding: 2px;
974
+ background: rgba(0, 0, 0, 0.02);
975
+ border: 1px solid rgba(0, 0, 0, 0.15);
976
+ border-radius: 6px;
977
+ cursor: pointer;
978
+ }
979
+
980
+ .vsui-control-value input[type='color']::-webkit-color-swatch-wrapper {
981
+ padding: 0;
982
+ }
983
+
984
+ .vsui-control-value input[type='color']::-webkit-color-swatch {
985
+ border: none;
986
+ border-radius: 4px;
987
+ }
988
+
989
+ .vsui-control-value input[type='checkbox'] {
990
+ width: 18px;
991
+ height: 18px;
992
+ margin: 0;
993
+ cursor: pointer;
994
+ accent-color: #3b82f6;
995
+ }
996
+
997
+ .vsui-control-hint {
998
+ font-size: 12px;
999
+ color: #999;
1000
+ text-align: right;
1001
+ }
1002
+
1003
+ .vsui-settings-nested {
1004
+ display: none;
1005
+ margin: 2px 0 10px 8px;
1006
+ padding: 8px 8px 4px 12px;
1007
+ border-left: 2px solid rgba(0, 0, 0, 0.08);
1008
+ background: rgba(0, 0, 0, 0.02);
1009
+ border-radius: 0 6px 6px 0;
1010
+ }
1011
+
1012
+ .vsui-settings-nested.is-visible {
1013
+ display: block;
1014
+ }
1015
+
1016
+ .vsui-control-value--slider input[type='range'] {
1017
+ flex: 1;
1018
+ min-width: 0;
1019
+ height: 4px;
1020
+ background: rgba(0, 0, 0, 0.12);
1021
+ border-radius: 2px;
1022
+ outline: none;
1023
+ -webkit-appearance: none;
1024
+ }
1025
+
1026
+ .vsui-control-value--slider input[type='range']::-webkit-slider-thumb {
1027
+ -webkit-appearance: none;
1028
+ width: 16px;
1029
+ height: 16px;
1030
+ background: #3b82f6;
1031
+ border-radius: 50%;
1032
+ cursor: pointer;
1033
+ }
1034
+
1035
+ .vsui-control-value--slider input[type='range']::-moz-range-thumb {
1036
+ width: 16px;
1037
+ height: 16px;
1038
+ background: #3b82f6;
1039
+ border: none;
1040
+ border-radius: 50%;
1041
+ cursor: pointer;
1042
+ }
1043
+
1044
+ .vsui-control-value--slider span {
1045
+ min-width: 28px;
1046
+ text-align: right;
1047
+ color: #666;
1048
+ font-size: 13px;
1049
+ font-weight: 500;
1050
+ font-variant-numeric: tabular-nums;
1051
+ }
1052
+
1053
+ .vsui-settings-group {
1054
+ margin-bottom: 16px;
1055
+ }
1056
+
1057
+ .vsui-settings-group:last-child {
1058
+ margin-bottom: 0;
1059
+ }
1060
+
1061
+ .vsui-settings-group label {
1062
+ display: block;
1063
+ margin-bottom: 8px;
1064
+ color: #666;
1065
+ font-size: 13px;
1066
+ font-weight: 500;
1067
+ }
1068
+
1069
+ .vsui-settings-group input[type='color'] {
1070
+ width: 100%;
1071
+ height: 36px;
1072
+ padding: 4px;
1073
+ background: rgba(0, 0, 0, 0.02);
1074
+ border: 1px solid rgba(0, 0, 0, 0.15);
1075
+ border-radius: 6px;
1076
+ cursor: pointer;
1077
+ }
1078
+
1079
+ .vsui-settings-group input[type='color']::-webkit-color-swatch-wrapper {
1080
+ padding: 0;
1081
+ }
1082
+
1083
+ .vsui-settings-group input[type='color']::-webkit-color-swatch {
1084
+ border: none;
1085
+ border-radius: 4px;
1086
+ }
1087
+
1088
+ .vsui-checkbox-label {
1089
+ display: flex;
1090
+ align-items: center;
1091
+ cursor: pointer;
1092
+ margin: 0;
1093
+ }
1094
+
1095
+ .vsui-checkbox-label input[type='checkbox'] {
1096
+ width: 18px;
1097
+ height: 18px;
1098
+ margin: 0 8px 0 0;
1099
+ cursor: pointer;
1100
+ accent-color: #3b82f6;
1101
+ }
1102
+
1103
+ .vsui-checkbox-label span {
1104
+ color: #666;
1105
+ font-size: 14px;
1106
+ }
1107
+
1108
+ .vsui-slider-group {
1109
+ display: flex;
1110
+ align-items: center;
1111
+ gap: 12px;
1112
+ }
1113
+
1114
+ .vsui-slider-group input[type='range'] {
1115
+ flex: 1;
1116
+ height: 4px;
1117
+ background: rgba(0, 0, 0, 0.12);
1118
+ border-radius: 2px;
1119
+ outline: none;
1120
+ -webkit-appearance: none;
1121
+ }
1122
+
1123
+ .vsui-slider-group input[type='range']::-webkit-slider-thumb {
1124
+ -webkit-appearance: none;
1125
+ width: 16px;
1126
+ height: 16px;
1127
+ background: #3b82f6;
1128
+ border-radius: 50%;
1129
+ cursor: pointer;
1130
+ transition: all 0.2s;
1131
+ }
1132
+
1133
+ .vsui-slider-group input[type='range']::-webkit-slider-thumb:hover {
1134
+ background: #2563eb;
1135
+ transform: scale(1.1);
1136
+ }
1137
+
1138
+ .vsui-slider-group input[type='range']::-moz-range-thumb {
1139
+ width: 16px;
1140
+ height: 16px;
1141
+ background: #3b82f6;
1142
+ border: none;
1143
+ border-radius: 50%;
1144
+ cursor: pointer;
1145
+ transition: all 0.2s;
1146
+ }
1147
+
1148
+ .vsui-slider-group input[type='range']::-moz-range-thumb:hover {
1149
+ background: #2563eb;
1150
+ transform: scale(1.1);
1151
+ }
1152
+
1153
+ .vsui-slider-group span {
1154
+ min-width: 32px;
1155
+ text-align: right;
1156
+ color: #666;
1157
+ font-size: 13px;
1158
+ font-weight: 500;
1159
+ }
1160
+
1161
+ .vsui-sr-only {
1162
+ position: absolute;
1163
+ width: 1px;
1164
+ height: 1px;
1165
+ padding: 0;
1166
+ margin: -1px;
1167
+ overflow: hidden;
1168
+ clip: rect(0, 0, 0, 0);
1169
+ white-space: nowrap;
1170
+ border: 0;
1171
+ }