`fitWidth` for `video-miniature`, fluid grid (#2830)
[oweals/peertube.git] / client / src / sass / player / peertube-skin.scss
1 @import '_variables';
2 @import '_mixins';
3 @import './_player-variables';
4
5 body {
6   --embedForegroundColor: #{$primary-foreground-color};
7
8   --embedBigPlayBackgroundColor: #{$primary-background-color};
9 }
10
11 @mixin big-play-button-triangle-size($triangle-size) {
12   width: $triangle-size;
13   height: $triangle-size;
14   top: calc(50% - #{$triangle-size / 2});
15   left: calc(53% - #{($triangle-size / 2)});
16 }
17
18 .video-js.vjs-peertube-skin {
19   font-size: $font-size;
20   color: pvar(--embedForegroundColor);
21
22   .vjs-dock-text {
23     padding-right: 10px;
24     background: linear-gradient(to bottom, rgba(0, 0, 0, .6) 0, rgba(0, 0, 0, 0.2) 70%, rgba(0, 0, 0, 0) 100%);
25   }
26
27   .vjs-dock-title,
28   .vjs-dock-description {
29     text-shadow: 0 0 2px rgba(0, 0, 0, .5);
30   }
31
32   .vjs-dock-description {
33     font-size: 11px;
34
35     .text::before {
36       margin-right: 4px;
37     }
38
39     .text::after {
40       margin-left: 4px;
41       transform: scale(-1, 1);
42     }
43   }
44
45   .vjs-button > .vjs-icon-placeholder::before {
46     line-height: $control-bar-height;
47   }
48
49   .vjs-volume-level::before {
50     content: ''; /* Remove Circle From Progress Bar */
51   }
52
53   .vjs-audio-button {
54     display: none;
55   }
56
57   .vjs-big-play-button {
58     outline: 0;
59     font-size: 6em;
60
61     $big-play-width: 1.2em;
62     $big-play-height: 1.2em;
63
64     border: 2px solid #fff;
65     border-radius: 100%;
66
67     left: 50%;
68     top: 50%;
69     width: $big-play-width;
70     height: $big-play-height;
71     line-height: $big-play-height;
72     margin-left: -($big-play-width / 2);
73     margin-top: -($big-play-height / 2);
74     transition: 0.4s opacity;
75
76     &::-moz-focus-inner {
77       border: 0;
78       padding: 0
79     }
80
81     .vjs-icon-placeholder::before {
82       @include big-play-button-triangle-size(45px);
83
84       content: '';
85       background-image: url('#{$assets-path}/player/images/big-play-button.svg');
86     }
87
88     &:hover {
89       opacity: 0.8;
90     }
91   }
92
93   // Small effect when we click on the play button
94   &.vjs-has-big-play-button-clicked {
95
96     .vjs-big-play-button, .vjs-poster {
97       display: block;
98       visibility: hidden;
99
100       &.vjs-big-play-button, &.vjs-big-play-button::before {
101         opacity: 0;
102         transition: visibility 0.2s, opacity 0.2s;
103       }
104
105       &.vjs-poster, &.vjs-poster::before {
106         opacity: 0;
107         transition: visibility 0.3s, opacity 0.3s;
108         transition-delay: 0.05s;
109       }
110     }
111   }
112
113   // Show poster and controls when playing audio-only content
114   &.vjs-playing-audio-only-content {
115     .vjs-poster {
116       display: block;
117       visibility: visible;
118     }
119
120     .vjs-control-bar {
121       opacity: $primary-foreground-opacity-hover;
122     }
123   }
124
125   // Hide the big play button on autoplay
126   &.vjs-has-autoplay {
127     .vjs-big-play-button {
128       display: none !important;
129     }
130   }
131
132   .vjs-control-bar,
133   .vjs-big-play-button,
134   .vjs-settings-dialog {
135     background-color: pvar(--embedBigPlayBackgroundColor);
136   }
137
138   .vjs-poster {
139     outline: none; /* Remove Blue Outline on Click*/
140     outline: 0;
141   }
142
143   .vjs-control-bar {
144     height: $control-bar-height;
145     background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.6));
146     box-shadow: 0 -15px 40px 10px rgba(0, 0, 0, 0.2);
147     text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
148
149     .vjs-progress-control,
150     .vjs-play-control,
151     .vjs-playback-rate,
152     .vjs-mute-control,
153     .vjs-volume-control,
154     .vjs-resolution-control,
155     .vjs-fullscreen-control,
156     .vjs-peertube-link,
157     .vjs-theater-control,
158     .vjs-settings
159     {
160       color: pvar(--embedForegroundColor) !important;
161
162       opacity: $primary-foreground-opacity;
163       transition: opacity .1s;
164
165       &:hover {
166         opacity: $primary-foreground-opacity-hover;
167       }
168     }
169
170     .vjs-current-time,
171     .vjs-duration,
172     .vjs-peertube {
173       color: pvar(--embedForegroundColor);
174       opacity: $primary-foreground-opacity;
175     }
176
177     .vjs-progress-control {
178       position: absolute;
179       z-index: 100; // On top of the progress bar
180       bottom: 29px;
181       width: calc(100% - (2 * #{$progress-margin}));
182       margin-left: $progress-margin;
183       height: 14px;
184
185       .vjs-slider {
186         margin: 0;
187         border-radius: 0;
188         background-color: rgba(255, 255, 255, .2);
189         height: 3px;
190         transition: none;
191
192         .vjs-play-progress {
193           background: pvar(--embedForegroundColor);
194
195           // Not display the circle if the progress is not hovered
196           &::before {
197             opacity: 0;
198             transition: opacity 0.1s ease;
199             font-size: 14px;
200
201             top: -0.3em;
202           }
203
204           .vjs-time-tooltip {
205             display: none;
206           }
207         }
208
209         .vjs-load-progress {
210           &, & div {
211             background: rgba(255, 255, 255, .2);
212           }
213         }
214       }
215     }
216
217     .vjs-progress-control:hover .vjs-slider,
218     .vjs-progress-control .vjs-slider.vjs-sliding {
219       height: 5px;
220
221       .vjs-play-progress::before {
222         opacity: 1;
223       }
224     }
225
226
227     .vjs-play-control {
228       @include disable-outline;
229
230       cursor: pointer;
231       font-size: $font-size;
232       margin-left: 1em;
233       width: 3em;
234     }
235
236     .vjs-time-control {
237       line-height: inherit;
238
239       &.vjs-current-time {
240         font-size: $font-size;
241         display: inline-block;
242         padding: 0;
243         margin-left: .5em;
244
245         .vjs-current-time-display {
246           line-height: calc(#{$control-bar-height} + 1px);
247
248           &::after {
249             content: "/";
250             margin: 0 1px 0 2px;
251           }
252         }
253       }
254
255       &.vjs-duration {
256         font-size: $font-size;
257         display: inline-block;
258         padding: 0;
259         .vjs-duration-display {
260           line-height: calc(#{$control-bar-height} + 1px);
261         }
262       }
263
264       &.vjs-remaining-time {
265         display: none;
266       }
267     }
268
269     .vjs-peertube {
270       width: 100%;
271       line-height: $control-bar-height;
272       text-align: right;
273       margin-right: 6px;
274       overflow: hidden;
275
276       .vjs-peertube-displayed {
277         display: block;
278       }
279
280       .vjs-peertube-hidden {
281         display: none;
282       }
283
284       .download-speed-number, .upload-speed-number, .peers-number, .http-fallback {
285         font-weight: $font-semibold;
286       }
287
288       .download-speed-text, .upload-speed-text, .peers-text, .http-fallback {
289         margin-right: 15px;
290       }
291
292       .icon {
293         &.icon-download {
294           background-image: url('#{$assets-path}/player/images/arrow-down.svg');
295         }
296
297         &.icon-upload {
298           background-image: url('#{$assets-path}/player/images/arrow-up.svg');
299         }
300       }
301     }
302
303     .vjs-next-video {
304       line-height: $control-bar-height;
305       text-align: right;
306
307       .icon {
308         &.icon-next {
309           mask-image: url('#{$assets-path}/player/images/next.svg');
310           background-color: white;
311           mask-size: cover;
312           transform: scale(2.2);
313         }
314       }
315     }
316
317     .vjs-peertube,
318     .vjs-next-video {
319       .icon {
320         display: inline-block;
321         width: 15px;
322         height: 15px;
323         background-size: contain;
324         vertical-align: middle;
325         background-repeat: no-repeat;
326         position: relative;
327         top: -1px;
328       }
329     }
330
331     .vjs-playback-rate {
332       font-size: 10px;
333       width: 37px !important;
334
335       .vjs-playback-rate-value {
336         font-size: 13px;
337         line-height: $control-bar-height;
338       }
339
340       .vjs-menu .vjs-menu-content {
341         width: 37px !important;
342       }
343     }
344
345     .vjs-mute-control {
346       @include disable-outline;
347
348       line-height: $control-bar-height;
349       padding: 0;
350       width: 30px;
351
352       .vjs-icon-placeholder {
353         display: inline-block;
354         width: 22px;
355         height: 22px;
356         vertical-align: middle;
357         background: url('#{$assets-path}/player/images/volume.svg') no-repeat;
358         background-size: contain;
359
360         &::before {
361           content: '';
362         }
363       }
364
365       &.vjs-vol-0 .vjs-icon-placeholder {
366         background: url('#{$assets-path}/player/images/volume-mute.svg') no-repeat;
367         background-size: contain;
368       }
369     }
370
371     .vjs-volume-control {
372       width: 30px;
373       margin: 0 5px 0 0;
374     }
375
376     .vjs-volume-bar {
377       background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcCAQAAACw95UnAAAAMElEQVRIx2NgoBL4n4YKGUYNHkEG4zJg1OCRYDCpBowaPJwMppbLRg0eNXjUYBLEAXWNUA6QNm1lAAAAAElFTkSuQmCC) no-repeat;
378       background-size: 22px 14px;
379       height: 100%;
380       width: 100%;
381       max-width: 22px;
382       max-height: 14px;
383       margin: 7px 4px;
384       border-radius: 0;
385       top: 3px;
386
387       .vjs-volume-level {
388         background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcAQAAAAAyhWABAAAAAnRSTlMAAHaTzTgAAAAZSURBVHgBYwAB/g9EUv+JokCqiaT+U4MCAPKPS7WUUOc1AAAAAElFTkSuQmCC) no-repeat;
389         background-size: 22px 14px;
390         max-width: 22px;
391         max-height: 14px;
392         height: 100%;
393       }
394
395       &:focus {
396         text-shadow: none;
397         box-shadow: none;
398       }
399     }
400
401     .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,
402     .vjs-volume-panel.vjs-volume-panel-horizontal:active,
403     .vjs-volume-panel.vjs-volume-panel-horizontal:focus,
404     .vjs-volume-panel.vjs-volume-panel-horizontal:hover {
405       width: 6em;
406       transition-property: none;
407     }
408
409     .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal {
410       width: 3em;
411       height: auto;
412     }
413
414     .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control {
415       transition-property: none;
416     }
417
418     .vjs-volume-panel {
419       .vjs-mute-control {
420         width: 2em;
421         z-index: 1;
422         padding: 0;
423       }
424
425       .vjs-volume-control {
426         display: inline-block;
427         position: relative;
428         left: 5px;
429         opacity: 1;
430         width: 3em;
431         height: auto;
432       }
433     }
434
435     .vjs-peertube-link {
436       @include disable-outline;
437       @include disable-default-a-behaviour;
438
439       text-decoration: none;
440       line-height: $control-bar-height;
441       font-weight: $font-semibold;
442       padding: 0 5px;
443     }
444
445     .vjs-theater-control {
446       @include disable-outline;
447
448       width: 37px;
449       margin-right: 1px;
450       cursor: pointer;
451
452       .vjs-icon-placeholder {
453         transition: transform 0.2s ease;
454         display: inline-block;
455         width: 22px;
456         height: 22px;
457         vertical-align: middle;
458         background: url('#{$assets-path}/player/images/theater.svg') no-repeat;
459         background-size: contain;
460
461         &::before {
462           content: '';
463         }
464       }
465     }
466
467     .vjs-fullscreen-control {
468       @include disable-outline;
469
470       width: 37px;
471       margin-right: 11px;
472
473       .vjs-icon-placeholder {
474         display: inline-block;
475         width: 22px;
476         height: 22px;
477         vertical-align: middle;
478         background: url('#{$assets-path}/player/images/fullscreen.svg') no-repeat;
479         background-size: contain;
480
481         &::before {
482           content: '';
483         }
484       }
485     }
486
487     .vjs-menu-button-popup {
488       font-weight: $font-semibold;
489       width: 50px;
490
491       .vjs-resolution-button {
492         @include disable-outline;
493       }
494
495       .vjs-menu {
496         top: 20px;
497         left: 0;
498
499         .vjs-menu-content {
500           width: 50px;
501           bottom: 20px;
502         }
503
504         li {
505           text-transform: none;
506           font-size: 13px;
507         }
508       }
509     }
510   }
511
512   @media screen and (max-width: 750px) {
513     .vjs-theater-control {
514       display: none;
515     }
516
517     .vjs-dock-text {
518       font-size: 16px;
519     }
520
521     .vjs-dock-description {
522       font-size: 9px;
523     }
524
525     .vjs-big-play-button {
526       font-size: 5em;
527       border-width: 3px;
528
529       .vjs-icon-placeholder::before {
530         @include big-play-button-triangle-size(32px);
531       }
532     }
533   }
534
535   @media screen and (max-width: 570px) {
536     .vjs-dock-text {
537       font-size: 14px;
538     }
539
540     .vjs-big-play-button {
541       font-size: 4.5em;
542       border-width: 2.5px;
543
544       .vjs-icon-placeholder::before {
545         @include big-play-button-triangle-size(27px);
546       }
547     }
548
549     .vjs-peertube {
550       padding: 0 !important;
551
552       .vjs-peertube-displayed {
553         display: none !important;
554       }
555     }
556   }
557
558   @media screen and (max-width: 300px) {
559     .vjs-dock-text {
560       font-size: 13px;
561     }
562
563     .vjs-big-play-button {
564       font-size: 3em;
565       border-width: 2px;
566
567       .vjs-icon-placeholder::before {
568         @include big-play-button-triangle-size(20px);
569       }
570     }
571
572     .vjs-volume-control {
573       display: none !important;
574     }
575
576     .vjs-peertube-link {
577       padding: 0 !important;
578     }
579
580     .vjs-settings {
581       width: 33px;
582     }
583   }
584
585   // Theater mode is enabled
586   &.vjs-theater-enabled {
587     .vjs-theater-control {
588       width: 30px;
589
590       .vjs-icon-placeholder {
591         transform: scale(0.8);
592       }
593     }
594   }
595
596   // On fullscreen, hide theater control
597   &.vjs-fullscreen {
598     .vjs-theater-control {
599       display: none;
600     }
601   }
602 }
603
604 // Play/pause animations
605 .vjs-has-started .vjs-play-control {
606   &.vjs-playing {
607     animation: remove-pause-button 0.25s ease;
608   }
609
610   &.vjs-paused {
611     animation: add-play-button 0.25s ease;
612   }
613
614   @keyframes remove-pause-button {
615     0% {
616       transform: rotate(90deg);
617     }
618     100% {
619       transform: rotate(0deg);
620     }
621   }
622
623   @keyframes add-play-button {
624     0% {
625       transform: rotate(-90deg);
626     }
627     100% {
628       transform: rotate(0deg);
629     }
630   }
631 }
632
633 // Error display disabled
634 .vjs-error:not(.vjs-error-display-enabled) {
635   .vjs-error-display {
636     display: none;
637   }
638
639   .vjs-loading-spinner {
640     display: block;
641   }
642 }
643
644 // Error display enabled
645 .vjs-error.vjs-error-display-enabled {
646   .vjs-error-display {
647     display: block;
648   }
649 }