@frameset/plex-player 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.
@@ -0,0 +1,1943 @@
1
+ /* =====================================================
2
+ PLEX Video Player - Main Styles
3
+ ===================================================== */
4
+
5
+ /* CSS Variables */
6
+ :root {
7
+ --plex-primary: #e5a00d;
8
+ --plex-primary-hover: #f5b82e;
9
+ --plex-bg-dark: #1a1a1a;
10
+ --plex-bg-darker: #0d0d0d;
11
+ --plex-bg-overlay: rgba(0, 0, 0, 0.85);
12
+ --plex-text-primary: #ffffff;
13
+ --plex-text-secondary: #a0a0a0;
14
+ --plex-border: rgba(255, 255, 255, 0.1);
15
+ --plex-gradient: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 100%);
16
+ --plex-gradient-top: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, transparent 100%);
17
+ --plex-transition-fast: 0.15s ease;
18
+ --plex-transition-normal: 0.25s ease;
19
+ --plex-transition-slow: 0.4s ease;
20
+ --plex-radius-sm: 4px;
21
+ --plex-radius-md: 8px;
22
+ --plex-radius-lg: 12px;
23
+ --plex-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
24
+ --plex-z-video: 1;
25
+ --plex-z-overlay: 10;
26
+ --plex-z-controls: 20;
27
+ --plex-z-panel: 30;
28
+ --plex-z-modal: 40;
29
+ --plex-z-toast: 50;
30
+ }
31
+
32
+ /* Reset & Base */
33
+ *, *::before, *::after {
34
+ box-sizing: border-box;
35
+ margin: 0;
36
+ padding: 0;
37
+ }
38
+
39
+ html, body {
40
+ width: 100%;
41
+ height: 100%;
42
+ background: var(--plex-bg-darker);
43
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
44
+ color: var(--plex-text-primary);
45
+ overflow: hidden;
46
+ -webkit-font-smoothing: antialiased;
47
+ -moz-osx-font-smoothing: grayscale;
48
+ }
49
+
50
+ /* Player Container */
51
+ .plex-player {
52
+ position: relative;
53
+ width: 100%;
54
+ height: 100%;
55
+ background: var(--plex-bg-darker);
56
+ overflow: hidden;
57
+ user-select: none;
58
+ -webkit-user-select: none;
59
+ -webkit-tap-highlight-color: transparent;
60
+ }
61
+
62
+ .plex-player.fullscreen {
63
+ position: fixed;
64
+ top: 0;
65
+ left: 0;
66
+ width: 100vw;
67
+ height: 100vh;
68
+ z-index: 9999;
69
+ }
70
+
71
+ /* Video Container */
72
+ .video-container {
73
+ position: relative;
74
+ width: 100%;
75
+ height: 100%;
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ background: #000;
80
+ z-index: var(--plex-z-video);
81
+ }
82
+
83
+ .video-container video {
84
+ width: 100%;
85
+ height: 100%;
86
+ max-width: 100%;
87
+ max-height: 100%;
88
+ object-fit: contain;
89
+ background: #000;
90
+ }
91
+
92
+ /* Controls Visibility */
93
+ .plex-player.controls-visible .top-controls,
94
+ .plex-player.controls-visible .bottom-controls {
95
+ opacity: 1;
96
+ visibility: visible;
97
+ transform: translateY(0);
98
+ }
99
+
100
+ .plex-player:not(.controls-visible) .top-controls,
101
+ .plex-player:not(.controls-visible) .bottom-controls {
102
+ opacity: 0;
103
+ visibility: hidden;
104
+ }
105
+
106
+ .plex-player:not(.controls-visible) .top-controls {
107
+ transform: translateY(-100%);
108
+ }
109
+
110
+ .plex-player:not(.controls-visible) .bottom-controls {
111
+ transform: translateY(100%);
112
+ }
113
+
114
+ /* Cursor hiding */
115
+ .plex-player.hide-cursor {
116
+ cursor: none;
117
+ }
118
+
119
+ .plex-player.hide-cursor video {
120
+ cursor: none;
121
+ }
122
+
123
+ /* Loading Spinner */
124
+ .loading-spinner {
125
+ position: absolute;
126
+ top: 50%;
127
+ left: 50%;
128
+ transform: translate(-50%, -50%);
129
+ z-index: var(--plex-z-overlay);
130
+ }
131
+
132
+ .loading-spinner .spinner {
133
+ width: 60px;
134
+ height: 60px;
135
+ border: 4px solid rgba(255, 255, 255, 0.2);
136
+ border-top-color: var(--plex-primary);
137
+ border-radius: 50%;
138
+ animation: spin 1s linear infinite;
139
+ }
140
+
141
+ @keyframes spin {
142
+ to {
143
+ transform: rotate(360deg);
144
+ }
145
+ }
146
+
147
+ /* Big Play Button */
148
+ .big-play-btn {
149
+ position: absolute;
150
+ top: 50%;
151
+ left: 50%;
152
+ transform: translate(-50%, -50%) scale(1);
153
+ width: 80px;
154
+ height: 80px;
155
+ background: var(--plex-primary);
156
+ border-radius: 50%;
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ cursor: pointer;
161
+ z-index: var(--plex-z-overlay);
162
+ transition: all var(--plex-transition-normal);
163
+ box-shadow: 0 4px 30px rgba(229, 160, 13, 0.4);
164
+ }
165
+
166
+ .big-play-btn:hover {
167
+ transform: translate(-50%, -50%) scale(1.1);
168
+ background: var(--plex-primary-hover);
169
+ }
170
+
171
+ .big-play-btn .material-icons {
172
+ font-size: 48px;
173
+ color: #000;
174
+ margin-left: 4px;
175
+ }
176
+
177
+ .big-play-btn.hidden {
178
+ opacity: 0;
179
+ visibility: hidden;
180
+ transform: translate(-50%, -50%) scale(0.8);
181
+ }
182
+
183
+ /* Gesture Overlay */
184
+ .gesture-overlay {
185
+ position: absolute;
186
+ top: 0;
187
+ left: 0;
188
+ width: 100%;
189
+ height: 100%;
190
+ display: flex;
191
+ z-index: var(--plex-z-overlay);
192
+ pointer-events: none;
193
+ }
194
+
195
+ .gesture-left,
196
+ .gesture-right {
197
+ flex: 1;
198
+ display: flex;
199
+ align-items: center;
200
+ justify-content: center;
201
+ }
202
+
203
+ .gesture-center {
204
+ flex: 1;
205
+ }
206
+
207
+ .gesture-indicator {
208
+ display: flex;
209
+ flex-direction: column;
210
+ align-items: center;
211
+ gap: 8px;
212
+ padding: 20px;
213
+ background: rgba(0, 0, 0, 0.7);
214
+ border-radius: var(--plex-radius-lg);
215
+ opacity: 0;
216
+ transform: scale(0.8);
217
+ transition: all var(--plex-transition-fast);
218
+ }
219
+
220
+ .gesture-indicator.active {
221
+ opacity: 1;
222
+ transform: scale(1);
223
+ }
224
+
225
+ .gesture-indicator .material-icons {
226
+ font-size: 48px;
227
+ color: var(--plex-text-primary);
228
+ }
229
+
230
+ .gesture-indicator .gesture-text {
231
+ font-size: 14px;
232
+ font-weight: 600;
233
+ color: var(--plex-text-primary);
234
+ }
235
+
236
+ /* Volume/Brightness Indicators */
237
+ .volume-indicator,
238
+ .brightness-indicator {
239
+ position: absolute;
240
+ top: 50%;
241
+ left: 50%;
242
+ transform: translate(-50%, -50%);
243
+ display: flex;
244
+ flex-direction: column;
245
+ align-items: center;
246
+ gap: 12px;
247
+ padding: 24px;
248
+ background: rgba(0, 0, 0, 0.8);
249
+ border-radius: var(--plex-radius-lg);
250
+ z-index: var(--plex-z-overlay);
251
+ transition: opacity var(--plex-transition-fast);
252
+ }
253
+
254
+ .volume-indicator .material-icons,
255
+ .brightness-indicator .material-icons {
256
+ font-size: 36px;
257
+ color: var(--plex-text-primary);
258
+ }
259
+
260
+ .volume-indicator-bar,
261
+ .brightness-indicator-bar {
262
+ width: 120px;
263
+ height: 4px;
264
+ background: rgba(255, 255, 255, 0.2);
265
+ border-radius: 2px;
266
+ overflow: hidden;
267
+ }
268
+
269
+ .volume-indicator-fill,
270
+ .brightness-indicator-fill {
271
+ height: 100%;
272
+ background: var(--plex-primary);
273
+ border-radius: 2px;
274
+ transition: width var(--plex-transition-fast);
275
+ }
276
+
277
+ /* Subtitles Container */
278
+ .subtitles-container {
279
+ position: absolute;
280
+ bottom: 80px;
281
+ left: 50%;
282
+ transform: translateX(-50%);
283
+ width: 80%;
284
+ max-width: 800px;
285
+ text-align: center;
286
+ z-index: var(--plex-z-overlay);
287
+ pointer-events: none;
288
+ }
289
+
290
+ .subtitle-line {
291
+ display: inline-block;
292
+ padding: 8px 16px;
293
+ margin: 4px 0;
294
+ background: rgba(0, 0, 0, 0.75);
295
+ border-radius: var(--plex-radius-sm);
296
+ font-size: 24px;
297
+ line-height: 1.4;
298
+ color: #fff;
299
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
300
+ }
301
+
302
+ /* Cast Overlay */
303
+ .cast-overlay {
304
+ position: absolute;
305
+ top: 0;
306
+ left: 0;
307
+ width: 100%;
308
+ height: 100%;
309
+ background: var(--plex-bg-darker);
310
+ display: flex;
311
+ align-items: center;
312
+ justify-content: center;
313
+ z-index: var(--plex-z-overlay);
314
+ }
315
+
316
+ .cast-overlay.hidden {
317
+ display: none;
318
+ }
319
+
320
+ .cast-overlay-content {
321
+ text-align: center;
322
+ animation: castPulse 2s ease-in-out infinite;
323
+ }
324
+
325
+ .cast-overlay .cast-icon {
326
+ font-size: 80px;
327
+ color: var(--plex-primary);
328
+ margin-bottom: 24px;
329
+ }
330
+
331
+ .cast-overlay .cast-title {
332
+ font-size: 18px;
333
+ color: var(--plex-text-secondary);
334
+ margin-bottom: 8px;
335
+ }
336
+
337
+ .cast-overlay .cast-device {
338
+ font-size: 28px;
339
+ font-weight: 600;
340
+ color: var(--plex-text-primary);
341
+ margin-bottom: 16px;
342
+ }
343
+
344
+ .cast-overlay .cast-video {
345
+ font-size: 16px;
346
+ color: var(--plex-text-secondary);
347
+ max-width: 300px;
348
+ white-space: nowrap;
349
+ overflow: hidden;
350
+ text-overflow: ellipsis;
351
+ }
352
+
353
+ @keyframes castPulse {
354
+ 0%, 100% { opacity: 1; }
355
+ 50% { opacity: 0.7; }
356
+ }
357
+
358
+ /* Utility Classes */
359
+ .hidden {
360
+ display: none !important;
361
+ }
362
+
363
+ .visually-hidden {
364
+ opacity: 0;
365
+ visibility: hidden;
366
+ }
367
+
368
+ /* Toast Notification */
369
+ .toast {
370
+ position: absolute;
371
+ bottom: 100px;
372
+ left: 50%;
373
+ transform: translateX(-50%) translateY(20px);
374
+ background: var(--plex-bg-overlay);
375
+ padding: 12px 24px;
376
+ border-radius: var(--plex-radius-md);
377
+ z-index: var(--plex-z-toast);
378
+ opacity: 0;
379
+ visibility: hidden;
380
+ transition: all var(--plex-transition-normal);
381
+ }
382
+
383
+ .toast.show {
384
+ opacity: 1;
385
+ visibility: visible;
386
+ transform: translateX(-50%) translateY(0);
387
+ }
388
+
389
+ .toast-message {
390
+ font-size: 14px;
391
+ font-weight: 500;
392
+ color: var(--plex-text-primary);
393
+ }
394
+
395
+ /* Context Menu */
396
+ .context-menu {
397
+ position: fixed;
398
+ min-width: 200px;
399
+ background: var(--plex-bg-dark);
400
+ border: 1px solid var(--plex-border);
401
+ border-radius: var(--plex-radius-md);
402
+ box-shadow: var(--plex-shadow);
403
+ z-index: var(--plex-z-modal);
404
+ overflow: hidden;
405
+ }
406
+
407
+ .context-menu-item {
408
+ display: flex;
409
+ align-items: center;
410
+ gap: 12px;
411
+ padding: 12px 16px;
412
+ cursor: pointer;
413
+ transition: background var(--plex-transition-fast);
414
+ }
415
+
416
+ .context-menu-item:hover {
417
+ background: rgba(255, 255, 255, 0.1);
418
+ }
419
+
420
+ .context-menu-item .material-icons {
421
+ font-size: 20px;
422
+ color: var(--plex-text-secondary);
423
+ }
424
+
425
+ .context-menu-item span:last-child {
426
+ font-size: 14px;
427
+ color: var(--plex-text-primary);
428
+ }
429
+
430
+ .context-menu-divider {
431
+ height: 1px;
432
+ background: var(--plex-border);
433
+ margin: 4px 0;
434
+ }
435
+
436
+ /* Stats Overlay */
437
+ .stats-overlay {
438
+ position: absolute;
439
+ top: 80px;
440
+ left: 20px;
441
+ width: 280px;
442
+ background: var(--plex-bg-overlay);
443
+ border-radius: var(--plex-radius-md);
444
+ z-index: var(--plex-z-panel);
445
+ overflow: hidden;
446
+ }
447
+
448
+ .stats-header {
449
+ display: flex;
450
+ align-items: center;
451
+ justify-content: space-between;
452
+ padding: 12px 16px;
453
+ background: rgba(255, 255, 255, 0.05);
454
+ border-bottom: 1px solid var(--plex-border);
455
+ font-size: 14px;
456
+ font-weight: 600;
457
+ }
458
+
459
+ .stats-content {
460
+ padding: 12px 16px;
461
+ }
462
+
463
+ .stat-item {
464
+ display: flex;
465
+ justify-content: space-between;
466
+ padding: 8px 0;
467
+ font-size: 13px;
468
+ border-bottom: 1px solid var(--plex-border);
469
+ }
470
+
471
+ .stat-item:last-child {
472
+ border-bottom: none;
473
+ }
474
+
475
+ .stat-label {
476
+ color: var(--plex-text-secondary);
477
+ }
478
+
479
+ .stat-value {
480
+ color: var(--plex-text-primary);
481
+ font-weight: 500;
482
+ }
483
+
484
+ /* Responsive */
485
+ @media (max-width: 768px) {
486
+ .big-play-btn {
487
+ width: 64px;
488
+ height: 64px;
489
+ }
490
+
491
+ .big-play-btn .material-icons {
492
+ font-size: 36px;
493
+ }
494
+
495
+ .subtitle-line {
496
+ font-size: 18px;
497
+ padding: 6px 12px;
498
+ }
499
+
500
+ .subtitles-container {
501
+ width: 90%;
502
+ bottom: 70px;
503
+ }
504
+
505
+ .gesture-indicator .material-icons {
506
+ font-size: 36px;
507
+ }
508
+
509
+ .stats-overlay {
510
+ top: 60px;
511
+ left: 10px;
512
+ width: 240px;
513
+ }
514
+ }
515
+
516
+ @media (max-width: 480px) {
517
+ .big-play-btn {
518
+ width: 56px;
519
+ height: 56px;
520
+ }
521
+
522
+ .big-play-btn .material-icons {
523
+ font-size: 32px;
524
+ }
525
+
526
+ .subtitle-line {
527
+ font-size: 16px;
528
+ }
529
+ }
530
+
531
+ /* Touch Device Optimizations */
532
+ @media (hover: none) and (pointer: coarse) {
533
+ .control-btn {
534
+ min-width: 44px;
535
+ min-height: 44px;
536
+ }
537
+
538
+ .volume-slider-container {
539
+ display: none;
540
+ }
541
+ }
542
+
543
+ /* Animations */
544
+ @keyframes fadeIn {
545
+ from {
546
+ opacity: 0;
547
+ }
548
+ to {
549
+ opacity: 1;
550
+ }
551
+ }
552
+
553
+ @keyframes slideUp {
554
+ from {
555
+ opacity: 0;
556
+ transform: translateY(20px);
557
+ }
558
+ to {
559
+ opacity: 1;
560
+ transform: translateY(0);
561
+ }
562
+ }
563
+
564
+ @keyframes pulse {
565
+ 0%, 100% {
566
+ transform: translate(-50%, -50%) scale(1);
567
+ }
568
+ 50% {
569
+ transform: translate(-50%, -50%) scale(1.05);
570
+ }
571
+ }
572
+
573
+ /* =====================================================
574
+ PLEX Video Player - Controls Styles
575
+ ===================================================== */
576
+
577
+ /* Top Controls Bar */
578
+ .top-controls {
579
+ position: absolute;
580
+ top: 0;
581
+ left: 0;
582
+ width: 100%;
583
+ display: flex;
584
+ align-items: center;
585
+ justify-content: space-between;
586
+ padding: 16px 20px;
587
+ background: var(--plex-gradient-top);
588
+ z-index: var(--plex-z-controls);
589
+ transition: all var(--plex-transition-normal);
590
+ }
591
+
592
+ .top-left,
593
+ .top-right {
594
+ display: flex;
595
+ align-items: center;
596
+ gap: 8px;
597
+ }
598
+
599
+ .video-title {
600
+ font-size: 16px;
601
+ font-weight: 600;
602
+ color: var(--plex-text-primary);
603
+ margin-left: 8px;
604
+ max-width: 400px;
605
+ white-space: nowrap;
606
+ overflow: hidden;
607
+ text-overflow: ellipsis;
608
+ }
609
+
610
+ /* Bottom Controls */
611
+ .bottom-controls {
612
+ position: absolute;
613
+ bottom: 0;
614
+ left: 0;
615
+ width: 100%;
616
+ padding: 0 16px 16px;
617
+ background: var(--plex-gradient);
618
+ z-index: var(--plex-z-controls);
619
+ transition: all var(--plex-transition-normal);
620
+ }
621
+
622
+ /* Progress Container */
623
+ .progress-container {
624
+ position: relative;
625
+ width: 100%;
626
+ height: 24px;
627
+ display: flex;
628
+ align-items: center;
629
+ cursor: pointer;
630
+ padding: 8px 0;
631
+ }
632
+
633
+ .progress-bar {
634
+ position: relative;
635
+ width: 100%;
636
+ height: 4px;
637
+ background: rgba(255, 255, 255, 0.2);
638
+ border-radius: 2px;
639
+ overflow: visible;
640
+ transition: height var(--plex-transition-fast);
641
+ }
642
+
643
+ .progress-container:hover .progress-bar {
644
+ height: 6px;
645
+ }
646
+
647
+ .progress-buffered {
648
+ position: absolute;
649
+ top: 0;
650
+ left: 0;
651
+ height: 100%;
652
+ background: rgba(255, 255, 255, 0.35);
653
+ border-radius: 2px;
654
+ pointer-events: none;
655
+ }
656
+
657
+ .progress-played {
658
+ position: absolute;
659
+ top: 0;
660
+ left: 0;
661
+ height: 100%;
662
+ background: var(--plex-primary);
663
+ border-radius: 2px;
664
+ pointer-events: none;
665
+ }
666
+
667
+ .progress-handle {
668
+ position: absolute;
669
+ top: 50%;
670
+ left: 0;
671
+ width: 14px;
672
+ height: 14px;
673
+ background: var(--plex-primary);
674
+ border-radius: 50%;
675
+ transform: translate(-50%, -50%) scale(0);
676
+ transition: transform var(--plex-transition-fast);
677
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
678
+ pointer-events: none;
679
+ }
680
+
681
+ .progress-container:hover .progress-handle,
682
+ .progress-container.dragging .progress-handle {
683
+ transform: translate(-50%, -50%) scale(1);
684
+ }
685
+
686
+ .progress-container.dragging .progress-bar {
687
+ height: 6px;
688
+ }
689
+
690
+ /* Progress Tooltip */
691
+ .progress-tooltip {
692
+ position: absolute;
693
+ bottom: 100%;
694
+ left: 0;
695
+ padding: 6px 10px;
696
+ background: var(--plex-bg-dark);
697
+ border-radius: var(--plex-radius-sm);
698
+ font-size: 13px;
699
+ font-weight: 500;
700
+ white-space: nowrap;
701
+ opacity: 0;
702
+ visibility: hidden;
703
+ transform: translateX(-50%) translateY(4px);
704
+ transition: all var(--plex-transition-fast);
705
+ pointer-events: none;
706
+ z-index: 50;
707
+ }
708
+
709
+ .progress-container:hover .progress-tooltip {
710
+ opacity: 1;
711
+ visibility: visible;
712
+ transform: translateX(-50%) translateY(-4px);
713
+ }
714
+
715
+ /* Hide tooltip when preview is visible */
716
+ .progress-container:hover .progress-preview[style*="display: flex"] ~ .progress-tooltip,
717
+ .progress-preview:not([style*="display: none"]) + .progress-tooltip {
718
+ opacity: 0;
719
+ visibility: hidden;
720
+ }
721
+
722
+ /* Progress Preview (Thumbnail) */
723
+ .progress-preview {
724
+ position: absolute;
725
+ bottom: calc(100% + 16px);
726
+ left: 0;
727
+ display: none;
728
+ flex-direction: column;
729
+ align-items: center;
730
+ z-index: 100;
731
+ pointer-events: none;
732
+ background: rgba(0, 0, 0, 0.9);
733
+ padding: 4px;
734
+ border-radius: var(--plex-radius-sm);
735
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
736
+ }
737
+
738
+ #preview-canvas {
739
+ width: 160px;
740
+ height: 90px;
741
+ background: var(--plex-bg-dark);
742
+ border: 2px solid var(--plex-primary);
743
+ border-radius: var(--plex-radius-sm);
744
+ object-fit: contain;
745
+ }
746
+
747
+ .preview-time {
748
+ margin-top: 6px;
749
+ padding: 4px 10px;
750
+ background: var(--plex-primary);
751
+ color: #000;
752
+ border-radius: var(--plex-radius-sm);
753
+ font-size: 12px;
754
+ font-weight: 700;
755
+ }
756
+
757
+ /* Time Display */
758
+ .time-display {
759
+ display: flex;
760
+ align-items: center;
761
+ gap: 4px;
762
+ padding: 8px 0;
763
+ font-size: 13px;
764
+ font-weight: 500;
765
+ color: var(--plex-text-primary);
766
+ }
767
+
768
+ .time-separator {
769
+ color: var(--plex-text-secondary);
770
+ }
771
+
772
+ /* Main Controls Row */
773
+ .main-controls {
774
+ display: flex;
775
+ align-items: center;
776
+ justify-content: space-between;
777
+ margin-top: 4px;
778
+ }
779
+
780
+ .controls-left,
781
+ .controls-right {
782
+ display: flex;
783
+ align-items: center;
784
+ gap: 4px;
785
+ }
786
+
787
+ /* Control Button */
788
+ .control-btn {
789
+ position: relative;
790
+ display: flex;
791
+ align-items: center;
792
+ justify-content: center;
793
+ width: 40px;
794
+ height: 40px;
795
+ background: transparent;
796
+ border: none;
797
+ border-radius: var(--plex-radius-sm);
798
+ cursor: pointer;
799
+ transition: all var(--plex-transition-fast);
800
+ color: var(--plex-text-primary);
801
+ }
802
+
803
+ .control-btn:hover {
804
+ background: rgba(255, 255, 255, 0.1);
805
+ }
806
+
807
+ .control-btn:active {
808
+ transform: scale(0.95);
809
+ }
810
+
811
+ .control-btn .material-icons {
812
+ font-size: 24px;
813
+ }
814
+
815
+ .control-btn.active {
816
+ color: var(--plex-primary);
817
+ }
818
+
819
+ /* Cast Button */
820
+ #cast-btn {
821
+ transition: all var(--plex-transition-fast);
822
+ }
823
+
824
+ #cast-btn.active {
825
+ color: var(--plex-primary);
826
+ animation: pulse-cast 2s ease-in-out infinite;
827
+ }
828
+
829
+ #cast-btn.hidden {
830
+ display: none;
831
+ }
832
+
833
+ @keyframes pulse-cast {
834
+ 0%, 100% { opacity: 1; }
835
+ 50% { opacity: 0.6; }
836
+ }
837
+
838
+ /* Play Button (Larger) */
839
+ .play-btn {
840
+ width: 48px;
841
+ height: 48px;
842
+ }
843
+
844
+ .play-btn .material-icons {
845
+ font-size: 32px;
846
+ }
847
+
848
+ /* Speed Text */
849
+ .speed-text {
850
+ font-size: 14px;
851
+ font-weight: 600;
852
+ min-width: 28px;
853
+ }
854
+
855
+ /* Volume Control */
856
+ .volume-control {
857
+ display: flex;
858
+ align-items: center;
859
+ gap: 4px;
860
+ }
861
+
862
+ .volume-slider-container {
863
+ position: relative;
864
+ width: 0;
865
+ overflow: hidden;
866
+ transition: width var(--plex-transition-normal);
867
+ }
868
+
869
+ .volume-control:hover .volume-slider-container {
870
+ width: 80px;
871
+ }
872
+
873
+ .volume-slider {
874
+ -webkit-appearance: none;
875
+ appearance: none;
876
+ width: 80px;
877
+ height: 4px;
878
+ background: rgba(255, 255, 255, 0.2);
879
+ border-radius: 2px;
880
+ outline: none;
881
+ cursor: pointer;
882
+ }
883
+
884
+ .volume-slider::-webkit-slider-thumb {
885
+ -webkit-appearance: none;
886
+ appearance: none;
887
+ width: 14px;
888
+ height: 14px;
889
+ background: var(--plex-primary);
890
+ border-radius: 50%;
891
+ cursor: pointer;
892
+ transition: transform var(--plex-transition-fast);
893
+ }
894
+
895
+ .volume-slider::-webkit-slider-thumb:hover {
896
+ transform: scale(1.2);
897
+ }
898
+
899
+ .volume-slider::-moz-range-thumb {
900
+ width: 14px;
901
+ height: 14px;
902
+ background: var(--plex-primary);
903
+ border: none;
904
+ border-radius: 50%;
905
+ cursor: pointer;
906
+ }
907
+
908
+ .volume-slider-fill {
909
+ position: absolute;
910
+ top: 50%;
911
+ left: 0;
912
+ height: 4px;
913
+ background: var(--plex-primary);
914
+ border-radius: 2px;
915
+ transform: translateY(-50%);
916
+ pointer-events: none;
917
+ }
918
+
919
+ /* Chapters Markers (on progress bar) */
920
+ .chapter-marker {
921
+ position: absolute;
922
+ top: 0;
923
+ width: 3px;
924
+ height: 100%;
925
+ background: rgba(255, 255, 255, 0.8);
926
+ border-radius: 1px;
927
+ transform: translateX(-50%);
928
+ cursor: pointer;
929
+ z-index: 2;
930
+ }
931
+
932
+ .chapter-marker:hover {
933
+ background: var(--plex-primary);
934
+ }
935
+
936
+ /* Skip Intro Button */
937
+ .skip-intro-btn {
938
+ position: absolute;
939
+ right: 20px;
940
+ bottom: 100px;
941
+ display: flex;
942
+ align-items: center;
943
+ gap: 8px;
944
+ padding: 12px 20px;
945
+ background: rgba(255, 255, 255, 0.9);
946
+ color: #000;
947
+ border: none;
948
+ border-radius: var(--plex-radius-md);
949
+ font-size: 14px;
950
+ font-weight: 600;
951
+ cursor: pointer;
952
+ z-index: var(--plex-z-controls);
953
+ transition: all var(--plex-transition-normal);
954
+ }
955
+
956
+ .skip-intro-btn:hover {
957
+ background: #fff;
958
+ transform: scale(1.02);
959
+ }
960
+
961
+ .skip-intro-btn .material-icons {
962
+ font-size: 20px;
963
+ }
964
+
965
+ /* Double Tap Ripple Effect */
966
+ .tap-ripple {
967
+ position: absolute;
968
+ width: 100px;
969
+ height: 100px;
970
+ border-radius: 50%;
971
+ background: rgba(255, 255, 255, 0.3);
972
+ transform: translate(-50%, -50%) scale(0);
973
+ animation: ripple 0.5s ease-out forwards;
974
+ pointer-events: none;
975
+ }
976
+
977
+ @keyframes ripple {
978
+ to {
979
+ transform: translate(-50%, -50%) scale(2);
980
+ opacity: 0;
981
+ }
982
+ }
983
+
984
+ /* Responsive Controls */
985
+ @media (max-width: 768px) {
986
+ .top-controls {
987
+ padding: 12px 16px;
988
+ }
989
+
990
+ .video-title {
991
+ font-size: 14px;
992
+ max-width: 200px;
993
+ }
994
+
995
+ .bottom-controls {
996
+ padding: 0 12px 12px;
997
+ }
998
+
999
+ .control-btn {
1000
+ width: 36px;
1001
+ height: 36px;
1002
+ }
1003
+
1004
+ .control-btn .material-icons {
1005
+ font-size: 22px;
1006
+ }
1007
+
1008
+ .play-btn {
1009
+ width: 44px;
1010
+ height: 44px;
1011
+ }
1012
+
1013
+ .play-btn .material-icons {
1014
+ font-size: 28px;
1015
+ }
1016
+
1017
+ .time-display {
1018
+ font-size: 12px;
1019
+ }
1020
+
1021
+ .speed-text {
1022
+ font-size: 12px;
1023
+ }
1024
+
1025
+ #preview-canvas {
1026
+ width: 120px;
1027
+ height: 68px;
1028
+ }
1029
+ }
1030
+
1031
+ @media (max-width: 480px) {
1032
+ .controls-left,
1033
+ .controls-right {
1034
+ gap: 0;
1035
+ }
1036
+
1037
+ .control-btn {
1038
+ width: 32px;
1039
+ height: 32px;
1040
+ }
1041
+
1042
+ .control-btn .material-icons {
1043
+ font-size: 20px;
1044
+ }
1045
+
1046
+ .video-title {
1047
+ max-width: 140px;
1048
+ font-size: 13px;
1049
+ }
1050
+
1051
+ /* Hide some buttons on very small screens */
1052
+ #cast-btn,
1053
+ #quality-btn {
1054
+ display: none;
1055
+ }
1056
+ }
1057
+
1058
+ /* Hover/Focus States for Accessibility */
1059
+ .control-btn:focus-visible {
1060
+ outline: 2px solid var(--plex-primary);
1061
+ outline-offset: 2px;
1062
+ }
1063
+
1064
+ .progress-container:focus-visible {
1065
+ outline: 2px solid var(--plex-primary);
1066
+ outline-offset: 2px;
1067
+ }
1068
+
1069
+ /* Disabled State */
1070
+ .control-btn:disabled {
1071
+ opacity: 0.4;
1072
+ cursor: not-allowed;
1073
+ }
1074
+
1075
+ .control-btn:disabled:hover {
1076
+ background: transparent;
1077
+ }
1078
+
1079
+ /* =====================================================
1080
+ PLEX Video Player - Playlist Styles
1081
+ ===================================================== */
1082
+
1083
+ /* Playlist Panel */
1084
+ .playlist-panel {
1085
+ position: absolute;
1086
+ top: 0;
1087
+ right: 0;
1088
+ width: 360px;
1089
+ height: 100%;
1090
+ background: var(--plex-bg-dark);
1091
+ border-left: 1px solid var(--plex-border);
1092
+ z-index: var(--plex-z-panel);
1093
+ display: flex;
1094
+ flex-direction: column;
1095
+ transform: translateX(100%);
1096
+ transition: transform var(--plex-transition-normal);
1097
+ }
1098
+
1099
+ .playlist-panel.visible {
1100
+ transform: translateX(0);
1101
+ }
1102
+
1103
+ /* Playlist Header */
1104
+ .playlist-header {
1105
+ display: flex;
1106
+ align-items: center;
1107
+ justify-content: space-between;
1108
+ padding: 16px 20px;
1109
+ background: rgba(255, 255, 255, 0.03);
1110
+ border-bottom: 1px solid var(--plex-border);
1111
+ flex-shrink: 0;
1112
+ }
1113
+
1114
+ .playlist-title {
1115
+ font-size: 16px;
1116
+ font-weight: 600;
1117
+ color: var(--plex-text-primary);
1118
+ }
1119
+
1120
+ .playlist-header-actions {
1121
+ display: flex;
1122
+ align-items: center;
1123
+ gap: 4px;
1124
+ }
1125
+
1126
+ /* Playlist Content */
1127
+ .playlist-content {
1128
+ flex: 1;
1129
+ overflow-y: auto;
1130
+ overflow-x: hidden;
1131
+ padding: 12px;
1132
+ }
1133
+
1134
+ .playlist-content::-webkit-scrollbar {
1135
+ width: 6px;
1136
+ }
1137
+
1138
+ .playlist-content::-webkit-scrollbar-track {
1139
+ background: transparent;
1140
+ }
1141
+
1142
+ .playlist-content::-webkit-scrollbar-thumb {
1143
+ background: rgba(255, 255, 255, 0.2);
1144
+ border-radius: 3px;
1145
+ }
1146
+
1147
+ .playlist-content::-webkit-scrollbar-thumb:hover {
1148
+ background: rgba(255, 255, 255, 0.3);
1149
+ }
1150
+
1151
+ /* Playlist Empty State */
1152
+ .playlist-empty {
1153
+ display: flex;
1154
+ flex-direction: column;
1155
+ align-items: center;
1156
+ justify-content: center;
1157
+ height: 100%;
1158
+ padding: 40px;
1159
+ text-align: center;
1160
+ }
1161
+
1162
+ .playlist-empty .material-icons {
1163
+ font-size: 64px;
1164
+ color: var(--plex-text-secondary);
1165
+ margin-bottom: 16px;
1166
+ opacity: 0.5;
1167
+ }
1168
+
1169
+ .playlist-empty-title {
1170
+ font-size: 18px;
1171
+ font-weight: 600;
1172
+ color: var(--plex-text-primary);
1173
+ margin-bottom: 8px;
1174
+ }
1175
+
1176
+ .playlist-empty-text {
1177
+ font-size: 14px;
1178
+ color: var(--plex-text-secondary);
1179
+ line-height: 1.5;
1180
+ }
1181
+
1182
+ /* Playlist Item */
1183
+ .playlist-item {
1184
+ display: flex;
1185
+ align-items: center;
1186
+ gap: 12px;
1187
+ padding: 10px 12px;
1188
+ background: rgba(255, 255, 255, 0.02);
1189
+ border-radius: var(--plex-radius-md);
1190
+ cursor: pointer;
1191
+ transition: all var(--plex-transition-fast);
1192
+ margin-bottom: 8px;
1193
+ position: relative;
1194
+ }
1195
+
1196
+ .playlist-item:hover {
1197
+ background: rgba(255, 255, 255, 0.08);
1198
+ }
1199
+
1200
+ .playlist-item.active {
1201
+ background: rgba(229, 160, 13, 0.15);
1202
+ border: 1px solid rgba(229, 160, 13, 0.3);
1203
+ }
1204
+
1205
+ .playlist-item.playing {
1206
+ background: rgba(229, 160, 13, 0.2);
1207
+ }
1208
+
1209
+ .playlist-item.dragging {
1210
+ opacity: 0.5;
1211
+ transform: scale(0.98);
1212
+ }
1213
+
1214
+ /* Playlist Item Thumbnail */
1215
+ .playlist-item-thumbnail {
1216
+ position: relative;
1217
+ width: 100px;
1218
+ height: 56px;
1219
+ background: var(--plex-bg-darker);
1220
+ border-radius: var(--plex-radius-sm);
1221
+ overflow: hidden;
1222
+ flex-shrink: 0;
1223
+ }
1224
+
1225
+ .playlist-item-thumbnail img {
1226
+ width: 100%;
1227
+ height: 100%;
1228
+ object-fit: cover;
1229
+ }
1230
+
1231
+ .playlist-item-thumbnail .placeholder-icon {
1232
+ position: absolute;
1233
+ top: 50%;
1234
+ left: 50%;
1235
+ transform: translate(-50%, -50%);
1236
+ font-size: 32px;
1237
+ color: var(--plex-text-secondary);
1238
+ opacity: 0.5;
1239
+ }
1240
+
1241
+ .playlist-item-duration {
1242
+ position: absolute;
1243
+ bottom: 4px;
1244
+ right: 4px;
1245
+ padding: 2px 6px;
1246
+ background: rgba(0, 0, 0, 0.8);
1247
+ border-radius: 3px;
1248
+ font-size: 11px;
1249
+ font-weight: 600;
1250
+ color: var(--plex-text-primary);
1251
+ }
1252
+
1253
+ /* Playing Indicator */
1254
+ .playlist-item-playing-indicator {
1255
+ position: absolute;
1256
+ top: 50%;
1257
+ left: 50%;
1258
+ transform: translate(-50%, -50%);
1259
+ display: none;
1260
+ align-items: flex-end;
1261
+ justify-content: center;
1262
+ gap: 2px;
1263
+ width: 24px;
1264
+ height: 20px;
1265
+ }
1266
+
1267
+ .playlist-item.playing .playlist-item-playing-indicator {
1268
+ display: flex;
1269
+ }
1270
+
1271
+ .playlist-item-playing-indicator span {
1272
+ width: 4px;
1273
+ background: var(--plex-primary);
1274
+ border-radius: 1px;
1275
+ animation: equalizer 0.5s ease-in-out infinite alternate;
1276
+ }
1277
+
1278
+ .playlist-item-playing-indicator span:nth-child(1) {
1279
+ height: 60%;
1280
+ animation-delay: 0s;
1281
+ }
1282
+
1283
+ .playlist-item-playing-indicator span:nth-child(2) {
1284
+ height: 100%;
1285
+ animation-delay: 0.15s;
1286
+ }
1287
+
1288
+ .playlist-item-playing-indicator span:nth-child(3) {
1289
+ height: 40%;
1290
+ animation-delay: 0.3s;
1291
+ }
1292
+
1293
+ @keyframes equalizer {
1294
+ from {
1295
+ transform: scaleY(0.5);
1296
+ }
1297
+ to {
1298
+ transform: scaleY(1);
1299
+ }
1300
+ }
1301
+
1302
+ /* Playlist Item Info */
1303
+ .playlist-item-info {
1304
+ flex: 1;
1305
+ min-width: 0;
1306
+ display: flex;
1307
+ flex-direction: column;
1308
+ gap: 4px;
1309
+ }
1310
+
1311
+ .playlist-item-title {
1312
+ font-size: 14px;
1313
+ font-weight: 500;
1314
+ color: var(--plex-text-primary);
1315
+ white-space: nowrap;
1316
+ overflow: hidden;
1317
+ text-overflow: ellipsis;
1318
+ }
1319
+
1320
+ .playlist-item-meta {
1321
+ font-size: 12px;
1322
+ color: var(--plex-text-secondary);
1323
+ display: flex;
1324
+ align-items: center;
1325
+ gap: 8px;
1326
+ }
1327
+
1328
+ /* Playlist Item Actions */
1329
+ .playlist-item-actions {
1330
+ display: flex;
1331
+ align-items: center;
1332
+ gap: 4px;
1333
+ opacity: 0;
1334
+ transition: opacity var(--plex-transition-fast);
1335
+ }
1336
+
1337
+ .playlist-item:hover .playlist-item-actions {
1338
+ opacity: 1;
1339
+ }
1340
+
1341
+ .playlist-item-action {
1342
+ display: flex;
1343
+ align-items: center;
1344
+ justify-content: center;
1345
+ width: 28px;
1346
+ height: 28px;
1347
+ background: transparent;
1348
+ border: none;
1349
+ border-radius: var(--plex-radius-sm);
1350
+ cursor: pointer;
1351
+ color: var(--plex-text-secondary);
1352
+ transition: all var(--plex-transition-fast);
1353
+ }
1354
+
1355
+ .playlist-item-action:hover {
1356
+ background: rgba(255, 255, 255, 0.1);
1357
+ color: var(--plex-text-primary);
1358
+ }
1359
+
1360
+ .playlist-item-action .material-icons {
1361
+ font-size: 18px;
1362
+ }
1363
+
1364
+ /* Drag Handle */
1365
+ .playlist-item-drag-handle {
1366
+ display: flex;
1367
+ align-items: center;
1368
+ justify-content: center;
1369
+ width: 20px;
1370
+ cursor: grab;
1371
+ color: var(--plex-text-secondary);
1372
+ opacity: 0;
1373
+ transition: opacity var(--plex-transition-fast);
1374
+ }
1375
+
1376
+ .playlist-item:hover .playlist-item-drag-handle {
1377
+ opacity: 1;
1378
+ }
1379
+
1380
+ .playlist-item-drag-handle:active {
1381
+ cursor: grabbing;
1382
+ }
1383
+
1384
+ .playlist-item-drag-handle .material-icons {
1385
+ font-size: 18px;
1386
+ }
1387
+
1388
+ /* Playlist Footer */
1389
+ .playlist-footer {
1390
+ padding: 16px;
1391
+ border-top: 1px solid var(--plex-border);
1392
+ flex-shrink: 0;
1393
+ }
1394
+
1395
+ .playlist-add-btn {
1396
+ display: flex;
1397
+ align-items: center;
1398
+ justify-content: center;
1399
+ gap: 8px;
1400
+ width: 100%;
1401
+ padding: 12px;
1402
+ background: rgba(255, 255, 255, 0.05);
1403
+ border: 2px dashed var(--plex-border);
1404
+ border-radius: var(--plex-radius-md);
1405
+ color: var(--plex-text-secondary);
1406
+ font-size: 14px;
1407
+ font-weight: 500;
1408
+ cursor: pointer;
1409
+ transition: all var(--plex-transition-fast);
1410
+ }
1411
+
1412
+ .playlist-add-btn:hover {
1413
+ background: rgba(255, 255, 255, 0.08);
1414
+ border-color: var(--plex-primary);
1415
+ color: var(--plex-primary);
1416
+ }
1417
+
1418
+ .playlist-add-btn .material-icons {
1419
+ font-size: 20px;
1420
+ }
1421
+
1422
+ /* Playlist Stats */
1423
+ .playlist-stats {
1424
+ display: flex;
1425
+ align-items: center;
1426
+ justify-content: space-between;
1427
+ padding: 12px 16px;
1428
+ background: rgba(0, 0, 0, 0.3);
1429
+ border-top: 1px solid var(--plex-border);
1430
+ font-size: 12px;
1431
+ color: var(--plex-text-secondary);
1432
+ }
1433
+
1434
+ /* Queue Next Indicator */
1435
+ .playlist-item-queue-next {
1436
+ position: absolute;
1437
+ top: 4px;
1438
+ left: 4px;
1439
+ padding: 2px 6px;
1440
+ background: var(--plex-primary);
1441
+ border-radius: 3px;
1442
+ font-size: 9px;
1443
+ font-weight: 700;
1444
+ color: #000;
1445
+ text-transform: uppercase;
1446
+ }
1447
+
1448
+ /* Responsive Playlist */
1449
+ @media (max-width: 768px) {
1450
+ .playlist-panel {
1451
+ width: 100%;
1452
+ max-width: 100%;
1453
+ }
1454
+
1455
+ .playlist-item-thumbnail {
1456
+ width: 80px;
1457
+ height: 45px;
1458
+ }
1459
+
1460
+ .playlist-item-title {
1461
+ font-size: 13px;
1462
+ }
1463
+
1464
+ .playlist-item-actions {
1465
+ opacity: 1;
1466
+ }
1467
+ }
1468
+
1469
+ @media (max-width: 480px) {
1470
+ .playlist-header {
1471
+ padding: 12px 16px;
1472
+ }
1473
+
1474
+ .playlist-content {
1475
+ padding: 8px;
1476
+ }
1477
+
1478
+ .playlist-item {
1479
+ padding: 8px;
1480
+ gap: 10px;
1481
+ }
1482
+
1483
+ .playlist-item-thumbnail {
1484
+ width: 70px;
1485
+ height: 40px;
1486
+ }
1487
+
1488
+ .playlist-item-drag-handle {
1489
+ display: none;
1490
+ }
1491
+ }
1492
+
1493
+ /* Drag and Drop States */
1494
+ .playlist-content.drag-over {
1495
+ background: rgba(229, 160, 13, 0.05);
1496
+ }
1497
+
1498
+ .playlist-item.drop-target-above::before {
1499
+ content: '';
1500
+ position: absolute;
1501
+ top: -4px;
1502
+ left: 0;
1503
+ right: 0;
1504
+ height: 2px;
1505
+ background: var(--plex-primary);
1506
+ border-radius: 1px;
1507
+ }
1508
+
1509
+ .playlist-item.drop-target-below::after {
1510
+ content: '';
1511
+ position: absolute;
1512
+ bottom: -4px;
1513
+ left: 0;
1514
+ right: 0;
1515
+ height: 2px;
1516
+ background: var(--plex-primary);
1517
+ border-radius: 1px;
1518
+ }
1519
+
1520
+ /* =====================================================
1521
+ PLEX Video Player - Settings Styles
1522
+ ===================================================== */
1523
+
1524
+ /* Settings Panel */
1525
+ .settings-panel {
1526
+ position: absolute;
1527
+ bottom: 80px;
1528
+ right: 20px;
1529
+ width: 300px;
1530
+ max-height: 400px;
1531
+ background: var(--plex-bg-dark);
1532
+ border: 1px solid var(--plex-border);
1533
+ border-radius: var(--plex-radius-lg);
1534
+ box-shadow: var(--plex-shadow);
1535
+ z-index: var(--plex-z-panel);
1536
+ overflow: hidden;
1537
+ transform-origin: bottom right;
1538
+ animation: settingsOpen 0.2s ease;
1539
+ }
1540
+
1541
+ @keyframes settingsOpen {
1542
+ from {
1543
+ opacity: 0;
1544
+ transform: scale(0.95);
1545
+ }
1546
+ to {
1547
+ opacity: 1;
1548
+ transform: scale(1);
1549
+ }
1550
+ }
1551
+
1552
+ /* Settings Header */
1553
+ .settings-header {
1554
+ display: flex;
1555
+ align-items: center;
1556
+ justify-content: space-between;
1557
+ padding: 12px 16px;
1558
+ background: rgba(255, 255, 255, 0.03);
1559
+ border-bottom: 1px solid var(--plex-border);
1560
+ }
1561
+
1562
+ .settings-title {
1563
+ font-size: 15px;
1564
+ font-weight: 600;
1565
+ color: var(--plex-text-primary);
1566
+ }
1567
+
1568
+ /* Settings Content */
1569
+ .settings-content {
1570
+ max-height: 340px;
1571
+ overflow-y: auto;
1572
+ }
1573
+
1574
+ .settings-content::-webkit-scrollbar {
1575
+ width: 6px;
1576
+ }
1577
+
1578
+ .settings-content::-webkit-scrollbar-track {
1579
+ background: transparent;
1580
+ }
1581
+
1582
+ .settings-content::-webkit-scrollbar-thumb {
1583
+ background: rgba(255, 255, 255, 0.2);
1584
+ border-radius: 3px;
1585
+ }
1586
+
1587
+ /* Settings Menu */
1588
+ .settings-menu {
1589
+ padding: 8px 0;
1590
+ }
1591
+
1592
+ /* Settings Item */
1593
+ .settings-item {
1594
+ display: flex;
1595
+ align-items: center;
1596
+ gap: 12px;
1597
+ padding: 12px 16px;
1598
+ cursor: pointer;
1599
+ transition: background var(--plex-transition-fast);
1600
+ }
1601
+
1602
+ .settings-item:hover {
1603
+ background: rgba(255, 255, 255, 0.05);
1604
+ }
1605
+
1606
+ .settings-item .material-icons:first-child {
1607
+ font-size: 22px;
1608
+ color: var(--plex-text-secondary);
1609
+ }
1610
+
1611
+ .settings-item-label {
1612
+ flex: 1;
1613
+ font-size: 14px;
1614
+ color: var(--plex-text-primary);
1615
+ }
1616
+
1617
+ .settings-item-value {
1618
+ font-size: 13px;
1619
+ color: var(--plex-text-secondary);
1620
+ }
1621
+
1622
+ .settings-item .material-icons:last-child {
1623
+ font-size: 20px;
1624
+ color: var(--plex-text-secondary);
1625
+ }
1626
+
1627
+ /* Settings Submenu */
1628
+ .settings-submenu {
1629
+ padding: 8px 0;
1630
+ }
1631
+
1632
+ /* Settings Option */
1633
+ .settings-option {
1634
+ display: flex;
1635
+ align-items: center;
1636
+ justify-content: space-between;
1637
+ padding: 12px 16px;
1638
+ cursor: pointer;
1639
+ transition: background var(--plex-transition-fast);
1640
+ font-size: 14px;
1641
+ color: var(--plex-text-primary);
1642
+ }
1643
+
1644
+ .settings-option:hover {
1645
+ background: rgba(255, 255, 255, 0.05);
1646
+ }
1647
+
1648
+ .settings-option.active {
1649
+ color: var(--plex-primary);
1650
+ }
1651
+
1652
+ .settings-option.active::after {
1653
+ content: 'check';
1654
+ font-family: 'Material Icons';
1655
+ font-size: 20px;
1656
+ color: var(--plex-primary);
1657
+ }
1658
+
1659
+ /* Toggle Switch */
1660
+ .toggle-switch {
1661
+ position: relative;
1662
+ width: 44px;
1663
+ height: 24px;
1664
+ background: rgba(255, 255, 255, 0.2);
1665
+ border-radius: 12px;
1666
+ cursor: pointer;
1667
+ transition: background var(--plex-transition-fast);
1668
+ }
1669
+
1670
+ .toggle-switch.active {
1671
+ background: var(--plex-primary);
1672
+ }
1673
+
1674
+ .toggle-slider {
1675
+ position: absolute;
1676
+ top: 2px;
1677
+ left: 2px;
1678
+ width: 20px;
1679
+ height: 20px;
1680
+ background: #fff;
1681
+ border-radius: 50%;
1682
+ transition: transform var(--plex-transition-fast);
1683
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
1684
+ }
1685
+
1686
+ .toggle-switch.active .toggle-slider {
1687
+ transform: translateX(20px);
1688
+ }
1689
+
1690
+ /* Subtitles Settings Panel */
1691
+ .subtitles-settings-panel {
1692
+ position: absolute;
1693
+ bottom: 80px;
1694
+ right: 20px;
1695
+ width: 320px;
1696
+ background: var(--plex-bg-dark);
1697
+ border: 1px solid var(--plex-border);
1698
+ border-radius: var(--plex-radius-lg);
1699
+ box-shadow: var(--plex-shadow);
1700
+ z-index: var(--plex-z-panel);
1701
+ overflow: hidden;
1702
+ }
1703
+
1704
+ .subtitles-settings-content {
1705
+ padding: 16px;
1706
+ }
1707
+
1708
+ /* Subtitle Setting Item */
1709
+ .subtitle-setting-item {
1710
+ display: flex;
1711
+ align-items: center;
1712
+ gap: 12px;
1713
+ margin-bottom: 16px;
1714
+ }
1715
+
1716
+ .subtitle-setting-item label {
1717
+ flex: 0 0 100px;
1718
+ font-size: 13px;
1719
+ color: var(--plex-text-secondary);
1720
+ }
1721
+
1722
+ .subtitle-setting-item input[type="range"] {
1723
+ flex: 1;
1724
+ -webkit-appearance: none;
1725
+ appearance: none;
1726
+ height: 4px;
1727
+ background: rgba(255, 255, 255, 0.2);
1728
+ border-radius: 2px;
1729
+ outline: none;
1730
+ }
1731
+
1732
+ .subtitle-setting-item input[type="range"]::-webkit-slider-thumb {
1733
+ -webkit-appearance: none;
1734
+ appearance: none;
1735
+ width: 16px;
1736
+ height: 16px;
1737
+ background: var(--plex-primary);
1738
+ border-radius: 50%;
1739
+ cursor: pointer;
1740
+ }
1741
+
1742
+ .subtitle-setting-item input[type="color"] {
1743
+ -webkit-appearance: none;
1744
+ appearance: none;
1745
+ width: 40px;
1746
+ height: 30px;
1747
+ border: none;
1748
+ border-radius: var(--plex-radius-sm);
1749
+ cursor: pointer;
1750
+ background: transparent;
1751
+ }
1752
+
1753
+ .subtitle-setting-item input[type="color"]::-webkit-color-swatch-wrapper {
1754
+ padding: 0;
1755
+ }
1756
+
1757
+ .subtitle-setting-item input[type="color"]::-webkit-color-swatch {
1758
+ border: 2px solid var(--plex-border);
1759
+ border-radius: var(--plex-radius-sm);
1760
+ }
1761
+
1762
+ .subtitle-setting-item span:last-child {
1763
+ flex: 0 0 50px;
1764
+ text-align: right;
1765
+ font-size: 13px;
1766
+ color: var(--plex-text-primary);
1767
+ font-weight: 500;
1768
+ }
1769
+
1770
+ /* Subtitle Load Button */
1771
+ .subtitle-load-btn {
1772
+ display: flex;
1773
+ align-items: center;
1774
+ justify-content: center;
1775
+ gap: 8px;
1776
+ width: 100%;
1777
+ padding: 12px;
1778
+ margin-top: 8px;
1779
+ background: rgba(255, 255, 255, 0.05);
1780
+ border: 1px solid var(--plex-border);
1781
+ border-radius: var(--plex-radius-md);
1782
+ color: var(--plex-text-primary);
1783
+ font-size: 14px;
1784
+ cursor: pointer;
1785
+ transition: all var(--plex-transition-fast);
1786
+ }
1787
+
1788
+ .subtitle-load-btn:hover {
1789
+ background: rgba(255, 255, 255, 0.1);
1790
+ border-color: var(--plex-primary);
1791
+ }
1792
+
1793
+ .subtitle-load-btn .material-icons {
1794
+ font-size: 20px;
1795
+ }
1796
+
1797
+ /* Speed Panel (Alternative) */
1798
+ .speed-panel {
1799
+ position: absolute;
1800
+ bottom: 80px;
1801
+ right: 60px;
1802
+ width: 200px;
1803
+ background: var(--plex-bg-dark);
1804
+ border: 1px solid var(--plex-border);
1805
+ border-radius: var(--plex-radius-lg);
1806
+ box-shadow: var(--plex-shadow);
1807
+ z-index: var(--plex-z-panel);
1808
+ overflow: hidden;
1809
+ padding: 8px 0;
1810
+ }
1811
+
1812
+ /* Quality Badge */
1813
+ .quality-badge {
1814
+ display: inline-flex;
1815
+ align-items: center;
1816
+ justify-content: center;
1817
+ padding: 2px 6px;
1818
+ background: var(--plex-primary);
1819
+ border-radius: 3px;
1820
+ font-size: 10px;
1821
+ font-weight: 700;
1822
+ color: #000;
1823
+ text-transform: uppercase;
1824
+ margin-left: 8px;
1825
+ }
1826
+
1827
+ /* Section Divider */
1828
+ .settings-divider {
1829
+ height: 1px;
1830
+ background: var(--plex-border);
1831
+ margin: 8px 16px;
1832
+ }
1833
+
1834
+ /* Settings Group Label */
1835
+ .settings-group-label {
1836
+ padding: 8px 16px 4px;
1837
+ font-size: 11px;
1838
+ font-weight: 600;
1839
+ color: var(--plex-text-secondary);
1840
+ text-transform: uppercase;
1841
+ letter-spacing: 0.5px;
1842
+ }
1843
+
1844
+ /* Responsive Settings */
1845
+ @media (max-width: 768px) {
1846
+ .settings-panel {
1847
+ position: fixed;
1848
+ top: auto;
1849
+ bottom: 0;
1850
+ left: 0;
1851
+ right: 0;
1852
+ width: 100%;
1853
+ max-height: 60vh;
1854
+ border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;
1855
+ transform-origin: bottom center;
1856
+ }
1857
+
1858
+ .subtitles-settings-panel {
1859
+ position: fixed;
1860
+ top: auto;
1861
+ bottom: 0;
1862
+ left: 0;
1863
+ right: 0;
1864
+ width: 100%;
1865
+ max-height: 70vh;
1866
+ border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;
1867
+ }
1868
+
1869
+ .settings-item {
1870
+ padding: 14px 20px;
1871
+ }
1872
+
1873
+ .settings-option {
1874
+ padding: 14px 20px;
1875
+ }
1876
+ }
1877
+
1878
+ @media (max-width: 480px) {
1879
+ .settings-content {
1880
+ max-height: 50vh;
1881
+ }
1882
+
1883
+ .subtitle-setting-item {
1884
+ flex-wrap: wrap;
1885
+ }
1886
+
1887
+ .subtitle-setting-item label {
1888
+ flex: 0 0 100%;
1889
+ margin-bottom: 8px;
1890
+ }
1891
+
1892
+ .subtitle-setting-item input[type="range"] {
1893
+ flex: 1;
1894
+ }
1895
+ }
1896
+
1897
+ /* Animation for panel open/close */
1898
+ .settings-panel.closing {
1899
+ animation: settingsClose 0.15s ease forwards;
1900
+ }
1901
+
1902
+ @keyframes settingsClose {
1903
+ from {
1904
+ opacity: 1;
1905
+ transform: scale(1);
1906
+ }
1907
+ to {
1908
+ opacity: 0;
1909
+ transform: scale(0.95);
1910
+ }
1911
+ }
1912
+
1913
+ /* Keyboard Shortcut Hints */
1914
+ .shortcut-hint {
1915
+ display: inline-flex;
1916
+ align-items: center;
1917
+ justify-content: center;
1918
+ min-width: 24px;
1919
+ height: 24px;
1920
+ padding: 0 6px;
1921
+ background: rgba(255, 255, 255, 0.1);
1922
+ border: 1px solid var(--plex-border);
1923
+ border-radius: 4px;
1924
+ font-size: 11px;
1925
+ font-weight: 600;
1926
+ color: var(--plex-text-secondary);
1927
+ margin-left: auto;
1928
+ }
1929
+
1930
+ /* Audio Track Indicator */
1931
+ .audio-track-indicator {
1932
+ display: flex;
1933
+ align-items: center;
1934
+ gap: 4px;
1935
+ font-size: 12px;
1936
+ color: var(--plex-text-secondary);
1937
+ }
1938
+
1939
+ .audio-track-indicator .material-icons {
1940
+ font-size: 16px;
1941
+ }
1942
+
1943
+ /*# sourceMappingURL=plex-player.css.map */