@visns-studio/visns-components 5.15.4 → 5.15.6

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.
@@ -0,0 +1,1495 @@
1
+ /* Mapbox GL and Mapbox Geocoder styles are imported in the component file */
2
+
3
+ // CSS Custom Properties for theme integration
4
+ :root {
5
+ --camera-primary-color: #3b82f6;
6
+ --camera-primary-hover: #2563eb;
7
+ --camera-success-color: #10b981;
8
+ --camera-success-hover: #059669;
9
+ --camera-warning-color: #f59e0b;
10
+ --camera-warning-hover: #d97706;
11
+ --camera-danger-color: #ef4444;
12
+ --camera-danger-hover: #dc2626;
13
+ --camera-purple-color: #8b5cf6;
14
+ --camera-purple-hover: #7c3aed;
15
+
16
+ --camera-background: #ffffff;
17
+ --camera-surface: #f8fafc;
18
+ --camera-border: #e5e7eb;
19
+ --camera-border-light: #f3f4f6;
20
+
21
+ --camera-text-primary: #1f2937;
22
+ --camera-text-secondary: #6b7280;
23
+ --camera-text-muted: #9ca3af;
24
+
25
+ --camera-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
26
+ --camera-shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.1);
27
+ }
28
+
29
+ .cameraPlacement {
30
+ padding: 0;
31
+ margin: 0;
32
+ height: 100vh;
33
+ display: flex;
34
+ flex-direction: column;
35
+ background: var(--camera-surface, #f8fafc);
36
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
37
+
38
+ .header {
39
+ background: #374151;
40
+ padding: 16px 32px;
41
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
42
+ border-bottom: none;
43
+ z-index: 100;
44
+ position: relative;
45
+
46
+ border-bottom: 1px solid #4b5563;
47
+
48
+ .title {
49
+ font-size: 24px;
50
+ font-weight: 700;
51
+ color: white;
52
+ margin: 0 0 16px 0;
53
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
54
+ letter-spacing: -0.5px;
55
+ }
56
+
57
+ .controls {
58
+ display: flex;
59
+ gap: 16px;
60
+ align-items: center;
61
+ flex-wrap: wrap;
62
+ justify-content: space-between;
63
+
64
+ .leftControls {
65
+ display: flex;
66
+ gap: 16px;
67
+ align-items: center;
68
+ flex: 1;
69
+
70
+ .uploadBtn {
71
+ padding: 8px 16px;
72
+ background: #059669;
73
+ color: white;
74
+ border: none;
75
+ border-radius: 6px;
76
+ cursor: pointer;
77
+ font-weight: 500;
78
+ font-size: 13px;
79
+ transition: all 0.2s ease;
80
+ border: 1px solid #10b981;
81
+
82
+ &:hover:not(:disabled) {
83
+ background: #047857;
84
+ transform: translateY(-1px);
85
+ box-shadow: 0 2px 8px rgba(5, 150, 105, 0.3);
86
+ }
87
+ }
88
+
89
+ .addCameraBtn {
90
+ padding: 8px 16px;
91
+ background: #3b82f6;
92
+ color: white;
93
+ border: none;
94
+ border-radius: 6px;
95
+ cursor: pointer;
96
+ font-weight: 500;
97
+ font-size: 13px;
98
+ transition: all 0.2s ease;
99
+ border: 1px solid #2563eb;
100
+
101
+ &:hover:not(:disabled) {
102
+ background: #2563eb;
103
+ transform: translateY(-1px);
104
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
105
+ }
106
+
107
+ &.activeControl {
108
+ background: #ef4444 !important;
109
+ border-color: #dc2626 !important;
110
+
111
+ &:hover:not(:disabled) {
112
+ background: #dc2626 !important;
113
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.3) !important;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ .rightControls {
120
+ display: flex;
121
+ gap: 12px;
122
+ }
123
+
124
+ .searchContainer {
125
+ position: relative;
126
+ flex: 1;
127
+ max-width: 500px;
128
+ margin-right: 20px;
129
+ }
130
+
131
+ .mapControls {
132
+ display: flex;
133
+ gap: 8px;
134
+ background: rgba(255, 255, 255, 0.9);
135
+ padding: 6px;
136
+ border-radius: 8px;
137
+ border: 1px solid rgba(255, 255, 255, 0.4);
138
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
139
+ }
140
+
141
+ button {
142
+ padding: 8px 16px;
143
+ background: #6b7280;
144
+ color: white;
145
+ border: none;
146
+ border-radius: 6px;
147
+ cursor: pointer;
148
+ font-weight: 500;
149
+ font-size: 13px;
150
+ transition: all 0.2s ease;
151
+ border: 1px solid #9ca3af;
152
+
153
+ &:hover:not(:disabled) {
154
+ background: #4b5563;
155
+ transform: translateY(-1px);
156
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
157
+ }
158
+
159
+ &:disabled {
160
+ background: #9ca3af;
161
+ cursor: not-allowed;
162
+ opacity: 0.6;
163
+ }
164
+
165
+ &.saveFileBtn {
166
+ background: var(--camera-purple-color, #8b5cf6);
167
+ border-color: var(--camera-purple-hover, #7c3aed);
168
+
169
+ &:hover:not(:disabled) {
170
+ background: var(--camera-purple-hover, #7c3aed);
171
+ transform: translateY(-1px);
172
+ box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
173
+ }
174
+ }
175
+
176
+ &.loadFileBtn {
177
+ background: var(--camera-warning-color, #f59e0b);
178
+ border-color: var(--camera-warning-hover, #d97706);
179
+
180
+ &:hover:not(:disabled) {
181
+ background: var(--camera-warning-hover, #d97706);
182
+ transform: translateY(-1px);
183
+ box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
184
+ }
185
+ }
186
+
187
+ &.exportBtn {
188
+ background: var(--camera-success-color, #10b981);
189
+ border-color: var(--camera-success-hover, #059669);
190
+
191
+ &:hover:not(:disabled) {
192
+ background: var(--camera-success-hover, #059669);
193
+ transform: translateY(-1px);
194
+ box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
195
+ }
196
+ }
197
+
198
+ &.activeControl {
199
+ background: var(--camera-primary-color, #3b82f6) !important;
200
+ border-color: var(--camera-primary-hover, #2563eb) !important;
201
+ color: white !important;
202
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
203
+
204
+ &:hover:not(:disabled) {
205
+ background: #2563eb !important;
206
+ box-shadow: 0 3px 12px rgba(59, 130, 246, 0.4) !important;
207
+ }
208
+ }
209
+ }
210
+ }
211
+
212
+ .imageControls {
213
+ display: flex;
214
+ gap: 8px;
215
+ background: rgba(255, 255, 255, 0.9);
216
+ padding: 6px;
217
+ border-radius: 8px;
218
+ border: 1px solid rgba(255, 255, 255, 0.4);
219
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
220
+ margin-right: 16px;
221
+
222
+ button {
223
+ padding: 8px 16px;
224
+ background: #6b7280;
225
+ color: white;
226
+ border: none;
227
+ border-radius: 6px;
228
+ cursor: pointer;
229
+ font-weight: 500;
230
+ font-size: 13px;
231
+ transition: all 0.2s ease;
232
+ border: 1px solid #9ca3af;
233
+
234
+ &:hover:not(:disabled) {
235
+ background: #4b5563;
236
+ transform: translateY(-1px);
237
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
238
+ }
239
+
240
+ &.activeControl {
241
+ background: var(--camera-primary-color, #3b82f6) !important;
242
+ border-color: var(--camera-primary-hover, #2563eb) !important;
243
+ color: white !important;
244
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
245
+
246
+ &:hover:not(:disabled) {
247
+ background: #2563eb !important;
248
+ box-shadow: 0 3px 12px rgba(59, 130, 246, 0.4) !important;
249
+ }
250
+ }
251
+
252
+ &.uploadBtn {
253
+ background: #059669;
254
+ border-color: #10b981;
255
+
256
+ &:hover:not(:disabled) {
257
+ background: #047857;
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
263
+
264
+ .mainContent {
265
+ display: flex;
266
+ flex: 1;
267
+ overflow: hidden;
268
+ gap: 0;
269
+ position: relative;
270
+ }
271
+
272
+ .mapContainer {
273
+ flex: 1;
274
+ position: relative;
275
+ min-height: calc(100vh - 100px);
276
+ height: calc(100vh - 100px);
277
+ width: 100%;
278
+ border-radius: 0;
279
+ overflow: hidden;
280
+
281
+ // Enhanced zoom controls styling for Mapbox GL
282
+ :global(.mapboxgl-ctrl-top-right) {
283
+ top: 20px;
284
+ right: 20px;
285
+
286
+ .mapboxgl-ctrl {
287
+ margin-bottom: 10px;
288
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
289
+ border-radius: 8px;
290
+
291
+ button {
292
+ width: 44px;
293
+ height: 44px;
294
+ font-size: 18px;
295
+ font-weight: bold;
296
+ border-radius: 8px;
297
+ transition: all 0.2s ease;
298
+
299
+ &:hover {
300
+ background-color: #f1f5f9 !important;
301
+ transform: scale(1.05);
302
+ }
303
+
304
+ &:active {
305
+ transform: scale(0.95);
306
+ }
307
+ }
308
+ }
309
+
310
+ .mapboxgl-ctrl-zoom-in {
311
+ border-bottom: 1px solid #e2e8f0;
312
+ }
313
+
314
+ .mapboxgl-ctrl-fullscreen {
315
+ .mapboxgl-ctrl-icon {
316
+ width: 20px;
317
+ height: 20px;
318
+ }
319
+ }
320
+ }
321
+ }
322
+
323
+ .imageContainer {
324
+ flex: 1;
325
+ position: relative;
326
+ min-height: calc(100vh - 100px);
327
+ height: calc(100vh - 100px);
328
+ width: calc(100% - 400px); /* Account for sidebar width */
329
+ background: #f8fafc;
330
+ overflow: hidden;
331
+ cursor: default;
332
+
333
+ &.addMode {
334
+ cursor: crosshair;
335
+ }
336
+
337
+ &.sidebarCollapsed {
338
+ width: 100%; /* Full width when sidebar is collapsed */
339
+ }
340
+
341
+ .imageWrapper {
342
+ position: relative;
343
+ width: 100%;
344
+ height: 100%;
345
+ display: flex;
346
+ align-items: center;
347
+ justify-content: center;
348
+
349
+ .uploadedImage {
350
+ max-width: 100%;
351
+ max-height: 100%;
352
+ object-fit: contain;
353
+ user-select: none;
354
+ pointer-events: none;
355
+ }
356
+ }
357
+
358
+ .uploadPlaceholder {
359
+ display: flex;
360
+ flex-direction: column;
361
+ align-items: center;
362
+ justify-content: center;
363
+ height: 100%;
364
+ color: #64748b;
365
+ text-align: center;
366
+ padding: 40px;
367
+
368
+ .uploadIcon {
369
+ font-size: 64px;
370
+ margin-bottom: 20px;
371
+ opacity: 0.5;
372
+ }
373
+
374
+ h3 {
375
+ margin: 0 0 12px 0;
376
+ font-size: 24px;
377
+ font-weight: 600;
378
+ color: #374151;
379
+ }
380
+
381
+ p {
382
+ margin: 0 0 24px 0;
383
+ font-size: 16px;
384
+ max-width: 400px;
385
+ line-height: 1.5;
386
+ }
387
+
388
+ button {
389
+ padding: 12px 24px;
390
+ background: #3b82f6;
391
+ color: white;
392
+ border: none;
393
+ border-radius: 8px;
394
+ font-size: 16px;
395
+ font-weight: 600;
396
+ cursor: pointer;
397
+ transition: all 0.2s ease;
398
+
399
+ &:hover {
400
+ background: #2563eb;
401
+ transform: translateY(-1px);
402
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
403
+ }
404
+ }
405
+ }
406
+ }
407
+
408
+ .imageMarker {
409
+ z-index: 10;
410
+ pointer-events: none;
411
+
412
+ .imageMarkerContent {
413
+ pointer-events: auto;
414
+ cursor: pointer;
415
+ }
416
+ }
417
+
418
+ .circularMarker {
419
+ width: 40px;
420
+ height: 40px;
421
+ border-radius: 50%;
422
+ background: rgba(107, 114, 128, 0.9);
423
+ color: white;
424
+ display: flex;
425
+ align-items: center;
426
+ justify-content: center;
427
+ font-size: 14px;
428
+ font-weight: 700;
429
+ cursor: pointer;
430
+ border: 3px solid white;
431
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
432
+ transition: all 0.2s ease;
433
+ pointer-events: auto;
434
+
435
+ &:hover {
436
+ transform: scale(1.1);
437
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
438
+ }
439
+
440
+ &.indoor {
441
+ background: rgba(16, 185, 129, 0.9);
442
+ }
443
+
444
+ &.outdoor {
445
+ background: rgba(245, 158, 11, 0.9);
446
+ }
447
+
448
+ &.ptzMarker {
449
+ border-color: #ef4444;
450
+ border-width: 4px;
451
+ }
452
+ }
453
+
454
+ .markerNumber {
455
+ color: white;
456
+ font-size: 14px;
457
+ font-weight: 700;
458
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
459
+ }
460
+
461
+ .rotationHandle {
462
+ position: absolute;
463
+ top: -8px;
464
+ right: -8px;
465
+ width: 16px;
466
+ height: 16px;
467
+ background: #3b82f6;
468
+ border: 2px solid white;
469
+ border-radius: 50%;
470
+ cursor: grab;
471
+ opacity: 0.9;
472
+ display: flex;
473
+ align-items: center;
474
+ justify-content: center;
475
+ transition: all 0.2s ease;
476
+ z-index: 1001; /* Higher than tooltip z-index */
477
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
478
+
479
+ &:hover {
480
+ opacity: 1;
481
+ cursor: grab;
482
+ transform: scale(1.25);
483
+ background: #2563eb;
484
+ box-shadow: 0 3px 10px rgba(59, 130, 246, 0.6);
485
+ }
486
+
487
+ &:active {
488
+ background: #1d4ed8;
489
+ transform: scale(1.1);
490
+ }
491
+
492
+ &::after {
493
+ content: '';
494
+ position: absolute;
495
+ width: 6px;
496
+ height: 6px;
497
+ border: 1px solid white;
498
+ border-left-color: transparent;
499
+ border-radius: 50%;
500
+ animation: spin 2s linear infinite;
501
+ }
502
+ }
503
+
504
+ @keyframes spin {
505
+ 0% { transform: rotate(0deg); }
506
+ 100% { transform: rotate(360deg); }
507
+ }
508
+
509
+ // Ensure rotation handle is clickable and visible
510
+ .imageMarker {
511
+ .rotationHandle {
512
+ pointer-events: auto;
513
+ z-index: 1001; /* Ensure it's always on top */
514
+ }
515
+
516
+ &:hover .rotationHandle {
517
+ opacity: 1;
518
+ transform: scale(1.15);
519
+ background: #2563eb;
520
+ box-shadow: 0 4px 16px rgba(59, 130, 246, 0.5);
521
+ }
522
+
523
+ &.rotating {
524
+ .circularMarker {
525
+ transform: scale(1.1);
526
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
527
+ }
528
+
529
+ .rotationHandle {
530
+ opacity: 1 !important;
531
+ transform: scale(1.3) !important;
532
+ background: #1d4ed8 !important;
533
+ box-shadow: 0 8px 24px rgba(29, 78, 216, 0.6) !important;
534
+ cursor: grabbing !important;
535
+ z-index: 1002 !important; /* Even higher during rotation */
536
+ }
537
+ }
538
+ }
539
+
540
+ // Camera tooltip styles
541
+ .cameraTooltip {
542
+ position: absolute;
543
+ background: white;
544
+ border: 2px solid #e5e7eb;
545
+ border-radius: 12px;
546
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
547
+ padding: 0;
548
+ z-index: 999; /* Lower than rotation handle */
549
+ width: 280px;
550
+ pointer-events: none; /* Ensure tooltip doesn't interfere with clicks */
551
+ opacity: 0;
552
+ animation: fadeInTooltip 0.2s ease forwards;
553
+
554
+ @keyframes fadeInTooltip {
555
+ from {
556
+ opacity: 0;
557
+ transform: translateY(10px);
558
+ }
559
+ to {
560
+ opacity: 1;
561
+ transform: translateY(0);
562
+ }
563
+ }
564
+ }
565
+
566
+ .tooltipImage {
567
+ width: 100%;
568
+ height: 80px;
569
+ overflow: hidden;
570
+ border-radius: 10px 10px 0 0;
571
+ background: #f8fafc;
572
+
573
+ img {
574
+ width: 100%;
575
+ height: 100%;
576
+ object-fit: contain;
577
+ padding: 8px;
578
+ }
579
+ }
580
+
581
+ .tooltipContent {
582
+ padding: 12px 16px;
583
+ }
584
+
585
+ .tooltipTitle {
586
+ font-size: 14px;
587
+ font-weight: 600;
588
+ color: #1f2937;
589
+ margin-bottom: 8px;
590
+ line-height: 1.3;
591
+ }
592
+
593
+ .tooltipSpecs {
594
+ display: flex;
595
+ flex-direction: column;
596
+ gap: 4px;
597
+
598
+ div {
599
+ font-size: 12px;
600
+ color: #6b7280;
601
+ line-height: 1.4;
602
+ }
603
+ }
604
+
605
+ .sidebar {
606
+ position: absolute;
607
+ top: 70px; /* Add top margin to clear navigation */
608
+ right: 0;
609
+ width: 400px;
610
+ height: calc(100% - 70px); /* Adjust height to account for top margin */
611
+ background: var(--camera-background, #ffffff);
612
+ border-left: 1px solid var(--camera-border, #e5e7eb);
613
+ display: flex;
614
+ flex-direction: column;
615
+ z-index: 20;
616
+ box-shadow: -4px 0 16px rgba(0, 0, 0, 0.1);
617
+ transform: translateX(0);
618
+ transition: transform 0.3s ease;
619
+
620
+ &.collapsed {
621
+ transform: translateX(100%);
622
+ }
623
+
624
+ }
625
+
626
+ .sidebarHeader {
627
+ padding: 20px 24px;
628
+ border-bottom: 1px solid #e5e7eb;
629
+ background: #f9fafb;
630
+ position: relative;
631
+ z-index: 1;
632
+
633
+
634
+ .sidebarTitle {
635
+ font-size: 18px;
636
+ font-weight: 700;
637
+ color: #1e293b;
638
+ margin: 0 0 6px 0;
639
+ letter-spacing: -0.3px;
640
+ }
641
+
642
+ .cameraCount {
643
+ font-size: 14px;
644
+ color: #64748b;
645
+ margin: 0;
646
+ font-weight: 500;
647
+ }
648
+ }
649
+
650
+ .camerasList {
651
+ flex: 1;
652
+ overflow-y: auto;
653
+ padding: 20px 24px;
654
+ position: relative;
655
+ z-index: 1;
656
+
657
+ &::-webkit-scrollbar {
658
+ width: 6px;
659
+ }
660
+
661
+ &::-webkit-scrollbar-track {
662
+ background: rgba(0, 0, 0, 0.05);
663
+ border-radius: 3px;
664
+ }
665
+
666
+ &::-webkit-scrollbar-thumb {
667
+ background: #d1d5db;
668
+ border-radius: 3px;
669
+
670
+ &:hover {
671
+ background: #9ca3af;
672
+ }
673
+ }
674
+
675
+ .cameraItem {
676
+ display: flex;
677
+ flex-direction: column;
678
+ padding: 16px;
679
+ background: #ffffff;
680
+ border-radius: 8px;
681
+ margin-bottom: 12px;
682
+ border: 1px solid #e5e7eb;
683
+ transition: all 0.2s ease;
684
+ position: relative;
685
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
686
+
687
+ &::before {
688
+ content: '';
689
+ position: absolute;
690
+ top: 0;
691
+ left: 0;
692
+ right: 0;
693
+ height: 2px;
694
+ background: #6b7280;
695
+ transform: scaleX(0);
696
+ transition: transform 0.2s ease;
697
+ }
698
+
699
+ &:hover {
700
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
701
+ border-color: #d1d5db;
702
+ transform: translateY(-1px);
703
+
704
+ &::before {
705
+ transform: scaleX(1);
706
+ }
707
+ }
708
+
709
+ .cameraHeader {
710
+ display: flex;
711
+ justify-content: space-between;
712
+ align-items: center;
713
+ margin-bottom: 12px;
714
+
715
+ .sidebarCameraInfo {
716
+ display: flex;
717
+ align-items: center;
718
+ gap: 12px;
719
+ flex: 1;
720
+ }
721
+
722
+ .sidebarCameraImageContainer {
723
+ position: relative;
724
+ width: 40px;
725
+ height: 40px;
726
+ flex-shrink: 0;
727
+ }
728
+
729
+ .sidebarCameraImage {
730
+ width: 100%;
731
+ height: 100%;
732
+ object-fit: contain;
733
+ border-radius: 6px;
734
+ background: #f8fafc;
735
+ border: 1px solid #e5e7eb;
736
+ padding: 2px;
737
+ }
738
+
739
+ .sidebarCameraIcon {
740
+ display: flex;
741
+ align-items: center;
742
+ justify-content: center;
743
+ width: 40px;
744
+ height: 40px;
745
+ background: #f3f4f6;
746
+ border-radius: 6px;
747
+ }
748
+
749
+ .sidebarCameraText {
750
+ flex: 1;
751
+ min-width: 0;
752
+ }
753
+
754
+ .cameraName {
755
+ font-size: 18px;
756
+ font-weight: 700;
757
+ color: var(--camera-text-primary, #1e293b);
758
+ margin: 0;
759
+ letter-spacing: -0.2px;
760
+ }
761
+
762
+ .cameraType {
763
+ padding: 6px 12px;
764
+ border-radius: 16px;
765
+ font-size: 11px;
766
+ font-weight: 700;
767
+ text-transform: uppercase;
768
+ letter-spacing: 0.5px;
769
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
770
+
771
+ &.indoor {
772
+ background: #10b981;
773
+ color: white;
774
+ }
775
+
776
+ &.outdoor {
777
+ background: #f59e0b;
778
+ color: white;
779
+ }
780
+ }
781
+ }
782
+ }
783
+ }
784
+ }
785
+
786
+ .indoor {
787
+ background: var(--camera-success-color, #10b981);
788
+ color: white;
789
+ }
790
+
791
+ .outdoor {
792
+ background: var(--camera-warning-color, #f59e0b);
793
+ color: white;
794
+ }
795
+
796
+ .cameraDetails {
797
+ font-size: 14px;
798
+ color: var(--camera-text-secondary, #64748b);
799
+ margin-bottom: 10px;
800
+ line-height: 1.5;
801
+ font-weight: 500;
802
+ }
803
+
804
+ .cameraCoords {
805
+ font-size: 12px;
806
+ color: var(--camera-text-secondary, #6b7280);
807
+ font-family: 'SF Mono', Monaco, 'Consolas', monospace;
808
+ font-weight: 500;
809
+ margin-bottom: 16px;
810
+ background: var(--camera-border-light, #f3f4f6);
811
+ padding: 8px 12px;
812
+ border-radius: 6px;
813
+ border: 1px solid var(--camera-border, #e5e7eb);
814
+ }
815
+
816
+ .cameraActions {
817
+ display: flex;
818
+ gap: 6px;
819
+ align-items: center;
820
+ flex-shrink: 0;
821
+ }
822
+
823
+ .iconBtn {
824
+ display: flex;
825
+ align-items: center;
826
+ justify-content: center;
827
+ width: 32px;
828
+ height: 32px;
829
+ border: none;
830
+ border-radius: 6px;
831
+ background: var(--camera-border-light, #f3f4f6);
832
+ color: var(--camera-text-secondary, #6b7280);
833
+ cursor: pointer;
834
+ transition: all 0.2s ease;
835
+
836
+ &:hover {
837
+ background: var(--camera-border, #e5e7eb);
838
+ color: var(--camera-text-primary, #374151);
839
+ transform: translateY(-1px);
840
+ }
841
+
842
+ &:active {
843
+ transform: translateY(0);
844
+ }
845
+
846
+ &:nth-child(2) { /* Remove button */
847
+ &:hover {
848
+ background: #fee2e2;
849
+ color: var(--camera-danger-hover, #dc2626);
850
+ }
851
+ }
852
+ }
853
+
854
+ .modalOverlay {
855
+ position: fixed;
856
+ top: 0;
857
+ left: 0;
858
+ right: 0;
859
+ bottom: 0;
860
+ background: rgba(0, 0, 0, 0.4);
861
+ display: flex;
862
+ align-items: center;
863
+ justify-content: center;
864
+ z-index: 1000;
865
+ padding: 20px;
866
+ }
867
+
868
+ .modal {
869
+ background: white;
870
+ border-radius: 8px;
871
+ padding: 24px;
872
+ max-width: 500px;
873
+ width: 90%;
874
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
875
+ border: 1px solid #e5e7eb;
876
+
877
+ h3 {
878
+ margin: 0 0 20px 0;
879
+ color: #374151;
880
+ font-size: 18px;
881
+ font-weight: 600;
882
+ text-align: center;
883
+ }
884
+ }
885
+
886
+ .formGroup {
887
+ margin-bottom: 20px;
888
+
889
+ label {
890
+ display: block;
891
+ margin-bottom: 8px;
892
+ font-weight: 500;
893
+ color: #555;
894
+ font-size: 14px;
895
+ }
896
+
897
+ input[type="text"], select {
898
+ width: 100%;
899
+ padding: 10px 12px;
900
+ border: 1px solid #d1d5db;
901
+ border-radius: 6px;
902
+ font-size: 14px;
903
+ transition: border-color 0.2s ease;
904
+ background: #ffffff;
905
+
906
+ &:focus {
907
+ outline: none;
908
+ border-color: #6b7280;
909
+ box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.1);
910
+ }
911
+ }
912
+
913
+ input[type="range"] {
914
+ width: 100%;
915
+ height: 6px;
916
+ border-radius: 3px;
917
+ background: #e5e7eb;
918
+ outline: none;
919
+
920
+ &::-webkit-slider-thumb {
921
+ appearance: none;
922
+ width: 18px;
923
+ height: 18px;
924
+ border-radius: 50%;
925
+ background: #6b7280;
926
+ cursor: pointer;
927
+ }
928
+
929
+ &::-moz-range-thumb {
930
+ width: 18px;
931
+ height: 18px;
932
+ border-radius: 50%;
933
+ background: #6b7280;
934
+ cursor: pointer;
935
+ border: none;
936
+ }
937
+ }
938
+
939
+ input[type="checkbox"] {
940
+ margin-right: 8px;
941
+ transform: scale(1.2);
942
+ }
943
+ }
944
+
945
+ .modalActions {
946
+ display: flex;
947
+ gap: 12px;
948
+ justify-content: flex-end;
949
+ margin-top: 30px;
950
+
951
+ button {
952
+ padding: 10px 20px;
953
+ border: none;
954
+ border-radius: 6px;
955
+ cursor: pointer;
956
+ font-weight: 500;
957
+ transition: all 0.2s ease;
958
+
959
+ &:first-child {
960
+ background: #3b82f6;
961
+ color: white;
962
+
963
+ &:hover {
964
+ background: #2563eb;
965
+ }
966
+ }
967
+
968
+ &:last-child {
969
+ background: #6b7280;
970
+ color: white;
971
+
972
+ &:hover {
973
+ background: #4b5563;
974
+ }
975
+ }
976
+ }
977
+ }
978
+
979
+ // New Camera Selection Modal Styles
980
+ .cameraSelectionModal {
981
+ background: white;
982
+ border-radius: 12px;
983
+ max-width: 1200px;
984
+ width: 90vw;
985
+ max-height: 90vh;
986
+ display: flex;
987
+ flex-direction: column;
988
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
989
+ overflow: hidden;
990
+ }
991
+
992
+ .modalHeader {
993
+ display: flex;
994
+ justify-content: space-between;
995
+ align-items: center;
996
+ padding: 24px 32px;
997
+ border-bottom: 1px solid #e5e7eb;
998
+ background: #f9fafb;
999
+
1000
+ h3 {
1001
+ margin: 0;
1002
+ font-size: 24px;
1003
+ font-weight: 700;
1004
+ color: #111827;
1005
+ }
1006
+
1007
+ .closeBtn {
1008
+ background: none;
1009
+ border: none;
1010
+ font-size: 28px;
1011
+ cursor: pointer;
1012
+ color: #6b7280;
1013
+ transition: color 0.2s ease;
1014
+
1015
+ &:hover {
1016
+ color: #374151;
1017
+ }
1018
+ }
1019
+ }
1020
+
1021
+ .modalContent {
1022
+ flex: 1;
1023
+ display: flex;
1024
+ flex-direction: column;
1025
+ overflow: hidden;
1026
+ }
1027
+
1028
+ .topSection {
1029
+ padding: 24px 32px;
1030
+ border-bottom: 1px solid #e5e7eb;
1031
+ background: white;
1032
+
1033
+ .formGroup {
1034
+ margin-bottom: 20px;
1035
+
1036
+ label {
1037
+ display: block;
1038
+ margin-bottom: 8px;
1039
+ font-weight: 600;
1040
+ color: #374151;
1041
+ font-size: 14px;
1042
+ }
1043
+
1044
+ input {
1045
+ width: 100%;
1046
+ max-width: 400px;
1047
+ padding: 10px 14px;
1048
+ border: 2px solid #e5e7eb;
1049
+ border-radius: 8px;
1050
+ font-size: 14px;
1051
+ transition: border-color 0.2s ease;
1052
+
1053
+ &:focus {
1054
+ outline: none;
1055
+ border-color: #3b82f6;
1056
+ }
1057
+ }
1058
+ }
1059
+ }
1060
+
1061
+ .categoryFilter {
1062
+ label {
1063
+ display: block;
1064
+ margin-bottom: 12px;
1065
+ font-weight: 600;
1066
+ color: #374151;
1067
+ font-size: 14px;
1068
+ }
1069
+ }
1070
+
1071
+ .categoryButtons {
1072
+ display: flex;
1073
+ gap: 8px;
1074
+ flex-wrap: wrap;
1075
+
1076
+ button {
1077
+ padding: 8px 16px;
1078
+ background: #f3f4f6;
1079
+ color: #6b7280;
1080
+ border: 2px solid #e5e7eb;
1081
+ border-radius: 20px;
1082
+ cursor: pointer;
1083
+ font-size: 13px;
1084
+ font-weight: 500;
1085
+ transition: all 0.2s ease;
1086
+
1087
+ &:hover {
1088
+ background: #e5e7eb;
1089
+ color: #374151;
1090
+ }
1091
+
1092
+ &.active {
1093
+ background: #3b82f6;
1094
+ color: white;
1095
+ border-color: #3b82f6;
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ .cameraGrid {
1101
+ flex: 1;
1102
+ padding: 24px 32px;
1103
+ overflow-y: auto;
1104
+ display: grid;
1105
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
1106
+ gap: 20px;
1107
+
1108
+ &::-webkit-scrollbar {
1109
+ width: 8px;
1110
+ }
1111
+
1112
+ &::-webkit-scrollbar-track {
1113
+ background: #f1f5f9;
1114
+ }
1115
+
1116
+ &::-webkit-scrollbar-thumb {
1117
+ background: #cbd5e1;
1118
+ border-radius: 4px;
1119
+
1120
+ &:hover {
1121
+ background: #94a3b8;
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ .cameraCard {
1127
+ background: white;
1128
+ border: 2px solid #e5e7eb;
1129
+ border-radius: 12px;
1130
+ padding: 16px;
1131
+ cursor: pointer;
1132
+ transition: all 0.2s ease;
1133
+ display: flex;
1134
+ flex-direction: column;
1135
+ gap: 12px;
1136
+
1137
+ &:hover {
1138
+ border-color: #cbd5e1;
1139
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1140
+ transform: translateY(-2px);
1141
+ }
1142
+
1143
+ &.selectedCard {
1144
+ border-color: #3b82f6;
1145
+ background: #eff6ff;
1146
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
1147
+
1148
+ &:hover {
1149
+ border-color: #2563eb;
1150
+ }
1151
+ }
1152
+ }
1153
+
1154
+ .cardHeader {
1155
+ display: flex;
1156
+ align-items: flex-start;
1157
+ gap: 12px;
1158
+ }
1159
+
1160
+ .cameraImageContainer {
1161
+ position: relative;
1162
+ width: 60px;
1163
+ height: 60px;
1164
+ flex-shrink: 0;
1165
+ border: 2px solid #10b981;
1166
+ border-radius: 8px;
1167
+ background: #fef3c7;
1168
+ }
1169
+
1170
+ .cameraImage {
1171
+ width: 100%;
1172
+ height: 100%;
1173
+ object-fit: contain;
1174
+ border-radius: 8px;
1175
+ background: #f8fafc;
1176
+ border: 1px solid #e5e7eb;
1177
+ padding: 4px;
1178
+ transition: transform 0.2s ease;
1179
+ }
1180
+
1181
+ .cameraIcon {
1182
+ display: flex;
1183
+ align-items: center;
1184
+ justify-content: center;
1185
+ width: 60px;
1186
+ height: 60px;
1187
+ background: #f3f4f6;
1188
+ border-radius: 8px;
1189
+ flex-shrink: 0;
1190
+ }
1191
+
1192
+ .cameraTitle {
1193
+ flex: 1;
1194
+
1195
+ h4 {
1196
+ margin: 0 0 4px 0;
1197
+ font-size: 16px;
1198
+ font-weight: 600;
1199
+ color: #111827;
1200
+ line-height: 1.2;
1201
+ }
1202
+ }
1203
+
1204
+ .environmentBadge {
1205
+ display: inline-block;
1206
+ padding: 2px 8px;
1207
+ border-radius: 12px;
1208
+ font-size: 11px;
1209
+ font-weight: 600;
1210
+ text-transform: uppercase;
1211
+
1212
+ &.indoor {
1213
+ background: #dcfce7;
1214
+ color: #166534;
1215
+ }
1216
+
1217
+ &.outdoor {
1218
+ background: #fef3c7;
1219
+ color: #92400e;
1220
+ }
1221
+ }
1222
+
1223
+ .cardBody {
1224
+ display: flex;
1225
+ flex-direction: column;
1226
+ gap: 8px;
1227
+ position: relative;
1228
+
1229
+ .ptzBadge {
1230
+ position: absolute;
1231
+ top: -4px;
1232
+ right: 0;
1233
+ background: #ef4444;
1234
+ color: white;
1235
+ padding: 2px 6px;
1236
+ border-radius: 4px;
1237
+ font-size: 10px;
1238
+ font-weight: 700;
1239
+ }
1240
+ }
1241
+
1242
+ .specRow {
1243
+ display: flex;
1244
+ justify-content: space-between;
1245
+ align-items: center;
1246
+ }
1247
+
1248
+ .specLabel {
1249
+ font-size: 13px;
1250
+ color: #6b7280;
1251
+ font-weight: 500;
1252
+ }
1253
+
1254
+ .specValue {
1255
+ font-size: 13px;
1256
+ color: #111827;
1257
+ font-weight: 600;
1258
+ }
1259
+
1260
+ .cardFooter {
1261
+ border-top: 1px solid #f3f4f6;
1262
+ padding-top: 12px;
1263
+ margin-top: 4px;
1264
+ }
1265
+
1266
+ .features {
1267
+ display: flex;
1268
+ flex-wrap: wrap;
1269
+ gap: 4px;
1270
+ align-items: center;
1271
+ }
1272
+
1273
+ .featureBadge {
1274
+ background: #f3f4f6;
1275
+ color: #6b7280;
1276
+ padding: 2px 6px;
1277
+ border-radius: 4px;
1278
+ font-size: 10px;
1279
+ font-weight: 500;
1280
+ }
1281
+
1282
+ .moreFeatures {
1283
+ color: #6b7280;
1284
+ font-size: 11px;
1285
+ font-style: italic;
1286
+ }
1287
+
1288
+ // Updated modal actions for new design
1289
+ .cameraSelectionModal .modalActions {
1290
+ display: flex;
1291
+ justify-content: space-between;
1292
+ align-items: center;
1293
+ padding: 20px 32px;
1294
+ border-top: 1px solid #e5e7eb;
1295
+ background: #f9fafb;
1296
+ margin-top: 0;
1297
+ }
1298
+
1299
+ .selectedInfo {
1300
+ font-size: 14px;
1301
+ color: #6b7280;
1302
+ font-weight: 500;
1303
+ }
1304
+
1305
+ .actionButtons {
1306
+ display: flex;
1307
+ gap: 12px;
1308
+ }
1309
+
1310
+ .cancelBtn {
1311
+ padding: 10px 20px;
1312
+ background: #f3f4f6;
1313
+ color: #6b7280;
1314
+ border: 1px solid #d1d5db;
1315
+ border-radius: 8px;
1316
+ cursor: pointer;
1317
+ font-weight: 500;
1318
+ font-size: 14px;
1319
+ transition: all 0.2s ease;
1320
+
1321
+ &:hover {
1322
+ background: #e5e7eb;
1323
+ color: #374151;
1324
+ }
1325
+ }
1326
+
1327
+ .saveBtn {
1328
+ padding: 10px 24px;
1329
+ background: #3b82f6;
1330
+ color: white;
1331
+ border: none;
1332
+ border-radius: 8px;
1333
+ cursor: pointer;
1334
+ font-weight: 600;
1335
+ font-size: 14px;
1336
+ transition: all 0.2s ease;
1337
+
1338
+ &:hover:not(:disabled) {
1339
+ background: #2563eb;
1340
+ transform: translateY(-1px);
1341
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
1342
+ }
1343
+
1344
+ &:disabled {
1345
+ background: #d1d5db;
1346
+ cursor: not-allowed;
1347
+ transform: none;
1348
+ box-shadow: none;
1349
+ }
1350
+ }
1351
+
1352
+ /* Global styles for map markers and geocoder */
1353
+ :global {
1354
+ .camera-map-marker {
1355
+ background: rgba(0, 0, 0, 0.9);
1356
+ color: white;
1357
+ border-radius: 16px;
1358
+ padding: 6px 12px;
1359
+ font-size: 11px;
1360
+ font-weight: 600;
1361
+ cursor: pointer;
1362
+ white-space: nowrap;
1363
+ border: 2px solid white;
1364
+ transition: all 0.2s ease;
1365
+ min-width: 70px;
1366
+ text-align: center;
1367
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
1368
+
1369
+ &:hover {
1370
+ transform: scale(1.05);
1371
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1372
+ }
1373
+
1374
+ &.indoor {
1375
+ background: rgba(0, 128, 0, 0.95);
1376
+ border-color: #00ff00;
1377
+ }
1378
+
1379
+ &.outdoor {
1380
+ background: rgba(255, 140, 0, 0.95);
1381
+ border-color: #ffa500;
1382
+ }
1383
+
1384
+ &.ptz {
1385
+ border-color: #ff4444;
1386
+ border-width: 3px;
1387
+ }
1388
+ }
1389
+
1390
+ .mapboxgl-popup {
1391
+ z-index: 1001;
1392
+ }
1393
+
1394
+ .mapboxgl-ctrl-geocoder {
1395
+ width: 100% !important;
1396
+ max-width: none !important;
1397
+ border-radius: 12px !important;
1398
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15) !important;
1399
+ backdrop-filter: blur(10px) !important;
1400
+ background: rgba(255, 255, 255, 0.95) !important;
1401
+ min-width: 100% !important;
1402
+
1403
+ .mapboxgl-ctrl-geocoder--input {
1404
+ height: 44px !important;
1405
+ padding: 0 50px 0 20px !important;
1406
+ font-size: 15px !important;
1407
+ border: 2px solid rgba(255, 255, 255, 0.3) !important;
1408
+ border-radius: 12px !important;
1409
+ background: rgba(255, 255, 255, 0.9) !important;
1410
+ color: #1e293b !important;
1411
+ font-weight: 500 !important;
1412
+ backdrop-filter: blur(10px) !important;
1413
+ width: 100% !important;
1414
+
1415
+ &::placeholder {
1416
+ color: #94a3b8 !important;
1417
+ font-weight: 400 !important;
1418
+ }
1419
+
1420
+ &:focus {
1421
+ border-color: #6b7280 !important;
1422
+ box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.1) !important;
1423
+ background: rgba(255, 255, 255, 1) !important;
1424
+ outline: none !important;
1425
+ }
1426
+ }
1427
+
1428
+ .mapboxgl-ctrl-geocoder--button {
1429
+ top: 50% !important;
1430
+ transform: translateY(-50%) !important;
1431
+ right: 12px !important;
1432
+ background: none !important;
1433
+ width: 32px !important;
1434
+ height: 32px !important;
1435
+ border-radius: 8px !important;
1436
+ transition: all 0.2s ease !important;
1437
+
1438
+ &:hover {
1439
+ background: #f3f4f6 !important;
1440
+ }
1441
+
1442
+ .mapboxgl-ctrl-geocoder--icon {
1443
+ fill: #6b7280 !important;
1444
+ width: 18px !important;
1445
+ height: 18px !important;
1446
+ }
1447
+ }
1448
+
1449
+ .suggestions {
1450
+ border-radius: 12px !important;
1451
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15) !important;
1452
+ backdrop-filter: blur(20px) !important;
1453
+ background: rgba(255, 255, 255, 0.95) !important;
1454
+ border: 1px solid rgba(0, 0, 0, 0.1) !important;
1455
+ margin-top: 8px !important;
1456
+ width: 100% !important;
1457
+
1458
+ .suggestion {
1459
+ padding: 12px 20px !important;
1460
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05) !important;
1461
+ font-weight: 500 !important;
1462
+ transition: all 0.2s ease !important;
1463
+
1464
+ &:hover, &.suggestion--selected {
1465
+ background: #f3f4f6 !important;
1466
+ color: #374151 !important;
1467
+ }
1468
+ }
1469
+ }
1470
+ }
1471
+
1472
+ .mapboxgl-ctrl-geocoder.mapboxgl-ctrl-geocoder--collapsed {
1473
+ width: 100% !important;
1474
+ min-width: 100% !important;
1475
+ }
1476
+
1477
+ // Enhanced map controls for Mapbox GL
1478
+ .mapboxgl-ctrl-group {
1479
+ border-radius: 12px !important;
1480
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15) !important;
1481
+ backdrop-filter: blur(10px) !important;
1482
+ background: rgba(255, 255, 255, 0.9) !important;
1483
+ border: 1px solid rgba(255, 255, 255, 0.2) !important;
1484
+
1485
+ button {
1486
+ background: transparent !important;
1487
+ border: none !important;
1488
+ transition: all 0.2s ease !important;
1489
+
1490
+ &:hover {
1491
+ background: #f3f4f6 !important;
1492
+ }
1493
+ }
1494
+ }
1495
+ }