aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'client/src')
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html320
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss20
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts24
-rw-r--r--client/src/sass/bootstrap.scss22
4 files changed, 258 insertions, 128 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index c1a46a373..f041101bf 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -701,7 +701,28 @@
701 701
702 <ng-template ngbNavContent> 702 <ng-template ngbNavContent>
703 703
704 <div class="form-row mt-5"> <!-- transcoding grid --> 704 <div class="form-row mt-4"> <!-- transcoding grid -->
705 <div class="form-group col-12 col-lg-4 col-xl-3"></div>
706 <div class="form-group form-group-right col-12 col-lg-8">
707
708 <div class="callout callout-info">
709 <span i18n>
710 Estimating a server's capacity to transcode and stream videos isn't easy and we can't tune PeerTube automatically.
711 </span>
712 <span i18n>
713 However, you may want to read our guidelines before tweaking the following values.
714 </span>
715
716 <div class="callout-container">
717 <a class="callout-link" target="_blank" rel="noopener noreferrer" href="https://docs.joinpeertube.org/#/admin-configuration?id=transcoding" i18n>Read guidelines</a>
718 </div>
719 </div>
720
721
722 </div>
723 </div>
724
725 <div class="form-row mt-2"> <!-- transcoding grid -->
705 <div class="form-group col-12 col-lg-4 col-xl-3"> 726 <div class="form-group col-12 col-lg-4 col-xl-3">
706 <div i18n class="inner-form-title">TRANSCODING</div> 727 <div i18n class="inner-form-title">TRANSCODING</div>
707 <div i18n class="inner-form-description"> 728 <div i18n class="inner-form-description">
@@ -714,89 +735,179 @@
714 735
715 <ng-container formGroupName="transcoding"> 736 <ng-container formGroupName="transcoding">
716 737
717 <div class="form-group"> 738 <div class="form-group mb-0 col-12 col-xl-11">
718 <my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled"> 739 <my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true">
719 <ng-template ptTemplate="label"> 740 <ng-template ptTemplate="label">
720 <ng-container i18n>Transcoding enabled</ng-container> 741 <ng-container i18n>Transcoding enabled</ng-container>
721 </ng-template> 742 </ng-template>
722 743
723 <ng-template ptTemplate="help">
724 <ng-container i18n>If you disable transcoding, many videos from your users will not work!</ng-container>
725 </ng-template>
726
727 <ng-container ngProjectAs="extra"> 744 <ng-container ngProjectAs="extra">
728 745
729 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> 746 <div class="callout callout-light pt-2 pb-0">
730 <my-peertube-checkbox 747 <label i18n>Input formats</label>
731 inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions"
732 i18n-labelText labelText="Allow additional extensions"
733 >
734 <ng-container ngProjectAs="description">
735 <span i18n>Allows users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, m2ts, .mxf, .nut videos.</span>
736 </ng-container>
737 </my-peertube-checkbox>
738 </div>
739 748
740 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
741 <my-peertube-checkbox
742 inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles"
743 i18n-labelText labelText="Allow audio files upload"
744 >
745 <ng-container ngProjectAs="description">
746 <span i18n>Allows users to upload audio files that will be merged with the preview file on upload.</span>
747 </ng-container>
748 </my-peertube-checkbox>
749 </div>
750
751 <ng-container formGroupName="webtorrent">
752 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> 749 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
753 <my-peertube-checkbox 750 <my-peertube-checkbox
754 inputName="transcodingWebTorrentEnabled" formControlName="enabled" 751 inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions"
755 i18n-labelText labelText="WebTorrent support enabled" 752 i18n-labelText labelText="Allow additional extensions"
756 > 753 >
757 <ng-template ptTemplate="help"> 754 <ng-container ngProjectAs="description">
758 <ng-container i18n> 755 <span i18n>Allows users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, m2ts, .mxf, or .nut videos.</span>
759 <p>If you also enabled HLS support, it will multiply videos storage by 2</p> 756 </ng-container>
760
761 <br />
762
763 <strong>If disabled, breaks federation with PeerTube instances < 2.1</strong>
764 </ng-container>
765 </ng-template>
766 </my-peertube-checkbox> 757 </my-peertube-checkbox>
767 </div> 758 </div>
768 </ng-container> 759
769
770 <ng-container formGroupName="hls">
771 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> 760 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
772 <my-peertube-checkbox 761 <my-peertube-checkbox
773 inputName="transcodingHlsEnabled" formControlName="enabled" 762 inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles"
774 i18n-labelText labelText="HLS with P2P support enabled" 763 i18n-labelText labelText="Allow audio files upload"
775 > 764 >
776 <ng-template ptTemplate="help"> 765 <ng-container ngProjectAs="description">
777 <ng-container i18n> 766 <div i18n>Allows users to upload .mp3, .ogg, .wma, .flac, .aac, or .ac3 audio files.</div>
778 <strong>Requires ffmpeg >= 4.1</strong> 767 <div i18n>The file will be merged in a still image video with the preview file on upload.</div>
779 768 </ng-container>
780 <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with the current default player:</p>
781 <ul>
782 <li>Resolution change is smoother</li>
783 <li>Faster playback in particular with long videos</li>
784 <li>More stable playback (less bugs/infinite loading)</li>
785 </ul>
786
787 <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p>
788 </ng-container>
789 </ng-template>
790 </my-peertube-checkbox> 769 </my-peertube-checkbox>
791 </div> 770 </div>
792 </ng-container> 771 </div>
772
773 <div class="callout callout-light pt-2 mt-2 pb-0">
774 <label i18n>Output formats</label>
775
776 <ng-container formGroupName="webtorrent">
777 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
778 <my-peertube-checkbox
779 inputName="transcodingWebTorrentEnabled" formControlName="enabled"
780 i18n-labelText labelText="WebTorrent enabled"
781 >
782 <ng-template ptTemplate="help">
783 <ng-container i18n>
784 <p>If you also enabled HLS support, it will multiply videos storage by 2</p>
785
786 <br />
787
788 <strong>If disabled, breaks federation with PeerTube instances < 2.1</strong>
789 </ng-container>
790 </ng-template>
791 </my-peertube-checkbox>
792 </div>
793 </ng-container>
794
795 <ng-container formGroupName="hls">
796 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
797 <my-peertube-checkbox
798 inputName="transcodingHlsEnabled" formControlName="enabled"
799 i18n-labelText labelText="HLS with P2P support enabled"
800 [recommended]="true"
801 >
802 <ng-template ptTemplate="help">
803 <ng-container i18n>
804 <strong>Requires ffmpeg >= 4.1</strong>
805
806 <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with plain WebTorrent:</p>
807 <ul>
808 <li>Resolution change is smoother</li>
809 <li>Faster playback especially with long videos</li>
810 <li>More stable playback (less bugs/infinite loading)</li>
811 </ul>
812
813 <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p>
814 </ng-container>
815 </ng-template>
816 </my-peertube-checkbox>
817 </div>
818 </ng-container>
819
820 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
821 <label i18n>Resolutions to generate per enabled format</label>
822
823 <div class="ml-2 mt-2 d-flex flex-column">
824 <ng-container formGroupName="resolutions">
825 <div class="form-group" *ngFor="let resolution of resolutions">
826 <my-peertube-checkbox
827 [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
828 labelText="{{ resolution.label }}"
829 >
830 <ng-template *ngIf="resolution.description" ptTemplate="help">
831 <div [innerHTML]="resolution.description"></div>
832 </ng-template>
833 </my-peertube-checkbox>
834 </div>
835 </ng-container>
836 </div>
837 </div>
838 </div>
793 839
794 </ng-container> 840 </ng-container>
795 </my-peertube-checkbox> 841 </my-peertube-checkbox>
796 </div> 842 </div>
797 843
844 </ng-container>
845
846 </div>
847 </div>
848
849 <div class="form-row mt-5"> <!-- transcoding live streams grid -->
850 <div class="form-group col-12 col-lg-4 col-xl-3">
851 <div i18n class="inner-form-title">TRANSCODING LIVE STREAMS</div>
852 <div i18n class="inner-form-description">
853 Same as above, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some.
854 </div>
855 </div>
856
857 <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
858
859 <ng-container formGroupName="live">
860 <ng-container formGroupName="transcoding">
861
862 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
863 <my-peertube-checkbox
864 inputName="liveTranscodingEnabled" formControlName="enabled"
865 >
866 <ng-template ptTemplate="label">
867 <ng-container i18n>Transcoding enabled for live streams</ng-container>
868 </ng-template>
869 </my-peertube-checkbox>
870 </div>
871
872 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
873 <label i18n for="liveTranscodingThreads">Live resolutions to generate</label>
874
875 <div class="ml-2 mt-2 d-flex flex-column">
876 <ng-container formGroupName="resolutions">
877 <div class="form-group" *ngFor="let resolution of liveResolutions">
878 <my-peertube-checkbox
879 [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
880 labelText="{{resolution.label}}"
881 >
882 <ng-template *ngIf="resolution.description" ptTemplate="help">
883 <div [innerHTML]="resolution.description"></div>
884 </ng-template>
885 </my-peertube-checkbox>
886 </div>
887 </ng-container>
888 </div>
889 </div>
890 </ng-container>
891 </ng-container>
892
893 </div>
894 </div>
895
896 <div class="form-row mt-5"> <!-- load repartition grid -->
897
898 <div class="form-group col-12 col-lg-4 col-xl-3">
899 <div i18n class="inner-form-title">LOAD REPARTITION</div>
900 <div i18n class="inner-form-description">
901 Share CPU power to prioritize one or the other. The total should not be above the number of available threads.
902 </div>
903 </div>
904
905 <div class="form-group form-group-right col-12 col-lg-8 col-xl-9">
906
907 <ng-container formGroupName="transcoding">
798 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> 908 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }">
799 <label i18n for="transcodingThreads">Transcoding threads</label> 909 <label i18n for="transcodingThreads">Transcoding threads</label>
910
800 <div class="peertube-select-container"> 911 <div class="peertube-select-container">
801 <select id="transcodingThreads" formControlName="threads" class="form-control"> 912 <select id="transcodingThreads" formControlName="threads" class="form-control">
802 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> 913 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
@@ -806,31 +917,29 @@
806 </div> 917 </div>
807 <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div> 918 <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div>
808 </div> 919 </div>
920 </ng-container>
809 921
810 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> 922 <ng-container formGroupName="live">
811 923 <ng-container formGroupName="transcoding">
812 <label i18n>Resolutions to generate</label> 924 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
813 925 <label i18n for="liveTranscodingThreads">Live transcoding threads</label>
814 <div class="ml-2 mt-2 d-flex flex-column"> 926 <div class="peertube-select-container">
815 <ng-container formGroupName="resolutions"> 927 <select id="liveTranscodingThreads" formControlName="threads" class="form-control">
816 <div class="form-group" *ngFor="let resolution of resolutions"> 928 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
817 <my-peertube-checkbox 929 {{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}}
818 [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id" 930 </option>
819 labelText="{{resolution.label}}" 931 </select>
820 > 932 </div>
821 <ng-template *ngIf="resolution.description" ptTemplate="help"> 933 <div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div>
822 <div [innerHTML]="resolution.description"></div>
823 </ng-template>
824 </my-peertube-checkbox>
825 </div>
826 </ng-container>
827 </div> 934 </div>
828 935 </ng-container>
829 </div>
830
831 </ng-container> 936 </ng-container>
832 937
938 <div *ngIf="getTotalTranscodingThreads().atMost" i18n>Transcoding will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }}.</div>
939 <div *ngIf="!getTotalTranscodingThreads().atMost" i18n>Transcoding will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }}.</div>
940
833 </div> 941 </div>
942
834 </div> 943 </div>
835 944
836 </ng-template> 945 </ng-template>
@@ -877,7 +986,7 @@
877 </div> 986 </div>
878 987
879 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> 988 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
880 <label i18n for="liveMaxInstanceLives">Max lives created on your instance (-1 for "unlimited")</label> 989 <label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance <span class="text-muted">(-1 for "unlimited")</span></label>
881 <div class="number-with-unit"> 990 <div class="number-with-unit">
882 <input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" /> 991 <input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" />
883 <span i18n>{form.value['live']['maxInstanceLives'], plural, =1 {live} other {lives}}</span> 992 <span i18n>{form.value['live']['maxInstanceLives'], plural, =1 {live} other {lives}}</span>
@@ -885,7 +994,7 @@
885 </div> 994 </div>
886 995
887 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> 996 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
888 <label i18n for="liveMaxUserLives">Max lives created per user (-1 for "unlimited")</label> 997 <label i18n for="liveMaxUserLives">Max simultaneous lives created per user <span class="text-muted">(-1 for "unlimited")</span></label>
889 <div class="number-with-unit"> 998 <div class="number-with-unit">
890 <input type="number" name="liveMaxUserLives" formControlName="maxUserLives" /> 999 <input type="number" name="liveMaxUserLives" formControlName="maxUserLives" />
891 <span i18n>{form.value['live']['maxUserLives'], plural, =1 {live} other {lives}}</span> 1000 <span i18n>{form.value['live']['maxUserLives'], plural, =1 {live} other {lives}}</span>
@@ -903,51 +1012,6 @@
903 ></ng-select> 1012 ></ng-select>
904 </div> 1013 </div>
905 </div> 1014 </div>
906
907 <ng-container formGroupName="transcoding">
908
909 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
910 <my-peertube-checkbox
911 inputName="liveTranscodingEnabled" formControlName="enabled"
912 i18n-labelText labelText="Enable live transcoding"
913 >
914 <ng-container ngProjectAs="description" i18n>
915 Requires a lot of CPU!
916 </ng-container>
917 </my-peertube-checkbox>
918 </div>
919
920 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
921 <label i18n for="liveTranscodingThreads">Live transcoding threads</label>
922 <div class="peertube-select-container">
923 <select id="liveTranscodingThreads" formControlName="threads" class="form-control">
924 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
925 {{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}}
926 </option>
927 </select>
928 </div>
929 <div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div>
930 </div>
931
932 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }">
933 <label i18n for="liveTranscodingThreads">Live resolutions to generate</label>
934
935 <div class="ml-2 mt-2 d-flex flex-column">
936 <ng-container formGroupName="resolutions">
937 <div class="form-group" *ngFor="let resolution of liveResolutions">
938 <my-peertube-checkbox
939 [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id"
940 labelText="{{resolution.label}}"
941 >
942 <ng-template *ngIf="resolution.description" ptTemplate="help">
943 <div [innerHTML]="resolution.description"></div>
944 </ng-template>
945 </my-peertube-checkbox>
946 </div>
947 </ng-container>
948 </div>
949 </div>
950 </ng-container>
951 </ng-container> 1015 </ng-container>
952 </my-peertube-checkbox> 1016 </my-peertube-checkbox>
953 </div> 1017 </div>
@@ -963,7 +1027,7 @@
963 1027
964 <ng-template ngbNavContent> 1028 <ng-template ngbNavContent>
965 1029
966 <div class="form-row mt-4"> <!-- cache grid --> 1030 <div class="form-row mt-5"> <!-- cache grid -->
967 <div class="form-group col-12 col-lg-4 col-xl-3"> 1031 <div class="form-group col-12 col-lg-4 col-xl-3">
968 <div i18n class="inner-form-title">CACHE</div> 1032 <div i18n class="inner-form-title">CACHE</div>
969 <div i18n class="inner-form-description"> 1033 <div i18n class="inner-form-description">
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
index d5352b472..6743879e7 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
@@ -103,3 +103,23 @@ ngb-tabset:not(.previews) ::ng-deep {
103 width: fit-content; 103 width: fit-content;
104 margin-top: 10px; 104 margin-top: 10px;
105} 105}
106
107.callout-container {
108 position: absolute;
109 display: flex;
110 height: 0;
111 width: 100%;
112 justify-content: right;
113
114 .callout-link {
115 @include peertube-button-link;
116
117 position: relative;
118 right: 3.3em;
119 top: .3em;
120 font-size: 90%;
121 color: pvar(--mainColor);
122 background-color: pvar(--mainBackgroundColor);
123 padding: 0 .3em;
124 }
125}
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index 7db65d038..7920600fc 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -119,6 +119,30 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A
119 .map(t => t.name) 119 .map(t => t.name)
120 } 120 }
121 121
122 getTotalTranscodingThreads () {
123 const transcodingEnabled = this.form.value['transcoding']['enabled']
124 const transcodingThreads = this.form.value['transcoding']['threads']
125 const liveTranscodingEnabled = this.form.value['live']['transcoding']['enabled']
126 const liveTranscodingThreads = this.form.value['live']['transcoding']['threads']
127
128 // checks whether all enabled method are on fixed values and not on auto (= 0)
129 let noneOnAuto = !transcodingEnabled || +transcodingThreads > 0
130 noneOnAuto &&= !liveTranscodingEnabled || +liveTranscodingThreads > 0
131
132 // count total of fixed value, repalcing auto by a single thread (knowing it will display "at least")
133 let value = 0
134 if (transcodingEnabled) value += +transcodingThreads || 1
135 if (liveTranscodingEnabled) value += +liveTranscodingThreads || 1
136
137 return {
138 value,
139 atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible
140 unit: value > 1
141 ? $localize`threads`
142 : $localize`thread`
143 }
144 }
145
122 getResolutionKey (resolution: string) { 146 getResolutionKey (resolution: string) {
123 return 'transcoding.resolutions.' + resolution 147 return 'transcoding.resolutions.' + resolution
124 } 148 }
diff --git a/client/src/sass/bootstrap.scss b/client/src/sass/bootstrap.scss
index 208c7f582..0bb349a45 100644
--- a/client/src/sass/bootstrap.scss
+++ b/client/src/sass/bootstrap.scss
@@ -361,3 +361,25 @@ ngb-tooltip-window {
361 display: none; 361 display: none;
362 } 362 }
363} 363}
364
365.callout {
366 padding: 1.25rem;
367 border: 1px solid #eee;
368 border-radius: .25rem;
369
370 & > label {
371 position: relative;
372 top: -5px;
373 left: -10px;
374 color: #6c757d !important;
375 }
376
377 &:not(.callout-light) {
378 border-left-width: .25rem;
379 }
380
381 &.callout-info {
382 border-color: pvar(--mainColorLightest);
383 border-left-color: pvar(--mainColor);
384 }
385}