three-cad-viewer 4.1.2 → 4.3.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 (58) hide show
  1. package/Readme.md +12 -5
  2. package/dist/camera/camera.d.ts +14 -2
  3. package/dist/core/studio-manager.d.ts +90 -0
  4. package/dist/core/types.d.ts +239 -9
  5. package/dist/core/viewer-state.d.ts +28 -2
  6. package/dist/core/viewer.d.ts +200 -6
  7. package/dist/index.d.ts +7 -2
  8. package/dist/rendering/environment.d.ts +239 -0
  9. package/dist/rendering/light-detection.d.ts +44 -0
  10. package/dist/rendering/material-factory.d.ts +77 -2
  11. package/dist/rendering/material-presets.d.ts +32 -0
  12. package/dist/rendering/room-environment.d.ts +13 -0
  13. package/dist/rendering/studio-composer.d.ts +130 -0
  14. package/dist/rendering/studio-floor.d.ts +53 -0
  15. package/dist/rendering/texture-cache.d.ts +100 -0
  16. package/dist/rendering/triplanar.d.ts +37 -0
  17. package/dist/scene/animation.d.ts +1 -1
  18. package/dist/scene/clipping.d.ts +31 -0
  19. package/dist/scene/nestedgroup.d.ts +63 -27
  20. package/dist/scene/objectgroup.d.ts +47 -0
  21. package/dist/three-cad-viewer.css +339 -29
  22. package/dist/three-cad-viewer.esm.js +26944 -11874
  23. package/dist/three-cad-viewer.esm.js.map +1 -1
  24. package/dist/three-cad-viewer.esm.min.js +10 -4
  25. package/dist/three-cad-viewer.js +26863 -11787
  26. package/dist/three-cad-viewer.min.js +10 -4
  27. package/dist/ui/display.d.ts +147 -0
  28. package/dist/utils/decode-instances.d.ts +60 -0
  29. package/dist/utils/utils.d.ts +10 -0
  30. package/package.json +4 -2
  31. package/src/_version.ts +1 -1
  32. package/src/camera/camera.ts +27 -10
  33. package/src/core/studio-manager.ts +652 -0
  34. package/src/core/types.ts +302 -9
  35. package/src/core/viewer-state.ts +84 -4
  36. package/src/core/viewer.ts +453 -22
  37. package/src/index.ts +24 -1
  38. package/src/rendering/environment.ts +840 -0
  39. package/src/rendering/light-detection.ts +327 -0
  40. package/src/rendering/material-factory.ts +458 -2
  41. package/src/rendering/material-presets.ts +289 -0
  42. package/src/rendering/raycast.ts +2 -2
  43. package/src/rendering/room-environment.ts +192 -0
  44. package/src/rendering/studio-composer.ts +577 -0
  45. package/src/rendering/studio-floor.ts +108 -0
  46. package/src/rendering/texture-cache.ts +319 -0
  47. package/src/rendering/triplanar.ts +329 -0
  48. package/src/scene/animation.ts +3 -2
  49. package/src/scene/clipping.ts +59 -0
  50. package/src/scene/nestedgroup.ts +392 -0
  51. package/src/scene/objectgroup.ts +186 -11
  52. package/src/scene/orientation.ts +12 -0
  53. package/src/scene/render-shape.ts +55 -21
  54. package/src/types/n8ao.d.ts +28 -0
  55. package/src/ui/display.ts +1032 -27
  56. package/src/ui/index.html +181 -44
  57. package/src/utils/decode-instances.ts +233 -0
  58. package/src/utils/utils.ts +33 -20
@@ -69,9 +69,17 @@ declare class ObjectGroup extends THREE.Group {
69
69
  vertexFocusSize: number;
70
70
  edgeFocusWidth: number;
71
71
  shapeGeometry?: THREE.BufferGeometry | null;
72
+ /** Material tag from shapes data, used for Studio mode material lookup */
73
+ materialTag: string;
72
74
  minZ?: number;
73
75
  height?: number;
74
76
  private _zebra;
77
+ private _cadFrontMaterial;
78
+ private _cadBackMaterial;
79
+ private _cadOriginalColor;
80
+ private _cadOriginalBackColor;
81
+ private _isStudioMode;
82
+ private _cadEdgesVisible;
75
83
  /**
76
84
  * Create an ObjectGroup for managing a CAD object's visual representation.
77
85
  * @param opacity - Default opacity value (0.0 to 1.0).
@@ -86,6 +94,10 @@ declare class ObjectGroup extends THREE.Group {
86
94
  * Get the zebra tool, creating it on first access.
87
95
  */
88
96
  get zebra(): ZebraTool;
97
+ /**
98
+ * Whether this ObjectGroup is currently in Studio mode.
99
+ */
100
+ get isStudioMode(): boolean;
89
101
  /**
90
102
  * Dispose of all resources and clean up memory.
91
103
  * Releases geometry, materials, children, and zebra tool.
@@ -252,6 +264,41 @@ declare class ObjectGroup extends THREE.Group {
252
264
  * Set the mapping mode for zebra stripes.
253
265
  */
254
266
  setZebraMappingMode(value: ZebraMappingMode): void;
267
+ /**
268
+ * Enter Studio mode: swap CAD materials for pre-built Studio materials.
269
+ *
270
+ * The caller (NestedGroup) is responsible for resolving material tags and
271
+ * building MeshPhysicalMaterial instances via MaterialFactory. ObjectGroup
272
+ * just receives the finished materials and performs the swap.
273
+ *
274
+ * On first call, saves the current CAD material references so they can be
275
+ * restored by `leaveStudioMode()`. Copies the `material.visible` flag from
276
+ * CAD to Studio material to preserve tree-view hide/show state. Updates
277
+ * `originalColor` / `originalBackColor` so highlight/unhighlight works
278
+ * correctly in Studio mode.
279
+ *
280
+ * @param studioFront - Studio material for front face, or null if this object has no front mesh
281
+ * @param studioBack - Studio material for back face, or null if back face should not be swapped
282
+ */
283
+ enterStudioMode(studioFront: THREE.MeshPhysicalMaterial | null, studioBack: THREE.MeshPhysicalMaterial | null): void;
284
+ /**
285
+ * Leave Studio mode: restore CAD materials.
286
+ *
287
+ * Copies `material.visible` from Studio back to CAD material to preserve
288
+ * any visibility changes made while in Studio mode (e.g., tree-view toggle).
289
+ * Restores `originalColor` / `originalBackColor` to CAD material colors.
290
+ * Restores edge visibility to the state saved when entering Studio mode.
291
+ */
292
+ leaveStudioMode(): void;
293
+ /**
294
+ * Toggle edge visibility while in Studio mode.
295
+ *
296
+ * Only affects edges (not vertices). Should only be called while in
297
+ * Studio mode; the saved CAD edge visibility is not affected.
298
+ *
299
+ * @param visible - Whether edges should be visible
300
+ */
301
+ setStudioShowEdges(visible: boolean): void;
255
302
  }
256
303
  /**
257
304
  * Type guard to check if an object is an ObjectGroup instance.
@@ -4,6 +4,7 @@
4
4
  --tcv-font-color: #333;
5
5
  --tcv-bg-color: #fff;
6
6
  --tcv-bg-overlay-color: rgba(255, 255, 255, 0.7);
7
+ --tcv-bg-overlay-rest-color: rgba(255, 255, 255, 0.14);
7
8
  --tcv-bg-highlight-color: #ddd;
8
9
  --tcv-bg-pressed-color: #eee;
9
10
  --tcv-bg-pressed-border-color: #bbb;
@@ -63,6 +64,7 @@
63
64
  --tcv-font-color: #ddd;
64
65
  --tcv-bg-color: #444;
65
66
  --tcv-bg-overlay-color: rgba(68, 68, 68, 0.7);
67
+ --tcv-bg-overlay-rest-color: rgba(68, 68, 68, 0.14);
66
68
  --tcv-bg-highlight-color: rgb(104, 104, 104);
67
69
  --tcv-bg-pressed-color: rgb(94, 94, 94);
68
70
  --tcv-bg-pressed-border-color: #999;
@@ -258,6 +260,7 @@ input[type="radio"] {
258
260
 
259
261
 
260
262
  .tcv_cad_viewer {
263
+ --tcv-ui-row-gap: 8px;
261
264
  margin: 0;
262
265
  display: flex;
263
266
  flex-direction: column;
@@ -292,7 +295,7 @@ input[type="radio"] {
292
295
 
293
296
  .tcv_cad_tree_toggles {
294
297
  text-align: right;
295
- margin-right: 0px;
298
+ padding: 0 4px;
296
299
  margin-bottom: 3px;
297
300
  }
298
301
 
@@ -310,6 +313,7 @@ input[type="radio"] {
310
313
  .tcv_cad_tree_glass {
311
314
  border: none !important;
312
315
  height: fit-content;
316
+ background-color: var(--tcv-bg-overlay-rest-color);
313
317
  }
314
318
 
315
319
  .tcv_cad_tree_glass:hover {
@@ -321,8 +325,6 @@ input[type="radio"] {
321
325
  height: 146px;
322
326
  font-family: sans-serif;
323
327
  font-size: 12px;
324
- border-style: solid;
325
- border-width: 1px;
326
328
  overflow: hidden;
327
329
  user-select:text;
328
330
  }
@@ -353,12 +355,38 @@ input[type="radio"] {
353
355
  font-weight: bold;
354
356
  margin-left: 4px;
355
357
  padding-bottom: 4px;
358
+ }
359
+
360
+ .tcv_toggle_tools {
361
+ vertical-align: middle;
362
+ display: inline-block;
363
+ width: 0.8rem;
364
+ cursor: pointer;
365
+ }
366
+
367
+ .tcv_toggle_tools_wrapper {
368
+ display: none;
369
+ margin-left: 4px;
370
+ cursor: pointer;
371
+ }
372
+
373
+ .tcv_tools_label {
374
+ font-size: 12px;
375
+ font-family: sans-serif;
376
+ font-weight: bold;
377
+ margin-left: 4px;
378
+ padding-bottom: 4px;
356
379
  vertical-align: middle;
357
380
  user-select: none;
358
381
  }
359
382
 
360
383
  .tcv_cad_info_glass {
361
384
  display: none;
385
+ border: none !important;
386
+ background: var(--tcv-bg-overlay-rest-color);
387
+ }
388
+
389
+ .tcv_cad_info_glass:hover {
362
390
  background: var(--tcv-bg-overlay-color);
363
391
  }
364
392
 
@@ -474,7 +502,7 @@ th {
474
502
 
475
503
  .tcv_cad_animation {
476
504
  height: 36px;
477
- background-color: var(--tcv-bg-overlay-color);
505
+ background-color: var(--tcv-bg-overlay-rest-color);
478
506
  border: none;
479
507
  margin: 0;
480
508
  padding: 0px;
@@ -484,9 +512,13 @@ th {
484
512
  z-index: 100;
485
513
  }
486
514
 
515
+ .tcv_cad_animation:hover {
516
+ background-color: var(--tcv-bg-overlay-color);
517
+ }
518
+
487
519
  .tcv_cad_zscale {
488
520
  height: 36px;
489
- background-color: var(--tcv-bg-overlay-color);
521
+ background-color: var(--tcv-bg-overlay-rest-color);
490
522
  border: none;
491
523
  margin: 0;
492
524
  padding: 0px;
@@ -497,6 +529,10 @@ th {
497
529
  align-content: center;
498
530
  }
499
531
 
532
+ .tcv_cad_zscale:hover {
533
+ background-color: var(--tcv-bg-overlay-color);
534
+ }
535
+
500
536
  .tcv_cad_tools {
501
537
  height: 38px;
502
538
  background-color: var(--tcv-bg-overlay-color);
@@ -552,7 +588,7 @@ th {
552
588
  }
553
589
 
554
590
  .tcv_box_content {
555
- overflow: scroll;
591
+ overflow: auto;
556
592
  height: 100%;
557
593
  /* margin: 0px 0px 0px 4px; */
558
594
  padding-top: 2px;
@@ -658,7 +694,10 @@ input[type="button"] {
658
694
  /* margin-bottom: 6px; */
659
695
  background-color: transparent;
660
696
  color: var(--tcv-font-color);
661
- font-size: 14px;
697
+ font-size: 12px;
698
+ overflow: hidden;
699
+ text-overflow: ellipsis;
700
+ white-space: nowrap;
662
701
  }
663
702
 
664
703
  .tcv_tab:hover {
@@ -776,47 +815,60 @@ input[type="button"] {
776
815
  }
777
816
 
778
817
  .tcv_slider_group {
779
- margin-bottom: 10px;
818
+ margin-bottom: var(--tcv-ui-row-gap);
819
+ }
820
+
821
+ .tcv_slider_group > div {
822
+ display: flex;
823
+ align-items: center;
824
+ gap: 4px;
825
+ }
826
+
827
+ .tcv_slider_group > div:first-child {
828
+ align-items: flex-end;
829
+ }
830
+
831
+ .tcv_slider_group .tcv_label {
832
+ margin-bottom: 0;
780
833
  }
781
834
 
782
835
  .tcv_material_ambientlight {
783
836
  margin-top: 4px;
784
837
  }
785
838
 
786
- .tcv_cad_clip_container {
787
- margin-top: 14px;
788
- overflow: hidden;
839
+ .tcv_cad_material_container .tcv_studio_slider_group {
840
+ width: 60%;
789
841
  }
790
842
 
791
- .tcv_cad_material_container {
843
+ .tcv_cad_clip_container,
844
+ .tcv_cad_material_container,
845
+ .tcv_cad_zebra_container,
846
+ .tcv_cad_studio_container {
792
847
  overflow: hidden;
848
+ padding: 0 4px;
793
849
  }
794
850
 
795
- .tcv_cad_zebra_container {
796
- overflow: hidden;
851
+ .tcv_cad_clip_container .tcv_label,
852
+ .tcv_cad_material_container .tcv_label,
853
+ .tcv_cad_zebra_container .tcv_label,
854
+ .tcv_cad_studio_container .tcv_label {
855
+ margin-left: 0;
856
+ margin-right: 0;
797
857
  }
798
858
 
799
- .tcv_zebra_stripe_count {
800
- margin-top: 20px;
801
- }
802
859
 
803
860
  .tcv_zebra_radio {
804
- margin-top: 8px;
805
- margin-bottom: 4px;
861
+ margin-bottom: var(--tcv-ui-row-gap);
806
862
  margin-left: -3px;
807
863
  }
808
864
 
809
- .tcv_zebra_mapping {
810
- margin-top: 8px;
811
- margin-bottom: 4px;
812
- }
813
-
814
865
  .tcv_clip_checks {
815
- margin-top: 20px;
866
+ margin-top: var(--tcv-ui-row-gap);
816
867
  }
817
868
 
818
869
  .tcv_clip_input {
819
- width: 25%;
870
+ width: 36px;
871
+ flex-shrink: 0;
820
872
  border: 1px solid #d3d3d3;
821
873
  background-color: var(--tcv-bg-overlay-color);
822
874
  color: var(--tcv-font-color);
@@ -825,10 +877,11 @@ input[type="button"] {
825
877
  .tcv_clip_slider {
826
878
  -webkit-appearance: none;
827
879
  appearance: none;
828
- width: 60%;
880
+ flex: 1;
881
+ min-width: 0;
829
882
  height: 5px;
830
883
  border-radius: 2px;
831
- background: #d3d3d3;
884
+ background: #a0a0a0;
832
885
  outline: none;
833
886
  opacity: 0.7;
834
887
  -webkit-transition: 0.2s;
@@ -860,7 +913,6 @@ input[type="button"] {
860
913
  }
861
914
 
862
915
  .tcv_lbl_norm_plane1 {
863
- margin-top: 20px;
864
916
  color: var(--tcv-x-color);
865
917
  }
866
918
 
@@ -955,6 +1007,126 @@ input[type="button"] {
955
1007
  font-size: 12px;
956
1008
  }
957
1009
 
1010
+ .tcv_studio_select {
1011
+ font-family: sans-serif;
1012
+ font-size: 13px;
1013
+ padding: 2px 4px;
1014
+ border: 1px solid #d3d3d3;
1015
+ border-radius: 3px;
1016
+ background-color: var(--tcv-bg-overlay-color);
1017
+ color: var(--tcv-font-color);
1018
+ width: 55%;
1019
+ flex-shrink: 0;
1020
+ margin-left: auto;
1021
+ outline: none;
1022
+ }
1023
+
1024
+ .tcv_studio_texture_mapping {
1025
+ width: auto;
1026
+ }
1027
+
1028
+ .tcv_studio_select:hover {
1029
+ opacity: 1;
1030
+ }
1031
+
1032
+ .tcv_studio_select option {
1033
+ background-color: var(--tcv-bg-color);
1034
+ color: var(--tcv-font-color);
1035
+ }
1036
+
1037
+ .tcv_studio_row {
1038
+ display: flex;
1039
+ align-items: center;
1040
+ justify-content: space-between;
1041
+ margin-bottom: var(--tcv-ui-row-gap);
1042
+ }
1043
+
1044
+ .tcv_studio_row > .tcv_label {
1045
+ margin-left: 0;
1046
+ padding-bottom: 0;
1047
+ flex-shrink: 0;
1048
+ }
1049
+
1050
+ .tcv_studio_slider_group {
1051
+ display: flex;
1052
+ align-items: center;
1053
+ width: 55%;
1054
+ flex-shrink: 0;
1055
+ margin-left: auto;
1056
+ gap: 4px;
1057
+ }
1058
+
1059
+ .tcv_studio_slider_group > .tcv_clip_slider {
1060
+ flex: 1;
1061
+ width: auto;
1062
+ min-width: 0;
1063
+ }
1064
+
1065
+ .tcv_studio_slider_group > .tcv_clip_input {
1066
+ width: 36px;
1067
+ flex-shrink: 0;
1068
+ }
1069
+
1070
+ .tcv_studio_checks {
1071
+ display: flex;
1072
+ gap: 16px;
1073
+ margin-top: var(--tcv-ui-row-gap);
1074
+ margin-bottom: var(--tcv-ui-row-gap);
1075
+ }
1076
+
1077
+ .tcv_studio_4k_row {
1078
+ /* Align checkbox with the slider/dropdown column (45% label + 55% control) */
1079
+ margin-left: 45%;
1080
+ gap: 4px;
1081
+ }
1082
+
1083
+ .tcv_studio_group_spacer {
1084
+ height: calc(var(--tcv-ui-row-gap) * 0.6);
1085
+ }
1086
+
1087
+ .tcv_studio_info {
1088
+ font-size: 12px;
1089
+ margin-top: 8px;
1090
+ color: var(--tcv-font-color);
1091
+ opacity: 0.7;
1092
+ font-style: italic;
1093
+ }
1094
+
1095
+ .tcv_warning_banner {
1096
+ position: absolute;
1097
+ top: 4px;
1098
+ left: 50%;
1099
+ transform: translateX(-50%);
1100
+ z-index: 100;
1101
+ background: #e8a735;
1102
+ color: #000;
1103
+ padding: 4px 12px;
1104
+ border-radius: 4px;
1105
+ font-size: 12px;
1106
+ line-height: 1.4;
1107
+ max-width: 80%;
1108
+ text-align: center;
1109
+ pointer-events: auto;
1110
+ box-shadow: 0 1px 4px rgba(0,0,0,0.3);
1111
+ }
1112
+
1113
+ .tcv_studio_spinner {
1114
+ display: none;
1115
+ width: 8px;
1116
+ height: 8px;
1117
+ border: 2px solid var(--tcv-font-color);
1118
+ border-top-color: transparent;
1119
+ border-radius: 50%;
1120
+ animation: tcv_spin 0.7s linear infinite;
1121
+ opacity: 0.6;
1122
+ float: left;
1123
+ margin-top: 5px;
1124
+ }
1125
+
1126
+ @keyframes tcv_spin {
1127
+ to { transform: rotate(360deg); }
1128
+ }
1129
+
958
1130
  .tcv_filter_menu {
959
1131
  position: relative;
960
1132
  }
@@ -1253,4 +1425,142 @@ input[type="button"] {
1253
1425
 
1254
1426
  .tcv_angle_val {
1255
1427
  text-align: right;
1428
+ }
1429
+
1430
+ /* MATERIAL EDITOR PANEL */
1431
+
1432
+ .tcv_mat_editor {
1433
+ position: absolute;
1434
+ top: 8px;
1435
+ right: 8px;
1436
+ width: 250px;
1437
+ max-height: calc(100% - 16px);
1438
+ display: flex;
1439
+ flex-direction: column;
1440
+ background-color: var(--tcv-bg-overlay-rest-color);
1441
+ border: 1px solid lightgray;
1442
+ border-radius: 6px;
1443
+ font-family: sans-serif;
1444
+ font-size: 13px;
1445
+ color: var(--tcv-font-color);
1446
+ user-select: none;
1447
+ z-index: 10;
1448
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1449
+ }
1450
+
1451
+ .tcv_mat_editor:hover {
1452
+ background-color: var(--tcv-bg-overlay-color);
1453
+ }
1454
+
1455
+ .tcv_mat_editor_titlebar {
1456
+ display: flex;
1457
+ align-items: center;
1458
+ justify-content: space-between;
1459
+ padding: 4px 6px;
1460
+ border-bottom: 1px solid lightgray;
1461
+ background-color: var(--tcv-bg-overlay-color);
1462
+ border-radius: 5px 5px 0 0;
1463
+ flex-shrink: 0;
1464
+ cursor: move;
1465
+ }
1466
+
1467
+ .tcv_mat_editor_titlebar_btns {
1468
+ display: flex;
1469
+ gap: 2px;
1470
+ flex-shrink: 0;
1471
+ }
1472
+
1473
+ .tcv_mat_editor_title {
1474
+ font-weight: bold;
1475
+ font-size: 12px;
1476
+ }
1477
+
1478
+ .tcv_mat_editor_close {
1479
+ cursor: pointer;
1480
+ }
1481
+
1482
+ .tcv_mat_editor_path {
1483
+ padding: 3px 6px;
1484
+ font-size: 11px;
1485
+ color: var(--tcv-font-color);
1486
+ opacity: 0.7;
1487
+ border-bottom: 1px solid lightgray;
1488
+ white-space: nowrap;
1489
+ overflow: hidden;
1490
+ text-overflow: ellipsis;
1491
+ flex-shrink: 0;
1492
+ user-select: text;
1493
+ }
1494
+
1495
+ .tcv_mat_editor_content {
1496
+ padding: 6px;
1497
+ overflow-y: auto;
1498
+ flex: 1;
1499
+ min-height: 0;
1500
+ }
1501
+
1502
+ .tcv_mat_editor_section {
1503
+ font-size: 11px;
1504
+ font-weight: bold;
1505
+ text-transform: uppercase;
1506
+ letter-spacing: 0.5px;
1507
+ color: var(--tcv-font-color);
1508
+ opacity: 0.6;
1509
+ margin-top: 8px;
1510
+ margin-bottom: 4px;
1511
+ padding-bottom: 2px;
1512
+ border-bottom: 1px solid var(--tcv-bg-overlay-color);
1513
+ }
1514
+
1515
+ .tcv_mat_editor_section:first-child {
1516
+ margin-top: 0;
1517
+ }
1518
+
1519
+ .tcv_mat_editor_row {
1520
+ display: flex;
1521
+ align-items: center;
1522
+ justify-content: space-between;
1523
+ margin-bottom: 5px;
1524
+ }
1525
+
1526
+ .tcv_mat_editor_label {
1527
+ font-size: 12px;
1528
+ color: var(--tcv-font-color);
1529
+ flex-shrink: 0;
1530
+ max-width: 45%;
1531
+ overflow: hidden;
1532
+ text-overflow: ellipsis;
1533
+ white-space: nowrap;
1534
+ }
1535
+
1536
+ /* Reuse tcv_studio_slider_group layout for slider + value */
1537
+ .tcv_mat_editor_slider_group {
1538
+ display: flex;
1539
+ align-items: center;
1540
+ width: 52%;
1541
+ flex-shrink: 0;
1542
+ margin-left: auto;
1543
+ gap: 4px;
1544
+ }
1545
+
1546
+ /* Sliders reuse tcv_clip_slider class (set in JS) */
1547
+ .tcv_mat_editor_slider_group > .tcv_clip_slider {
1548
+ flex: 1;
1549
+ width: auto;
1550
+ min-width: 0;
1551
+ }
1552
+
1553
+ /* Value inputs reuse tcv_clip_input class (set in JS) */
1554
+ .tcv_mat_editor_slider_group > .tcv_clip_input {
1555
+ width: 36px;
1556
+ flex-shrink: 0;
1557
+ }
1558
+
1559
+ .tcv_mat_editor_changed {
1560
+ color: #cc3333 !important;
1561
+ }
1562
+
1563
+ .tcv_mat_editor_toggle.tcv_active {
1564
+ background-color: var(--tcv-bg-overlay-color);
1565
+ border-radius: 6px;
1256
1566
  }