js-kompo-utils 1.0.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 (67) hide show
  1. package/README.md +1 -0
  2. package/app.js +22 -0
  3. package/components/VlApexChart.vue +89 -0
  4. package/components/VlCKEditorTemplate.vue +52 -0
  5. package/components/VlCKEditorWithVars.vue +80 -0
  6. package/components/VlCollapsible.vue +91 -0
  7. package/components/VlCopyBox.vue +61 -0
  8. package/components/VlCreditCardInput.vue +104 -0
  9. package/components/VlDateMonthDay.vue +327 -0
  10. package/components/VlDateTextInput.vue +151 -0
  11. package/components/VlInternationalPhoneInput.vue +902 -0
  12. package/components/VlPartialDate.vue +283 -0
  13. package/components/VlPasswordInput.vue +358 -0
  14. package/components/VlQrCodeScanner.vue +91 -0
  15. package/components/VlSwipeableTab.vue +35 -0
  16. package/components/VlSwipeableTabs.vue +325 -0
  17. package/components/VlText.vue +72 -0
  18. package/components/VlTutorialStepBuilder.vue +671 -0
  19. package/components/VlValidatedInput.vue +262 -0
  20. package/components/data/countries.js +253 -0
  21. package/components/getAllDefaultComponents.js +12 -0
  22. package/docs/architecture.md +71 -0
  23. package/docs/tutorials.md +247 -0
  24. package/docs/usage.md +128 -0
  25. package/functions/index.js +7 -0
  26. package/functions/inputs.js +64 -0
  27. package/functions/loading.js +20 -0
  28. package/kompo-ckeditor-1.0.17/index.js +5 -0
  29. package/kompo-ckeditor-1.0.17/komponents/CKEditor.vue +36 -0
  30. package/kompo-ckeditor-1.0.17/komponents/CKEditorExtended.vue +66 -0
  31. package/kompo-ckeditor-1.0.17/komponents/EditableCKEditor.vue +42 -0
  32. package/kompo-ckeditor-1.0.17/komponents/TranslatableEditor.vue +28 -0
  33. package/kompo-ckeditor-1.0.17/mixins/CKEditor.js +291 -0
  34. package/kompo-ckeditor-1.0.17/mixins/CKEditorUtilities.js +52 -0
  35. package/kompo-ckeditor-1.0.17/mixins/CkUploadAdapter.js +95 -0
  36. package/kompo-ckeditor-1.0.17/mixins/translations/en.js +1 -0
  37. package/kompo-ckeditor-1.0.17/mixins/translations/fr.js +1 -0
  38. package/kompo-ckeditor-1.0.17/plugins/JsonBlockCommand.js +100 -0
  39. package/kompo-ckeditor-1.0.17/plugins/JsonBlockEditing.js +225 -0
  40. package/kompo-ckeditor-1.0.17/plugins/JsonBlockUi.js +21 -0
  41. package/kompo-ckeditor-1.0.17/plugins/MentionPlugin.js +118 -0
  42. package/orchestrator/KompoJsBuilder.js +333 -0
  43. package/package.json +25 -0
  44. package/raw_animations/count-up-animation.js +220 -0
  45. package/raw_animations/magic-poof.js +210 -0
  46. package/tutorials/TutorialConfig.js +34 -0
  47. package/tutorials/TutorialEngine.js +448 -0
  48. package/tutorials/index.js +2 -0
  49. package/tutorials/modules/AutoNext.js +86 -0
  50. package/tutorials/modules/Avatar.js +94 -0
  51. package/tutorials/modules/Bubble.js +617 -0
  52. package/tutorials/modules/Cursor.js +315 -0
  53. package/tutorials/modules/Highlight.js +282 -0
  54. package/tutorials/modules/HoverForcer.js +250 -0
  55. package/tutorials/modules/Mobile.js +148 -0
  56. package/tutorials/modules/Options.js +98 -0
  57. package/tutorials/modules/Overlay.js +142 -0
  58. package/tutorials/modules/Scroll.js +37 -0
  59. package/tutorials/modules/Typewriter.js +132 -0
  60. package/tutorials/step-builder/step-builder-bridge.js +436 -0
  61. package/tutorials/step-builder/utils/bezier-editor.js +379 -0
  62. package/tutorials/step-builder/utils/code-generator.js +127 -0
  63. package/tutorials/step-builder/utils/element-picker.js +125 -0
  64. package/tutorials/tutorial.scss +816 -0
  65. package/tutorials/utils/selectors.js +225 -0
  66. package/tutorials/utils/stability.js +76 -0
  67. package/tutorials/utils/svg.js +46 -0
@@ -0,0 +1,816 @@
1
+ // tutorials/tutorial.scss
2
+ // All styles extracted from inline JS Object.assign(el.style, {...}) calls.
3
+
4
+ // === Overlay ===
5
+ .tutorial-overlay {
6
+ position: fixed;
7
+ top: 0;
8
+ left: 0;
9
+ width: 100%;
10
+ height: 100%;
11
+ // No background-color here — set exclusively via JS setMode()
12
+ // to avoid CSS/inline conflicts
13
+ z-index: 9997; // Z.OVERLAY — below highlight (9998)
14
+ touch-action: none;
15
+ overscroll-behavior: contain;
16
+
17
+ &--transparent {
18
+ background-color: transparent !important;
19
+ }
20
+ }
21
+
22
+ .tutorial-peek-btn {
23
+ position: fixed;
24
+ z-index: 10003; // Z.CONTAINER + 1
25
+ bottom: 12px;
26
+ right: 12px;
27
+ width: 40px;
28
+ height: 40px;
29
+ border-radius: 50%;
30
+ border: none;
31
+ background-color: rgba(0, 0, 0, 0.5);
32
+ color: #fff;
33
+ font-size: 18px;
34
+ cursor: pointer;
35
+ display: none;
36
+ align-items: center;
37
+ justify-content: center;
38
+ backdrop-filter: blur(4px);
39
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
40
+ }
41
+
42
+ // === Container / Avatar ===
43
+ // Container is a direct child of body (sibling of overlay, not inside it)
44
+ // so it needs its own fixed positioning to center on screen.
45
+ .tutorial-container {
46
+ position: fixed;
47
+ top: 0;
48
+ left: 0;
49
+ width: 100%;
50
+ height: 100%;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
54
+ z-index: 10002; // Z.CONTAINER — above overlay and highlight
55
+ pointer-events: none; // Let clicks pass through to overlay
56
+
57
+ > * {
58
+ pointer-events: auto; // But children (bubble, avatar) are clickable
59
+ }
60
+
61
+ &--no-avatar {
62
+ // Bubble is on body now, not inside container — no overrides needed
63
+ .tutorial-arrow { display: none; }
64
+ }
65
+ }
66
+
67
+ .tutorial-img-wrapper {
68
+ position: relative;
69
+ flex-shrink: 0;
70
+ align-self: flex-end;
71
+ }
72
+
73
+ .tutorial-avatar {
74
+ object-fit: contain;
75
+ display: block;
76
+ pointer-events: none;
77
+ }
78
+
79
+ .tutorial-avatar-video {
80
+ object-fit: contain;
81
+ display: block;
82
+ pointer-events: none;
83
+ }
84
+
85
+ // === Bubble ===
86
+ .tutorial-bubble {
87
+ background-color: #ffffff;
88
+ border-radius: 16px;
89
+ padding: clamp(1rem, 3vw, 2rem) clamp(1.2rem, 4vw, 2.5rem);
90
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
91
+ position: fixed;
92
+ z-index: 10003; // Above container (10002) so bubble is never cut by avatar
93
+ color: #1a1a1a;
94
+ font-family: "Outfit", sans-serif;
95
+ opacity: 0;
96
+ transform: scale(0.8);
97
+ transform-origin: bottom right;
98
+ transition: opacity 0.3s ease, transform 0.3s ease;
99
+ display: flex;
100
+ flex-direction: column;
101
+ pointer-events: auto;
102
+
103
+ &--mobile {
104
+ position: relative;
105
+ right: auto;
106
+ left: auto;
107
+ margin-right: 0;
108
+ margin-left: 0;
109
+ bottom: auto;
110
+ top: auto;
111
+ padding: 0.8rem 1rem;
112
+ font-size: 13px;
113
+ max-width: 90vw;
114
+ min-width: 0;
115
+ width: 100%;
116
+ }
117
+
118
+ &--chat {
119
+ position: relative;
120
+ top: auto;
121
+ bottom: auto;
122
+ left: auto;
123
+ right: auto;
124
+ transform: none;
125
+ margin-left: 0;
126
+ margin-right: 0;
127
+ display: grid;
128
+ grid-template-columns: 100px 1fr;
129
+ gap: 1rem;
130
+ align-items: start;
131
+ }
132
+
133
+ &--left {
134
+ left: auto;
135
+ right: 100%;
136
+ margin-left: 0;
137
+ margin-right: clamp(10px, 3vw, 20px);
138
+ transform-origin: bottom right;
139
+ }
140
+
141
+ &--right {
142
+ right: auto;
143
+ left: 100%;
144
+ margin-right: 0;
145
+ margin-left: clamp(10px, 3vw, 20px);
146
+ transform-origin: bottom left;
147
+ }
148
+
149
+ &--top {
150
+ left: 0;
151
+ right: 0;
152
+ margin-left: auto;
153
+ margin-right: auto;
154
+ top: auto;
155
+ transform: none;
156
+ transform-origin: bottom center;
157
+ }
158
+ }
159
+
160
+ .tutorial-arrow {
161
+ position: absolute;
162
+ right: -18px;
163
+ bottom: 18px;
164
+ width: 0;
165
+ height: 0;
166
+ border-top: 14px solid transparent;
167
+ border-bottom: 14px solid transparent;
168
+ border-left: 20px solid #ffffff;
169
+
170
+ &--left {
171
+ right: -18px;
172
+ left: auto;
173
+ border-top: 14px solid transparent;
174
+ border-bottom: 14px solid transparent;
175
+ border-left: 20px solid #ffffff;
176
+ border-right: none;
177
+ }
178
+
179
+ &--right {
180
+ right: auto;
181
+ left: -18px;
182
+ border-top: 14px solid transparent;
183
+ border-bottom: 14px solid transparent;
184
+ border-right: 20px solid #ffffff;
185
+ border-left: none;
186
+ }
187
+
188
+ &--top {
189
+ left: 50%;
190
+ right: auto;
191
+ bottom: -18px;
192
+ transform: translateX(-50%);
193
+ border-left: 14px solid transparent;
194
+ border-right: 14px solid transparent;
195
+ border-top: 20px solid #ffffff;
196
+ border-bottom: none;
197
+ }
198
+
199
+ &--bottom {
200
+ top: -18px;
201
+ bottom: auto;
202
+ left: 50%;
203
+ right: auto;
204
+ transform: translateX(-50%);
205
+ border-left: 14px solid transparent;
206
+ border-right: 14px solid transparent;
207
+ border-bottom: 20px solid #ffffff;
208
+ border-top: none;
209
+ }
210
+
211
+ &--hidden {
212
+ display: none;
213
+ }
214
+ }
215
+
216
+ .tutorial-text {
217
+ margin: 0;
218
+ max-height: clamp(150px, 40vh, 300px);
219
+ overflow-y: auto;
220
+ }
221
+
222
+ .tutorial-options {
223
+ margin-top: 1rem;
224
+ display: none;
225
+ flex-direction: column;
226
+ gap: 0.5rem;
227
+ }
228
+
229
+ .tutorial-btn-row {
230
+ margin-top: 1.2rem;
231
+ display: flex;
232
+ justify-content: flex-end;
233
+ gap: 0.5rem;
234
+ opacity: 0;
235
+ transition: opacity 0.3s ease;
236
+ }
237
+
238
+ .tutorial-action-btn {
239
+ padding: 0.75rem 1.5rem;
240
+ min-height: 44px;
241
+ background-color: #07499e;
242
+ color: #ffffff;
243
+ border: none;
244
+ border-radius: 8px;
245
+ cursor: pointer;
246
+ font-size: 14px;
247
+ font-weight: 600;
248
+ }
249
+
250
+ .tutorial-pause-btn {
251
+ padding: 0.75rem 1rem;
252
+ min-height: 44px;
253
+ background-color: transparent;
254
+ color: #07499e;
255
+ border: 2px solid #07499e;
256
+ border-radius: 8px;
257
+ cursor: pointer;
258
+ font-size: 14px;
259
+ font-weight: 600;
260
+ display: none;
261
+ }
262
+
263
+ .tutorial-back-btn {
264
+ padding: 0.75rem 1rem;
265
+ min-height: 44px;
266
+ background-color: transparent;
267
+ color: #07499e;
268
+ border: 2px solid #07499e;
269
+ border-radius: 8px;
270
+ cursor: pointer;
271
+ font-size: 14px;
272
+ font-weight: 600;
273
+ display: none;
274
+ }
275
+
276
+ // === Chat mode avatar ===
277
+ .tutorial-chat-avatar {
278
+ width: 100px;
279
+ height: 100px;
280
+ min-width: 100px;
281
+ border-radius: 50%;
282
+ overflow: hidden;
283
+ border: 3px solid #07499e;
284
+ flex-shrink: 0;
285
+ align-self: center;
286
+
287
+ img {
288
+ width: 100%;
289
+ height: 100%;
290
+ object-fit: cover;
291
+ object-position: top center;
292
+ }
293
+ }
294
+
295
+ // === Cursor ===
296
+ .tutorial-cursor {
297
+ position: fixed;
298
+ z-index: 10000; // Z.CURSOR
299
+ pointer-events: none;
300
+ left: 0;
301
+ top: 0;
302
+ opacity: 0;
303
+
304
+ &--mobile {
305
+ width: 24px;
306
+ height: 24px;
307
+ border-radius: 50%;
308
+ background-color: #4a6cf7;
309
+ border: 3px solid #ffffff;
310
+ box-shadow: 0 2px 8px rgba(74, 108, 247, 0.5);
311
+ transform: translate(-50%, -50%);
312
+ }
313
+ }
314
+
315
+ // === Highlight ===
316
+ .tutorial-highlight-svg {
317
+ position: fixed;
318
+ top: 0;
319
+ left: 0;
320
+ width: 100%;
321
+ height: 100%;
322
+ z-index: 9998; // Z.HIGHLIGHT — above overlay (9997)
323
+ pointer-events: none;
324
+ }
325
+
326
+ // === Options ===
327
+ .tutorial-option-btn {
328
+ padding: 0.75rem 1rem;
329
+ min-height: 44px;
330
+ border-radius: 10px;
331
+ cursor: pointer;
332
+ font-size: 14px;
333
+ font-weight: 600;
334
+ text-align: left;
335
+ transition: background-color 0.2s ease, transform 0.1s ease;
336
+ opacity: 0;
337
+ transform: translateY(8px);
338
+ pointer-events: none;
339
+ }
340
+
341
+ // === AutoNext ===
342
+ .tutorial-auto-next-bar {
343
+ position: absolute;
344
+ bottom: 0;
345
+ left: 0;
346
+ height: clamp(3px, 0.8vw, 5px);
347
+ width: 0%;
348
+ background-color: #07499e;
349
+ border-radius: 0 0 16px 16px;
350
+ transition: none;
351
+ }
352
+
353
+ // === Click Pulse ===
354
+ @keyframes tutorial-pulse-ring {
355
+ 0% {
356
+ transform: translate(-50%, -50%) scale(1);
357
+ opacity: 1;
358
+ }
359
+ 100% {
360
+ transform: translate(-50%, -50%) scale(var(--pulse-scale, 3));
361
+ opacity: 0;
362
+ }
363
+ }
364
+
365
+ .tutorial-pulse-ring {
366
+ position: fixed;
367
+ width: 48px;
368
+ height: 48px;
369
+ border-radius: 50%;
370
+ border: 3px solid #ff4444;
371
+ pointer-events: none;
372
+ z-index: 10001; // Z.PULSE
373
+ transform: translate(-50%, -50%);
374
+ animation: tutorial-pulse-ring var(--pulse-duration, 0.7s) var(--pulse-delay, 0s) ease-out forwards;
375
+ }
376
+
377
+ // === Element Picker (dev only) ===
378
+ .tutorial-picker-highlight {
379
+ position: fixed;
380
+ border: 2px solid #6c8aff;
381
+ border-radius: 4px;
382
+ pointer-events: none;
383
+ z-index: 100001;
384
+ display: none;
385
+ transition: all 0.08s ease;
386
+ box-shadow: 0 0 0 3px rgba(108, 138, 255, 0.2);
387
+ }
388
+
389
+ .tutorial-picker-label {
390
+ position: fixed;
391
+ background: #1a1a2e;
392
+ color: #6c8aff;
393
+ padding: 2px 6px;
394
+ border-radius: 4px;
395
+ font-size: 10px;
396
+ font-family: monospace;
397
+ pointer-events: none;
398
+ z-index: 100002;
399
+ display: none;
400
+ white-space: nowrap;
401
+ }
402
+
403
+ // === Step Builder Panel (dev only) ===
404
+ // Panel positioning and base look
405
+ .tutorial-step-builder-panel {
406
+ position: fixed;
407
+ top: 0;
408
+ right: 0;
409
+ width: 420px;
410
+ height: 100vh;
411
+ overflow-y: auto;
412
+ z-index: 10010;
413
+ background: linear-gradient(170deg, #1e1e2e 0%, #161625 100%);
414
+ color: #e0e4ec;
415
+ border-left: 1px solid rgba(255, 255, 255, 0.06);
416
+ box-shadow: -4px 0 24px rgba(0, 0, 0, 0.4);
417
+
418
+ &:empty { display: none; }
419
+ }
420
+
421
+ // === [data-sb] scoped styles ===
422
+ // Override Kompo wrapper styles for the dark step builder theme.
423
+ // Kompo wraps fields in .vlField > .vlFormControl > input with white backgrounds.
424
+ // We use !important sparingly where Kompo specificity can't be beaten otherwise.
425
+
426
+ [data-sb] {
427
+ font-family: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
428
+ font-size: 13px;
429
+ line-height: 1.5;
430
+ }
431
+
432
+ [data-sb] *,
433
+ [data-sb] *::before,
434
+ [data-sb] *::after {
435
+ box-sizing: border-box;
436
+ }
437
+
438
+ // --- Override Kompo wrappers ---
439
+ [data-sb] .vlField,
440
+ [data-sb] .vlFormControl,
441
+ [data-sb] .vlInputWrapper,
442
+ [data-sb] .vlToggle {
443
+ background: transparent !important;
444
+ border: none !important;
445
+ box-shadow: none !important;
446
+ padding: 0 !important;
447
+ margin: 0 !important;
448
+ min-height: auto !important;
449
+ }
450
+
451
+ [data-sb] .vlFieldLabel {
452
+ color: #7a7f8e !important;
453
+ font-size: 11px !important;
454
+ text-transform: uppercase !important;
455
+ letter-spacing: 0.3px !important;
456
+ margin-bottom: 4px !important;
457
+ }
458
+
459
+ // --- Inputs ---
460
+ [data-sb] input,
461
+ [data-sb] select,
462
+ [data-sb] textarea {
463
+ background: rgba(255, 255, 255, 0.06) !important;
464
+ color: #e0e4ec !important;
465
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
466
+ border-radius: 8px !important;
467
+ padding: 8px 10px !important;
468
+ font-size: 13px !important;
469
+ font-family: inherit !important;
470
+ transition: border-color 0.2s, box-shadow 0.2s;
471
+ outline: none !important;
472
+ width: 100% !important;
473
+ }
474
+
475
+ [data-sb] input:focus,
476
+ [data-sb] select:focus,
477
+ [data-sb] textarea:focus {
478
+ border-color: #6c8aff !important;
479
+ box-shadow: 0 0 0 2px rgba(108, 138, 255, 0.15) !important;
480
+ }
481
+
482
+ [data-sb] input[type="number"] {
483
+ width: 72px !important;
484
+ }
485
+
486
+ [data-sb] input[type="checkbox"] {
487
+ width: 16px !important;
488
+ height: 16px !important;
489
+ accent-color: #6c8aff;
490
+ cursor: pointer;
491
+ }
492
+
493
+ [data-sb] select {
494
+ cursor: pointer;
495
+ appearance: none !important;
496
+ padding-right: 24px !important;
497
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23888'/%3E%3C/svg%3E") !important;
498
+ background-repeat: no-repeat !important;
499
+ background-position: right 8px center !important;
500
+ }
501
+
502
+ // --- Kompo Collapse/Collapsible overrides ---
503
+ [data-sb] .vlCollapse,
504
+ [data-sb] .vlCollapsible {
505
+ background: transparent !important;
506
+ border: none !important;
507
+ box-shadow: none !important;
508
+ }
509
+
510
+ [data-sb] .vlCollapseHeader,
511
+ [data-sb] .vlCollapsibleHeader {
512
+ padding: 8px 0 !important;
513
+ background: transparent !important;
514
+ }
515
+
516
+ // --- Kompo Toggle override ---
517
+ [data-sb] .vlToggleWrapper {
518
+ background: transparent !important;
519
+ }
520
+
521
+ [data-sb] .vlToggleLabel {
522
+ color: #b0b4c0 !important;
523
+ font-size: 12px !important;
524
+ }
525
+
526
+ // --- Buttons ---
527
+ [data-sb] .sb-btn {
528
+ border: none;
529
+ border-radius: 8px;
530
+ cursor: pointer;
531
+ font-size: 14px;
532
+ font-weight: 600;
533
+ padding: 9px 16px;
534
+ transition: all 0.15s;
535
+ font-family: inherit;
536
+ white-space: nowrap;
537
+ }
538
+
539
+ [data-sb] .sb-btn:hover {
540
+ filter: brightness(1.15);
541
+ transform: translateY(-1px);
542
+ }
543
+
544
+ [data-sb] .sb-btn:active {
545
+ transform: translateY(0);
546
+ }
547
+
548
+ [data-sb] .sb-btn-blue { background: #4a6cf7; color: #fff; }
549
+ [data-sb] .sb-btn-green { background: #2ecc71; color: #fff; }
550
+ [data-sb] .sb-btn-red { background: #e74c3c; color: #fff; }
551
+ [data-sb] .sb-btn-yellow { background: #f1c40f; color: #1a1a2e; }
552
+
553
+ [data-sb] .sb-btn-ghost {
554
+ background: rgba(255, 255, 255, 0.06);
555
+ color: #ccc;
556
+ border: 1px solid rgba(255, 255, 255, 0.1);
557
+ }
558
+
559
+ [data-sb] .sb-btn-ghost:hover {
560
+ background: rgba(255, 255, 255, 0.12);
561
+ }
562
+
563
+ [data-sb] .sb-btn-sm {
564
+ padding: 7px 12px;
565
+ font-size: 13px;
566
+ }
567
+
568
+ [data-sb] .sb-btn-icon {
569
+ padding: 7px 10px;
570
+ font-size: 16px;
571
+ min-width: 32px;
572
+ display: inline-flex;
573
+ align-items: center;
574
+ justify-content: center;
575
+ }
576
+
577
+ // --- Step list items ---
578
+ [data-sb] .sb-step-list-inner {
579
+ display: flex;
580
+ flex-direction: column;
581
+ gap: 2px;
582
+ }
583
+
584
+ [data-sb] .sb-step-item {
585
+ display: flex;
586
+ align-items: center;
587
+ gap: 6px;
588
+ padding: 6px 8px;
589
+ border-radius: 6px;
590
+ cursor: pointer;
591
+ transition: background 0.15s;
592
+ font-size: 12px;
593
+
594
+ &:hover { background: rgba(108, 138, 255, 0.1); }
595
+ &.sb-active {
596
+ background: rgba(108, 138, 255, 0.2);
597
+ border: 1px solid rgba(108, 138, 255, 0.3);
598
+ }
599
+ }
600
+
601
+ [data-sb] .sb-step-num {
602
+ width: 22px;
603
+ height: 22px;
604
+ border-radius: 50%;
605
+ background: rgba(255, 255, 255, 0.08);
606
+ display: flex;
607
+ align-items: center;
608
+ justify-content: center;
609
+ font-size: 11px;
610
+ font-weight: 700;
611
+ flex-shrink: 0;
612
+
613
+ .sb-active & { background: #6c8aff; color: #fff; }
614
+ }
615
+
616
+ [data-sb] .sb-step-text {
617
+ flex: 1;
618
+ overflow: hidden;
619
+ text-overflow: ellipsis;
620
+ white-space: nowrap;
621
+ color: #b0b4c0;
622
+ }
623
+
624
+ [data-sb] .sb-step-icons {
625
+ display: flex;
626
+ gap: 3px;
627
+ flex-shrink: 0;
628
+ font-size: 11px;
629
+ color: #7a7f8e;
630
+ }
631
+
632
+ // --- Cards ---
633
+ [data-sb] .sb-card {
634
+ background: rgba(255, 255, 255, 0.03);
635
+ border: 1px solid rgba(255, 255, 255, 0.06);
636
+ border-radius: 8px;
637
+ }
638
+
639
+ // --- Spectator exit ---
640
+ .sb-spectator-exit {
641
+ position: fixed;
642
+ top: 16px;
643
+ right: 16px;
644
+ z-index: 100001;
645
+ background: rgba(0, 0, 0, 0.7);
646
+ color: #fff;
647
+ border: 1px solid rgba(255, 255, 255, 0.2);
648
+ border-radius: 8px;
649
+ padding: 8px 16px;
650
+ font-size: 13px;
651
+ font-weight: 600;
652
+ cursor: pointer;
653
+ backdrop-filter: blur(8px);
654
+ }
655
+
656
+ // --- Labels & rows ---
657
+ [data-sb] .sb-label {
658
+ font-size: 14px;
659
+ color: #7a7f8e;
660
+ min-width: 65px;
661
+ flex-shrink: 0;
662
+ }
663
+
664
+ [data-sb] .sb-row {
665
+ display: flex;
666
+ gap: 8px;
667
+ align-items: center;
668
+ margin-bottom: 10px;
669
+ flex-wrap: wrap;
670
+ }
671
+
672
+ // --- Section headers ---
673
+ [data-sb] .sb-section-header {
674
+ font-size: 14px;
675
+ font-weight: 700;
676
+ color: #6c8aff;
677
+ cursor: pointer;
678
+ padding: 12px 0 8px;
679
+ user-select: none;
680
+ display: flex;
681
+ align-items: center;
682
+ gap: 6px;
683
+ letter-spacing: 0.3px;
684
+ text-transform: uppercase;
685
+ }
686
+
687
+ [data-sb] .sb-section-header:hover {
688
+ color: #8aa4ff;
689
+ }
690
+
691
+ [data-sb] .sb-section-divider {
692
+ border-top: 1px solid rgba(255, 255, 255, 0.06);
693
+ margin-top: 4px;
694
+ }
695
+
696
+ // --- Code blocks ---
697
+ [data-sb] .sb-code {
698
+ font-family: "Fira Code", "Cascadia Code", "JetBrains Mono", monospace;
699
+ }
700
+
701
+ [data-sb] .sb-selector {
702
+ color: #2ecc71;
703
+ font-size: 12px;
704
+ word-break: break-all;
705
+ font-family: "Fira Code", monospace;
706
+ }
707
+
708
+ // --- Scrollbar ---
709
+ [data-sb] ::-webkit-scrollbar { width: 6px; }
710
+ [data-sb] ::-webkit-scrollbar-track { background: transparent; }
711
+ [data-sb] ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 3px; }
712
+ [data-sb] ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); }
713
+
714
+ // --- Resize handles ---
715
+ [data-sb] .sb-resize-handle {
716
+ position: absolute;
717
+ width: 12px;
718
+ height: 12px;
719
+ cursor: nwse-resize;
720
+ bottom: 0;
721
+ right: 0;
722
+ z-index: 2;
723
+ }
724
+
725
+ [data-sb] .sb-resize-handle::after {
726
+ content: "";
727
+ position: absolute;
728
+ right: 3px;
729
+ bottom: 3px;
730
+ width: 8px;
731
+ height: 8px;
732
+ border-right: 2px solid rgba(255, 255, 255, 0.15);
733
+ border-bottom: 2px solid rgba(255, 255, 255, 0.15);
734
+ }
735
+
736
+ [data-sb] .sb-resize-left {
737
+ position: absolute;
738
+ width: 6px;
739
+ top: 40px;
740
+ bottom: 0;
741
+ left: 0;
742
+ cursor: ew-resize;
743
+ z-index: 2;
744
+ }
745
+
746
+ [data-sb] .sb-resize-top {
747
+ position: absolute;
748
+ height: 6px;
749
+ top: 0;
750
+ left: 0;
751
+ right: 0;
752
+ cursor: ns-resize;
753
+ z-index: 2;
754
+ }
755
+
756
+ // --- Option rows ---
757
+ [data-sb] .sb-option-row {
758
+ display: flex;
759
+ gap: 8px;
760
+ align-items: center;
761
+ padding: 10px 12px;
762
+ background: rgba(255, 255, 255, 0.03);
763
+ border-radius: 8px;
764
+ margin-bottom: 4px;
765
+ border: 1px solid rgba(255, 255, 255, 0.04);
766
+ }
767
+
768
+ // --- Badge ---
769
+ [data-sb] .sb-badge {
770
+ display: inline-block;
771
+ font-size: 11px;
772
+ padding: 2px 6px;
773
+ border-radius: 4px;
774
+ background: rgba(108, 138, 255, 0.15);
775
+ color: #6c8aff;
776
+ font-weight: 600;
777
+ }
778
+
779
+ // --- Responsive ---
780
+ @media (max-width: 600px) {
781
+ [data-sb] input,
782
+ [data-sb] select,
783
+ [data-sb] textarea {
784
+ font-size: 14px;
785
+ padding: 8px;
786
+ }
787
+
788
+ [data-sb] .sb-btn {
789
+ font-size: 13px;
790
+ padding: 8px 12px;
791
+ }
792
+
793
+ [data-sb] .sb-btn-sm {
794
+ font-size: 12px;
795
+ padding: 6px 10px;
796
+ }
797
+
798
+ [data-sb] .sb-step-btn {
799
+ font-size: 12px;
800
+ padding: 6px 10px;
801
+ }
802
+
803
+ [data-sb] .sb-row {
804
+ gap: 6px;
805
+ margin-bottom: 8px;
806
+ }
807
+
808
+ [data-sb] .sb-label {
809
+ font-size: 12px;
810
+ min-width: 50px;
811
+ }
812
+
813
+ [data-sb] .sb-section-header {
814
+ font-size: 12px;
815
+ }
816
+ }