@jaak.ai/stamps 2.0.0-dev.30 → 2.0.0-dev.32

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 (68) hide show
  1. package/dist/cjs/jaak-stamps-webcomponent.cjs.js +1 -1
  2. package/dist/cjs/jaak-stamps.cjs.entry.js +1493 -1254
  3. package/dist/cjs/jaak-stamps.cjs.entry.js.map +1 -1
  4. package/dist/cjs/jaak-stamps.entry.cjs.js.map +1 -1
  5. package/dist/cjs/loader.cjs.js +1 -1
  6. package/dist/collection/components/my-component/my-component.css +325 -126
  7. package/dist/collection/components/my-component/my-component.js +645 -1389
  8. package/dist/collection/components/my-component/my-component.js.map +1 -1
  9. package/dist/collection/services/CameraService.js +292 -0
  10. package/dist/collection/services/CameraService.js.map +1 -0
  11. package/dist/collection/services/DetectionService.js +369 -0
  12. package/dist/collection/services/DetectionService.js.map +1 -0
  13. package/dist/collection/services/EventBusService.js +42 -0
  14. package/dist/collection/services/EventBusService.js.map +1 -0
  15. package/dist/collection/services/LoggerService.js +40 -0
  16. package/dist/collection/services/LoggerService.js.map +1 -0
  17. package/dist/collection/services/ServiceContainer.js +66 -0
  18. package/dist/collection/services/ServiceContainer.js.map +1 -0
  19. package/dist/collection/services/StateManagerService.js +109 -0
  20. package/dist/collection/services/StateManagerService.js.map +1 -0
  21. package/dist/collection/services/factories/DeviceStrategyFactory.js +16 -0
  22. package/dist/collection/services/factories/DeviceStrategyFactory.js.map +1 -0
  23. package/dist/collection/services/interfaces/ICameraService.js +2 -0
  24. package/dist/collection/services/interfaces/ICameraService.js.map +1 -0
  25. package/dist/collection/services/interfaces/IDetectionService.js +2 -0
  26. package/dist/collection/services/interfaces/IDetectionService.js.map +1 -0
  27. package/dist/collection/services/interfaces/IEventBus.js +2 -0
  28. package/dist/collection/services/interfaces/IEventBus.js.map +1 -0
  29. package/dist/collection/services/interfaces/ILogger.js +2 -0
  30. package/dist/collection/services/interfaces/ILogger.js.map +1 -0
  31. package/dist/collection/services/interfaces/IStateManager.js +2 -0
  32. package/dist/collection/services/interfaces/IStateManager.js.map +1 -0
  33. package/dist/collection/services/strategies/HighPerformanceDeviceStrategy.js +30 -0
  34. package/dist/collection/services/strategies/HighPerformanceDeviceStrategy.js.map +1 -0
  35. package/dist/collection/services/strategies/IDeviceStrategy.js +2 -0
  36. package/dist/collection/services/strategies/IDeviceStrategy.js.map +1 -0
  37. package/dist/collection/services/strategies/LowMemoryDeviceStrategy.js +30 -0
  38. package/dist/collection/services/strategies/LowMemoryDeviceStrategy.js.map +1 -0
  39. package/dist/components/jaak-stamps.js +1501 -1275
  40. package/dist/components/jaak-stamps.js.map +1 -1
  41. package/dist/esm/jaak-stamps-webcomponent.js +1 -1
  42. package/dist/esm/jaak-stamps.entry.js +1493 -1254
  43. package/dist/esm/jaak-stamps.entry.js.map +1 -1
  44. package/dist/esm/loader.js +1 -1
  45. package/dist/jaak-stamps-webcomponent/jaak-stamps-webcomponent.esm.js +1 -1
  46. package/dist/jaak-stamps-webcomponent/jaak-stamps.entry.esm.js.map +1 -1
  47. package/dist/jaak-stamps-webcomponent/p-9d1c45a9.entry.js +2 -0
  48. package/dist/jaak-stamps-webcomponent/p-9d1c45a9.entry.js.map +1 -0
  49. package/dist/types/components/my-component/my-component.d.ts +68 -100
  50. package/dist/types/components.d.ts +3 -3
  51. package/dist/types/services/CameraService.d.ts +41 -0
  52. package/dist/types/services/DetectionService.d.ts +35 -0
  53. package/dist/types/services/EventBusService.d.ts +9 -0
  54. package/dist/types/services/LoggerService.d.ts +12 -0
  55. package/dist/types/services/ServiceContainer.d.ts +26 -0
  56. package/dist/types/services/StateManagerService.d.ts +15 -0
  57. package/dist/types/services/factories/DeviceStrategyFactory.d.ts +4 -0
  58. package/dist/types/services/interfaces/ICameraService.d.ts +32 -0
  59. package/dist/types/services/interfaces/IDetectionService.d.ts +31 -0
  60. package/dist/types/services/interfaces/IEventBus.d.ts +16 -0
  61. package/dist/types/services/interfaces/ILogger.d.ts +8 -0
  62. package/dist/types/services/interfaces/IStateManager.d.ts +35 -0
  63. package/dist/types/services/strategies/HighPerformanceDeviceStrategy.d.ts +6 -0
  64. package/dist/types/services/strategies/IDeviceStrategy.d.ts +21 -0
  65. package/dist/types/services/strategies/LowMemoryDeviceStrategy.d.ts +6 -0
  66. package/package.json +3 -3
  67. package/dist/jaak-stamps-webcomponent/p-b62b53f8.entry.js +0 -2
  68. package/dist/jaak-stamps-webcomponent/p-b62b53f8.entry.js.map +0 -1
@@ -5,7 +5,7 @@ var index = require('./index-BfhtOB0D.js');
5
5
  const defineCustomElements = async (win, options) => {
6
6
  if (typeof window === 'undefined') return undefined;
7
7
  await index.globalScripts();
8
- return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"preferredCamera":[1,"preferred-camera"],"isVideoActive":[32],"statusMessage":[32],"statusColor":[32],"bestScore":[32],"capturedFullFrame":[32],"capturedCroppedId":[32],"capturedBackFullFrame":[32],"capturedBackCroppedId":[32],"captureStep":[32],"isCapturing":[32],"showFlipAnimation":[32],"showSuccessAnimation":[32],"shouldMirrorVideo":[32],"sideAlignment":[32],"isDetectionPaused":[32],"isLoading":[32],"isModelPreloaded":[32],"isMaskReady":[32],"availableCameras":[32],"selectedCameraId":[32],"showCameraSelector":[32],"isMultipleCamerasAvailable":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"getStatus":[64],"preloadModel":[64],"skipBackCapture":[64],"getCameraInfo":[64],"setPreferredCamera":[64]}]]]], options);
8
+ return index.bootstrapLazy([["jaak-stamps.cjs",[[1,"jaak-stamps",{"debug":[4],"alignmentTolerance":[2,"alignment-tolerance"],"maskSize":[2,"mask-size"],"cropMargin":[2,"crop-margin"],"useDocumentClassification":[4,"use-document-classification"],"preferredCamera":[1,"preferred-camera"],"detectionBoxes":[32],"sideAlignment":[32],"isMaskReady":[32],"shouldMirrorVideo":[32],"showCameraSelector":[32],"isSwitchingCamera":[32],"currentStatus":[32],"performanceData":[32],"isPerformanceMonitorMinimized":[32],"getCapturedImages":[64],"isProcessCompleted":[64],"startCapture":[64],"stopCapture":[64],"resetCapture":[64],"skipBackCapture":[64],"getStatus":[64],"preloadModel":[64],"getCameraInfo":[64],"setPreferredCamera":[64]}]]]], options);
9
9
  };
10
10
 
11
11
  exports.setNonce = index.setNonce;
@@ -31,25 +31,31 @@ h1 {
31
31
  overflow: hidden;
32
32
  }
33
33
 
34
- video, canvas {
34
+ video, .detection-overlay {
35
35
  position: absolute;
36
36
  width: 100%;
37
37
  height: 100%;
38
38
  border-radius: 8px;
39
39
  }
40
40
 
41
- video.mirror, canvas.mirror {
41
+ video.mirror, .detection-overlay.mirror {
42
42
  transform: rotateY(180deg);
43
43
  }
44
44
 
45
- canvas {
45
+ .detection-overlay {
46
46
  z-index: 1;
47
+ pointer-events: none;
47
48
  }
48
49
 
49
50
  video {
50
51
  z-index: 0;
51
52
  }
52
53
 
54
+ /* Detection boxes for debug mode */
55
+ .detection-box {
56
+ transition: opacity 0.2s ease;
57
+ }
58
+
53
59
 
54
60
  .status {
55
61
  margin-top: 16px;
@@ -79,12 +85,10 @@ video {
79
85
  border: none;
80
86
  border-radius: 4px;
81
87
  background: transparent;
82
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
83
88
  opacity: 0.8;
84
89
  }
85
90
 
86
91
  .card-outline.perfect-match {
87
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
88
92
  }
89
93
 
90
94
  /* Lados individuales de la máscara */
@@ -92,79 +96,74 @@ video {
92
96
  position: absolute;
93
97
  background: #999;
94
98
  transition: background-color 0.3s ease;
99
+ border-radius: 1px;
100
+ }
101
+
102
+ .side-top.aligned {
103
+ border-left-color: #28a745;
104
+ border-top-color: #28a745;
105
+ }
106
+
107
+ .side-right.aligned {
108
+ border-right-color: #28a745;
109
+ border-top-color: #28a745;
110
+ }
111
+
112
+ .side-bottom.aligned {
113
+ border-left-color: #28a745;
114
+ border-bottom-color: #28a745;
95
115
  }
96
116
 
97
- .side.aligned {
98
- background: #28a745;
117
+ .side-left.aligned {
118
+ border-right-color: #28a745;
119
+ border-bottom-color: #28a745;
99
120
  }
100
121
 
101
122
  .side-top {
102
- top: 0;
103
- left: 0;
104
- width: 100%;
105
- height: 3px;
123
+ top: -3px;
124
+ left: -3px;
125
+ width: 30px;
126
+ height: 30px;
127
+ border-left: 6px solid #ffffff;
128
+ border-top: 6px solid #ffffff;
129
+ background: transparent;
106
130
  }
107
131
 
108
132
  .side-right {
109
- top: 0;
110
- right: 0;
111
- width: 3px;
112
- height: 100%;
133
+ top: -3px;
134
+ right: -3px;
135
+ width: 30px;
136
+ height: 30px;
137
+ border-right: 6px solid #ffffff;
138
+ border-top: 6px solid #ffffff;
139
+ background: transparent;
113
140
  }
114
141
 
115
142
  .side-bottom {
116
- bottom: 0;
117
- left: 0;
118
- width: 100%;
119
- height: 3px;
143
+ bottom: -3px;
144
+ left: -3px;
145
+ width: 30px;
146
+ height: 30px;
147
+ border-left: 6px solid #ffffff;
148
+ border-bottom: 6px solid #ffffff;
149
+ background: transparent;
120
150
  }
121
151
 
122
152
  .side-left {
123
- top: 0;
124
- left: 0;
125
- width: 3px;
126
- height: 100%;
153
+ bottom: -3px;
154
+ right: -3px;
155
+ width: 30px;
156
+ height: 30px;
157
+ border-right: 6px solid #ffffff;
158
+ border-bottom: 6px solid #ffffff;
159
+ background: transparent;
127
160
  }
128
161
 
129
- .corner {
130
- position: absolute;
131
- width: 20px;
132
- height: 20px;
133
- border: 2px solid #999;
134
- z-index: 12;
135
- }
136
162
 
137
- .corner-tl {
138
- top: -10px;
139
- left: -10px;
140
- border-right: none;
141
- border-bottom: none;
142
- }
143
163
 
144
- .corner-tr {
145
- top: -10px;
146
- right: -10px;
147
- border-left: none;
148
- border-bottom: none;
149
- }
150
164
 
151
- .corner-bl {
152
- bottom: -10px;
153
- left: -10px;
154
- border-right: none;
155
- border-top: none;
156
- }
157
165
 
158
- .corner-br {
159
- bottom: -10px;
160
- right: -10px;
161
- border-left: none;
162
- border-top: none;
163
- }
164
166
 
165
- .corner.perfect-match {
166
- border-color: #28a745;
167
- }
168
167
 
169
168
  .guide-text {
170
169
  position: absolute;
@@ -227,15 +226,15 @@ video {
227
226
  @keyframes pulseGreen {
228
227
  0% {
229
228
  border-color: #28a745;
230
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7), 0 0 0 4px rgba(40, 167, 69, 0);
229
+ box-shadow: 0 0 0 4px rgba(40, 167, 69, 0);
231
230
  }
232
231
  50% {
233
232
  border-color: #28a745;
234
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7), 0 0 0 8px rgba(40, 167, 69, 0.6);
233
+ box-shadow: 0 0 0 8px rgba(40, 167, 69, 0.6);
235
234
  }
236
235
  100% {
237
236
  border-color: #28a745;
238
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7), 0 0 0 4px rgba(40, 167, 69, 0);
237
+ box-shadow: 0 0 0 4px rgba(40, 167, 69, 0);
239
238
  }
240
239
  }
241
240
 
@@ -481,32 +480,13 @@ video {
481
480
  pointer-events: auto;
482
481
  }
483
482
 
484
- .flip-camera-button {
485
- height: 40px;
486
- padding: 0 16px;
487
- border: none;
488
- border-radius: 8px;
489
- background: rgba(0, 0, 0, 0.6);
490
- backdrop-filter: blur(12px);
491
- color: #ffffff;
492
- font-size: 12px;
493
- font-weight: 500;
494
- cursor: pointer;
495
- transition: all 0.2s ease;
496
- display: flex;
497
- align-items: center;
498
- justify-content: center;
499
- border: 1px solid rgba(255, 255, 255, 0.1);
500
- white-space: nowrap;
501
- min-width: fit-content;
502
- }
503
483
 
504
484
  .camera-selector-button {
505
- height: 40px;
506
- padding: 0 16px;
485
+ height: 32px;
486
+ padding: 0 10px;
507
487
  border: none;
508
488
  border-radius: 8px;
509
- background: rgba(0, 0, 0, 0.6);
489
+ background: rgba(0, 0, 0, 0.25);
510
490
  backdrop-filter: blur(12px);
511
491
  color: #ffffff;
512
492
  font-size: 12px;
@@ -521,26 +501,52 @@ video {
521
501
  min-width: fit-content;
522
502
  }
523
503
 
524
- .flip-camera-button:hover,
525
504
  .camera-selector-button:hover {
526
505
  background: rgba(0, 0, 0, 0.8);
527
506
  border-color: rgba(255, 255, 255, 0.2);
528
507
  transform: translateY(-1px);
529
508
  }
530
509
 
531
- .flip-camera-button:active,
532
510
  .camera-selector-button:active {
533
511
  transform: translateY(0);
534
512
  background: rgba(0, 0, 0, 0.9);
535
513
  }
536
514
 
515
+ .camera-selector-button:disabled,
516
+ .camera-selector-button.loading {
517
+ opacity: 0.7;
518
+ cursor: not-allowed;
519
+ pointer-events: none;
520
+ }
521
+
522
+ .camera-selector-button:disabled:hover,
523
+ .camera-selector-button.loading:hover {
524
+ transform: none;
525
+ background: rgba(0, 0, 0, 0.6);
526
+ border-color: rgba(255, 255, 255, 0.1);
527
+ }
528
+
529
+ .button-spinner {
530
+ width: 16px;
531
+ height: 16px;
532
+ border: 2px solid rgba(255, 255, 255, 0.3);
533
+ border-top: 2px solid #ffffff;
534
+ border-radius: 50%;
535
+ animation: spin 1s linear infinite;
536
+ }
537
+
538
+ @keyframes spin {
539
+ 0% { transform: rotate(0deg); }
540
+ 100% { transform: rotate(360deg); }
541
+ }
542
+
537
543
  /* Camera selector dropdown */
538
544
  .camera-selector-dropdown {
539
545
  position: absolute;
540
546
  top: 56px;
541
547
  right: 16px;
542
548
  z-index: 30;
543
- background: rgba(0, 0, 0, 0.85);
549
+ background: rgba(0, 0, 0, 0.25);
544
550
  backdrop-filter: blur(20px);
545
551
  border-radius: 12px;
546
552
  min-width: 260px;
@@ -566,7 +572,7 @@ video {
566
572
  display: flex;
567
573
  justify-content: space-between;
568
574
  align-items: center;
569
- padding: 12px 16px;
575
+ padding: 8px 12px;
570
576
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
571
577
  }
572
578
 
@@ -605,7 +611,7 @@ video {
605
611
 
606
612
  .camera-option {
607
613
  width: 100%;
608
- padding: 10px 16px;
614
+ padding: 8px 12px;
609
615
  border: none;
610
616
  background: none;
611
617
  text-align: left;
@@ -643,7 +649,7 @@ video {
643
649
  }
644
650
 
645
651
  .device-info {
646
- padding: 8px 16px;
652
+ padding: 6px 12px;
647
653
  border-top: 1px solid rgba(255, 255, 255, 0.1);
648
654
  background: rgba(255, 255, 255, 0.05);
649
655
  }
@@ -663,13 +669,6 @@ video {
663
669
  gap: 6px;
664
670
  }
665
671
 
666
- .flip-camera-button {
667
- height: 36px;
668
- padding: 0 12px;
669
- font-size: 11px;
670
- border-radius: 6px;
671
- }
672
-
673
672
  .camera-selector-button {
674
673
  height: 36px;
675
674
  padding: 0 12px;
@@ -685,15 +684,15 @@ video {
685
684
  }
686
685
 
687
686
  .camera-selector-header {
688
- padding: 10px 14px;
687
+ padding: 6px 10px;
689
688
  }
690
689
 
691
690
  .camera-option {
692
- padding: 8px 14px;
691
+ padding: 6px 10px;
693
692
  }
694
693
 
695
694
  .device-info {
696
- padding: 6px 14px;
695
+ padding: 4px 10px;
697
696
  }
698
697
  }
699
698
 
@@ -713,38 +712,131 @@ video {
713
712
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
714
713
  }
715
714
 
716
- /* Animación de carga */
715
+ /* Estado siempre visible del componente */
716
+ .component-status {
717
+ position: absolute;
718
+ top: 16px;
719
+ left: 16px;
720
+ background: rgba(0, 0, 0, 0.25);
721
+ backdrop-filter: blur(20px);
722
+ border-radius: 12px;
723
+ border: 1px solid rgba(255, 255, 255, 0.1);
724
+ display: flex;
725
+ align-items: center;
726
+ gap: 6px;
727
+ padding: 6px 10px;
728
+ z-index: 40;
729
+ height: 32px;
730
+ width: fit-content;
731
+ animation: slideInFromTop 0.3s ease-out;
732
+ }
733
+
734
+
735
+ .status-spinner {
736
+ width: 16px;
737
+ height: 16px;
738
+ border: 1px solid rgba(255, 255, 255, 0.3);
739
+ border-top: 1px solid #ffffff;
740
+ border-radius: 50%;
741
+ animation: statusSpin 1s linear infinite;
742
+ flex-shrink: 0;
743
+ }
744
+
745
+ .status-content {
746
+ display: flex;
747
+ flex-direction: column;
748
+ gap: 1px;
749
+ }
750
+
751
+ .status-message {
752
+ color: #ffffff;
753
+ font-size: 12px;
754
+ font-weight: 500;
755
+ margin: 0;
756
+ }
757
+
758
+ .status-description {
759
+ color: rgba(255, 255, 255, 0.7);
760
+ font-size: 10px;
761
+ line-height: 1.2;
762
+ margin: 0;
763
+ }
764
+
765
+ @keyframes statusSpin {
766
+ 0% {
767
+ transform: rotate(0deg);
768
+ }
769
+ 100% {
770
+ transform: rotate(360deg);
771
+ }
772
+ }
773
+
774
+ /* Responsive para estado en móviles */
775
+ @media (max-width: 480px) {
776
+ .component-status {
777
+ top: 12px;
778
+ left: 12px;
779
+ padding: 4px 8px;
780
+ gap: 4px;
781
+ height: 28px;
782
+ border-radius: 8px;
783
+ }
784
+
785
+ .status-spinner {
786
+ width: 14px;
787
+ height: 14px;
788
+ }
789
+
790
+ .status-message {
791
+ font-size: 11px;
792
+ }
793
+
794
+ .status-description {
795
+ font-size: 9px;
796
+ }
797
+ }
798
+
799
+ /* Animación de carga mejorada */
717
800
  .loading-overlay {
718
801
  position: absolute;
719
802
  top: 0;
720
803
  left: 0;
721
804
  width: 100%;
722
805
  height: 100%;
723
- background: rgba(0, 0, 0, 0.8);
806
+ background: rgba(0, 0, 0, 0.85);
807
+ backdrop-filter: blur(4px);
724
808
  display: flex;
725
809
  flex-direction: column;
726
810
  align-items: center;
727
811
  justify-content: center;
728
812
  z-index: 30;
729
- border-radius: 20px;
813
+ border-radius: 8px;
730
814
  }
731
815
 
732
816
  .loading-spinner {
733
- width: 60px;
734
- height: 60px;
735
- border: 4px solid rgba(255, 255, 255, 0.2);
736
- border-top: 4px solid #007bff;
817
+ width: 50px;
818
+ height: 50px;
819
+ border: 3px solid rgba(255, 255, 255, 0.15);
820
+ border-top: 3px solid #28a745;
737
821
  border-radius: 50%;
738
- animation: spin 1s linear infinite;
739
- margin-bottom: 20px;
822
+ animation: spin 1s ease-in-out infinite;
823
+ margin-bottom: 16px;
740
824
  }
741
825
 
742
826
  .loading-text {
743
- color: white;
744
- font-size: 16px;
827
+ color: #ffffff;
828
+ font-size: 14px;
745
829
  font-weight: 500;
746
830
  text-align: center;
747
831
  opacity: 0.9;
832
+ margin-bottom: 4px;
833
+ }
834
+
835
+ .loading-description {
836
+ color: rgba(255, 255, 255, 0.7);
837
+ font-size: 12px;
838
+ text-align: center;
839
+ opacity: 0.8;
748
840
  }
749
841
 
750
842
  @keyframes spin {
@@ -756,27 +848,134 @@ video {
756
848
  }
757
849
  }
758
850
 
759
- /* Status bar always visible */
760
- .status-bar {
851
+ /* Monitor de Performance - Diseño compacto y minimalista */
852
+ .performance-monitor {
761
853
  position: absolute;
762
- bottom: 10px;
763
- left: 50%;
764
- transform: translateX(-50%);
765
- background: rgba(0, 0, 0, 0.7);
766
- border-radius: 15px;
767
- padding: 8px 16px;
768
- z-index: 40;
769
- backdrop-filter: blur(5px);
854
+ top: 70px;
855
+ left: 16px;
856
+ background: rgba(0, 0, 0, 0.25);
857
+ backdrop-filter: blur(20px);
858
+ border-radius: 12px;
770
859
  border: 1px solid rgba(255, 255, 255, 0.1);
860
+ z-index: 35;
861
+ width: fit-content;
862
+ animation: slideInFromLeft 0.3s ease-out;
863
+ transition: all 0.3s ease;
771
864
  }
772
865
 
773
- .status-message {
774
- font-size: 12px;
866
+ @keyframes slideInFromLeft {
867
+ 0% {
868
+ opacity: 0;
869
+ transform: translateX(-20px) scale(0.95);
870
+ }
871
+ 100% {
872
+ opacity: 1;
873
+ transform: translateX(0) scale(1);
874
+ }
875
+ }
876
+
877
+
878
+ .performance-expanded {
879
+ padding: 6px 10px;
880
+ }
881
+
882
+ .metrics-row {
883
+ display: flex;
884
+ gap: 8px;
885
+ margin-bottom: 4px;
886
+ }
887
+
888
+ .metrics-row:last-child {
889
+ margin-bottom: 0;
890
+ }
891
+
892
+ .metric-compact {
893
+ display: flex;
894
+ flex-direction: column;
895
+ align-items: center;
896
+ gap: 2px;
897
+ min-width: 50px;
898
+ }
899
+
900
+ .metric-label {
901
+ font-size: 9px;
902
+ color: rgba(255, 255, 255, 0.6);
775
903
  font-weight: 500;
904
+ text-transform: uppercase;
905
+ letter-spacing: 0.3px;
906
+ }
907
+
908
+ .metric-value {
909
+ font-size: 10px;
910
+ font-weight: 600;
911
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
912
+ padding: 2px 4px;
913
+ border-radius: 3px;
776
914
  text-align: center;
777
- color: #fff;
778
915
  white-space: nowrap;
779
- max-width: 280px;
780
- overflow: hidden;
781
- text-overflow: ellipsis;
782
- }
916
+ }
917
+
918
+ .metric-value.good {
919
+ color: #4ade80;
920
+ background: rgba(74, 222, 128, 0.1);
921
+ border: 1px solid rgba(74, 222, 128, 0.2);
922
+ }
923
+
924
+ .metric-value.warning {
925
+ color: #fbbf24;
926
+ background: rgba(251, 191, 36, 0.1);
927
+ border: 1px solid rgba(251, 191, 36, 0.2);
928
+ }
929
+
930
+ .metric-value.danger {
931
+ color: #f87171;
932
+ background: rgba(248, 113, 113, 0.1);
933
+ border: 1px solid rgba(248, 113, 113, 0.2);
934
+ }
935
+
936
+ /* Responsive para monitor de performance */
937
+ @media (max-width: 480px) {
938
+ .performance-monitor {
939
+ top: 60px;
940
+ left: 12px;
941
+ width: fit-content;
942
+ }
943
+
944
+ .performance-expanded {
945
+ padding: 4px 8px;
946
+ }
947
+
948
+ .metrics-row {
949
+ gap: 6px;
950
+ margin-bottom: 3px;
951
+ }
952
+
953
+ .metric-compact {
954
+ min-width: 45px;
955
+ gap: 1px;
956
+ }
957
+
958
+ .metric-label {
959
+ font-size: 8px;
960
+ }
961
+
962
+ .metric-value {
963
+ font-size: 9px;
964
+ padding: 1px 3px;
965
+ }
966
+ }
967
+
968
+ /* Animación pulsante para valores críticos */
969
+ @keyframes pulse {
970
+ 0%, 100% {
971
+ opacity: 1;
972
+ }
973
+ 50% {
974
+ opacity: 0.7;
975
+ }
976
+ }
977
+
978
+ .metric-value.danger {
979
+ animation: pulse 2s infinite;
980
+ }
981
+