fcad-core-dragon 2.0.0-beta.3 → 2.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/.eslintrc.cjs +81 -81
  4. package/CHANGELOG +13 -0
  5. package/README.md +71 -71
  6. package/bk.scss +117 -117
  7. package/package.json +8 -8
  8. package/src/$locales/en.json +145 -143
  9. package/src/$locales/fr.json +107 -105
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +1150 -1054
  12. package/src/components/AppBaseButton.test.js +22 -0
  13. package/src/components/AppBaseButton.vue +93 -87
  14. package/src/components/AppBaseErrorDisplay.vue +438 -438
  15. package/src/components/AppBaseFlipCard.vue +84 -84
  16. package/src/components/AppBaseModule.vue +1657 -1673
  17. package/src/components/AppBasePage.vue +742 -779
  18. package/src/components/AppBasePopover.vue +41 -41
  19. package/src/components/AppCompAudio.vue +265 -234
  20. package/src/components/AppCompBranchButtons.vue +556 -552
  21. package/src/components/AppCompButtonProgress.vue +121 -126
  22. package/src/components/AppCompCarousel.vue +328 -298
  23. package/src/components/AppCompInputCheckBoxNext.vue +200 -195
  24. package/src/components/AppCompInputDropdownNext.vue +201 -159
  25. package/src/components/AppCompInputRadioNext.vue +152 -152
  26. package/src/components/AppCompInputTextNext.vue +125 -106
  27. package/src/components/AppCompInputTextTableNext.vue +142 -141
  28. package/src/components/AppCompInputTextToFillDropdownNext.vue +238 -230
  29. package/src/components/AppCompInputTextToFillNext.vue +171 -171
  30. package/src/components/AppCompJauge.vue +74 -74
  31. package/src/components/AppCompMenu.vue +25 -10
  32. package/src/components/AppCompMenuItem.vue +228 -228
  33. package/src/components/AppCompNavigation.vue +972 -960
  34. package/src/components/AppCompNoteCall.vue +159 -133
  35. package/src/components/AppCompNoteCredit.vue +490 -292
  36. package/src/components/AppCompPlayBar.vue +1217 -1218
  37. package/src/components/AppCompPlayBarNext.vue +2060 -2052
  38. package/src/components/AppCompPlayBarProgress.vue +82 -82
  39. package/src/components/AppCompPopUpNext.vue +500 -503
  40. package/src/components/AppCompQuizNext.vue +2908 -2904
  41. package/src/components/AppCompQuizRecall.vue +298 -276
  42. package/src/components/AppCompSVGNext.vue +347 -347
  43. package/src/components/AppCompSettingsMenu.vue +172 -172
  44. package/src/components/AppCompTableOfContent.vue +386 -387
  45. package/src/components/AppCompTranscript.vue +24 -24
  46. package/src/components/AppCompVideoPlayer.vue +368 -368
  47. package/src/components/BaseModule.vue +55 -72
  48. package/src/components/tests__/AppBaseButton.spec.js +53 -0
  49. package/src/composables/useQuiz.js +206 -206
  50. package/src/externalComps/ModuleView.vue +22 -22
  51. package/src/externalComps/SummaryView.vue +91 -91
  52. package/src/main.js +272 -272
  53. package/src/mixins/$mediaMixins.js +819 -819
  54. package/src/mixins/timerMixin.js +155 -155
  55. package/src/module/stores/appStore.js +954 -893
  56. package/src/module/xapi/ADL.js +380 -376
  57. package/src/module/xapi/Crypto/Hasher.js +241 -241
  58. package/src/module/xapi/Crypto/WordArray.js +278 -278
  59. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  60. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  61. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  62. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  63. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  64. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  65. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  66. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  67. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  68. package/src/module/xapi/Statement/agent.js +55 -55
  69. package/src/module/xapi/Statement/index.js +259 -259
  70. package/src/module/xapi/Statement/statement.js +253 -253
  71. package/src/module/xapi/launch.js +157 -157
  72. package/src/module/xapi/utils.js +167 -167
  73. package/src/module/xapi/verbs.js +294 -294
  74. package/src/module/xapi/wrapper.js +1963 -1963
  75. package/src/module/xapi/xapiStatement.js +444 -444
  76. package/src/plugins/bus.js +8 -8
  77. package/src/plugins/gsap.js +14 -14
  78. package/src/plugins/helper.js +355 -308
  79. package/src/plugins/i18n.js +44 -44
  80. package/src/plugins/idb.js +227 -219
  81. package/src/plugins/save.js +37 -37
  82. package/src/plugins/scorm.js +287 -287
  83. package/src/plugins/xapi.js +11 -11
  84. package/src/public/index.html +33 -33
  85. package/src/router/index.js +48 -43
  86. package/src/router/routes.js +312 -312
  87. package/src/shared/generalfuncs.js +210 -210
  88. package/src/shared/validators.js +926 -1069
  89. package/vitest.config.js +19 -0
  90. package/vite.config.js +0 -27
@@ -1,298 +1,328 @@
1
- <!--
2
- @ Description: This component is used to display a carousel.
3
- @ What it does: Create an html element including an array of slides. These slides are objects including required property (imgSrc) and optional properties (imgAlt, Title, Hypertext).
4
- -->
5
-
6
- <template>
7
- <section id="carousel" :aria-label="$t('text.carousel')">
8
- <div class="carousel-inner">
9
- <div id="mycarousel-slides" class="carousel-slides" aria-live="polite">
10
- <div
11
- v-for="(slide, index) in slides"
12
- :key="index"
13
- class="carousel-slide"
14
- :class="{
15
- current: currentSlide == index + 1,
16
- prev: currentSlide >= index + 2,
17
- next: currentSlide <= index
18
- }"
19
- role="group"
20
- :aria-hidden="!(currentSlide == index + 1)"
21
- >
22
- <span class="sr-only">
23
- {{
24
- $t('text.slide') +
25
- ' ' +
26
- (index + 1) +
27
- ' ' +
28
- $t('text.of') +
29
- ' ' +
30
- slideLength
31
- }}
32
- </span>
33
- <div
34
- class="carousel-image"
35
- :class="{ 'full-width': !(slide.title || slide.hypertext) }"
36
- >
37
- <img
38
- :src="slide.imgSrc"
39
- :alt="slide.imgAlt"
40
- :aria-hidden="slide.imgAlt == ' ' || !slide.imgAlt ? true : false"
41
- />
42
- </div>
43
- <div v-if="slide.title || slide.hypertext" class="carousel-text">
44
- <h3 v-if="slide.title">
45
- {{ slide.title }}
46
- </h3>
47
- <div v-html="slide.hypertext"></div>
48
- </div>
49
- </div>
50
- </div>
51
- <div class="carousel-controls">
52
- <app-base-button
53
- id="carousel-btn-prev"
54
- class="carousel-btn"
55
- :aria-label="$t('button.carousel_prev')"
56
- aria-controls="mycarousel-slides"
57
- :title="$t('button.carousel_prev')"
58
- :disabled="disablePrev"
59
- :aria-disabled="disablePrev"
60
- @click="prevSlide()"
61
- >
62
- <svg>
63
- <use href="#fleche-gauche-icon"></use>
64
- </svg>
65
- </app-base-button>
66
- <app-base-button
67
- id="carousel-btn-next"
68
- class="carousel-btn"
69
- :aria-label="$t('button.carousel_next')"
70
- aria-controls="mycarousel-slides"
71
- :title="$t('button.carousel_next')"
72
- :disabled="disableNext"
73
- :aria-disabled="disableNext"
74
- @click="nextSlide()"
75
- >
76
- <svg>
77
- <use href="#fleche-droite-icon"></use>
78
- </svg>
79
- </app-base-button>
80
- </div>
81
- </div>
82
- <div class="carousel-index">
83
- <p aria-hidden="true">{{ currentSlide }}/{{ slideLength }}</p>
84
- </div>
85
- </section>
86
- </template>
87
-
88
- <script>
89
- export default {
90
- name: 'AppCompSlider',
91
- props: {
92
- slides: { type: Array, required: true } //Array of slides {imgSrc, imgAlt, title, hypertext}
93
- },
94
- data() {
95
- return {
96
- currentSlide: 1, //Slide management
97
- requiredProperties: ['imgSrc'], //For slides validation
98
- optionalProperties: ['title', 'imgAlt', 'hypertext'] //For slides validation
99
- }
100
- },
101
- computed: {
102
- disablePrev() {
103
- return !(this.currentSlide > 1)
104
- },
105
- disableNext() {
106
- return !(this.currentSlide < this.slideLength)
107
- },
108
- slideLength() {
109
- return this.slides.length
110
- }
111
- },
112
- mounted() {
113
- //Validating slides
114
- if (Array.isArray(this.slides) && this.slideLength > 0) {
115
- //Validate properties for all the slides
116
- for (const slide of this.slides) {
117
- this.validateProperties(
118
- this.requiredProperties,
119
- this.optionalProperties,
120
- slide
121
- )
122
- }
123
- } else {
124
- console.warn(
125
- `%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
126
- 'background: orange; color: white; display: block; margin:5px;'
127
- )
128
- }
129
- },
130
- methods: {
131
- prevSlide() {
132
- if (this.currentSlide > 1) {
133
- this.currentSlide--
134
- }
135
- },
136
- nextSlide() {
137
- if (this.currentSlide < this.slideLength) {
138
- this.currentSlide++
139
- }
140
- },
141
- //Validate the properties of a specific object (currentObject)
142
- validateProperties(requiredProperties, optionalProperties, currentObject) {
143
- let allProperties = requiredProperties.concat(optionalProperties)
144
- let currentProperties = Object.keys(currentObject)
145
- let wrongProperties = this.checkerWrong(allProperties, currentProperties)
146
- let missingRequired = this.checkerMissing(
147
- requiredProperties,
148
- currentProperties
149
- )
150
-
151
- //Validate if all properties in currentObject are valid
152
- if (wrongProperties.length > 0) {
153
- console.warn(
154
- `%c WARNING!>>> AppCompSlider : slides ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
155
- 'background: orange; color: white; display: block; margin:5px;'
156
- )
157
- }
158
- //Validate if all required properties are present in currentObject
159
- if (missingRequired.length > 0) {
160
- console.warn(
161
- `%c WARNING!>>> AppCompQuizSlider : slides missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
162
- 'background: orange; color: white; display: block; margin:5px;'
163
- )
164
- }
165
- },
166
- //Get all the invalids properties from the object
167
- /*Add element from target array that are NOT in arr to the wrongArray*/
168
- checkerWrong(arr, target) {
169
- let wrongArray = []
170
- target.every((v) => {
171
- if (arr.includes(v)) {
172
- return true
173
- } else {
174
- wrongArray.push(v)
175
- return true
176
- }
177
- })
178
- return wrongArray
179
- },
180
- //Get all the required properties that are missing from the object
181
- /*Add element from the arr that are NOT in target arr to the missingArray*/
182
- checkerMissing(arr, target) {
183
- let missingArray = []
184
- arr.every((v) => {
185
- if (target.includes(v)) {
186
- return true
187
- } else {
188
- missingArray.push(v)
189
- return true
190
- }
191
- })
192
- return missingArray
193
- }
194
- }
195
- }
196
- </script>
197
- <style lang="scss">
198
- #carousel {
199
- width: max(100%, 350px);
200
- }
201
-
202
- .carousel-inner {
203
- position: relative;
204
- height: 100%;
205
- width: 100%;
206
- display: flex;
207
- justify-content: center;
208
- overflow: initial;
209
- }
210
-
211
- .carousel-slides {
212
- position: relative;
213
- height: 100%;
214
- width: calc(
215
- 100% - 136px
216
- ); //add 68px each side of the carousel for the buttons
217
- display: flex;
218
- flex-direction: row;
219
- overflow: hidden;
220
- }
221
-
222
- .carousel-slide {
223
- min-width: 100%;
224
- width: 100%;
225
- display: flex;
226
- flex-direction: row;
227
- opacity: 0.5;
228
- transition: all 0.6s ease-out;
229
- position: relative;
230
- @media screen and (max-width: 1000px) {
231
- flex-direction: column;
232
- }
233
- &.current {
234
- opacity: 1;
235
- }
236
- &.prev {
237
- margin-left: -100%;
238
- }
239
- }
240
-
241
- .carousel-image {
242
- width: 60%;
243
- height: 100%;
244
- display: flex;
245
- justify-content: center;
246
- &.full-width {
247
- width: 100%;
248
- }
249
- @media screen and (max-width: 1000px) {
250
- width: 100%;
251
- max-height: 250px;
252
- }
253
- img {
254
- max-width: 100%;
255
- width: 100%;
256
- min-height: 300px;
257
- object-fit: contain;
258
- @media screen and (max-width: 1000px) {
259
- min-height: 250px;
260
- max-height: 250px;
261
- }
262
- }
263
- }
264
-
265
- .carousel-text {
266
- width: 40%;
267
- height: 100%;
268
- padding: 48px 24px 32px 24px;
269
-
270
- @media screen and (max-width: 1000px) {
271
- width: 100%;
272
- }
273
- }
274
-
275
- .carousel-index {
276
- margin-top: 20px;
277
- display: flex;
278
- justify-content: center;
279
- }
280
-
281
- .carousel-controls {
282
- position: absolute;
283
- width: 75%;
284
- top: calc(50% - 25px); //Center buttons
285
-
286
- @media screen and (min-width: 510px) {
287
- width: 100%;
288
- }
289
- & {
290
- display: flex;
291
- flex-direction: row;
292
- justify-content: space-between;
293
- z-index: 3;
294
- user-select: none;
295
- min-width: 300px;
296
- }
297
- }
298
- </style>
1
+ <!--
2
+ @ Description: This component is used to display a carousel.
3
+ @ What it does: Create an html element including an array of slides. These slides are objects including required property (imgSrc) and optional properties (imgAlt, Title, Hypertext).
4
+ -->
5
+
6
+ <template v-if="slides">
7
+ <section id="carousel" :aria-label="$t('text.carousel')">
8
+ <app-base-error-display
9
+ v-if="errorsSlider.length"
10
+ :error-group="'component'"
11
+ :error-title="'ERREUR: CRÉATION CAROUSEL'"
12
+ :errors-list="errorsSlider"
13
+ ></app-base-error-display>
14
+ <template v-else>
15
+ <div class="carousel-inner">
16
+ <div id="mycarousel-slides" class="carousel-slides" aria-live="polite">
17
+ <div
18
+ v-for="(slide, index) in slides"
19
+ :key="index"
20
+ class="carousel-slide"
21
+ :class="{
22
+ current: currentSlide == index + 1,
23
+ prev: currentSlide >= index + 2,
24
+ next: currentSlide <= index
25
+ }"
26
+ role="group"
27
+ :aria-hidden="!(currentSlide == index + 1)"
28
+ >
29
+ <span class="sr-only">
30
+ {{
31
+ $t('text.slide') +
32
+ ' ' +
33
+ (index + 1) +
34
+ ' ' +
35
+ $t('text.of') +
36
+ ' ' +
37
+ slideLength
38
+ }}
39
+ </span>
40
+ <div
41
+ class="carousel-image"
42
+ :class="{ 'full-width': !(slide.title || slide.hypertext) }"
43
+ >
44
+ <img
45
+ :src="slide.imgSrc"
46
+ :alt="slide.imgAlt"
47
+ :aria-hidden="
48
+ slide.imgAlt == ' ' || !slide.imgAlt ? true : false
49
+ "
50
+ />
51
+ </div>
52
+ <div v-if="slide.title || slide.hypertext" class="carousel-text">
53
+ <h3 v-if="slide.title">
54
+ {{ slide.title }}
55
+ </h3>
56
+ <div v-html="slide.hypertext"></div>
57
+ </div>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="carousel-controls">
62
+ <app-base-button
63
+ id="carousel-btn-prev"
64
+ class="carousel-btn"
65
+ :aria-label="$t('button.carousel_prev')"
66
+ aria-controls="mycarousel-slides"
67
+ :title="$t('button.carousel_prev')"
68
+ :aria-disabled="disablePrev"
69
+ :is-disabled="disablePrev"
70
+ :disabled="disablePrev"
71
+ @click="prevSlide()"
72
+ >
73
+ <svg>
74
+ <use href="#fleche-gauche-icon"></use>
75
+ </svg>
76
+ </app-base-button>
77
+ <app-base-button
78
+ id="carousel-btn-next"
79
+ class="carousel-btn"
80
+ :aria-label="$t('button.carousel_next')"
81
+ aria-controls="mycarousel-slides"
82
+ :title="$t('button.carousel_next')"
83
+ :aria-disabled="disableNext"
84
+ :is-disabled="disableNext"
85
+ :disabled="disableNext"
86
+ @click="nextSlide()"
87
+ >
88
+ <svg>
89
+ <use href="#fleche-droite-icon"></use>
90
+ </svg>
91
+ </app-base-button>
92
+ </div>
93
+ </div>
94
+ </template>
95
+ <div class="carousel-index">
96
+ <p aria-hidden="true">{{ currentSlide }}/{{ slideLength }}</p>
97
+ </div>
98
+ </section>
99
+ </template>
100
+
101
+ <script>
102
+ import AppBaseErrorDisplay from './AppBaseErrorDisplay.vue'
103
+ export default {
104
+ name: 'AppCompSlider',
105
+ components: { AppBaseErrorDisplay },
106
+ props: {
107
+ slides: { type: Array, required: true }, //Array of slides {imgSrc, imgAlt, title, hypertext}
108
+ name: { type: String, default: 'toto cool' }
109
+ },
110
+ data() {
111
+ return {
112
+ currentSlide: null, //Slide management
113
+ requiredProperties: ['imgSrc'], //For slides validation
114
+ optionalProperties: ['title', 'imgAlt', 'hypertext'], //For slides validation
115
+ errorsSlider: []
116
+ }
117
+ },
118
+ computed: {
119
+ disablePrev() {
120
+ return !(this.currentSlide > 1)
121
+ },
122
+ disableNext() {
123
+ return !(this.currentSlide < this.slideLength)
124
+ },
125
+ slideLength() {
126
+ return this.slides ? this.slides.length : 0
127
+ }
128
+ },
129
+ created() {
130
+ this.currentSlide = this.slides && this.slides.length ? 1 : 0
131
+ },
132
+ mounted() {
133
+ this.validateCarousel()
134
+ },
135
+ methods: {
136
+ prevSlide() {
137
+ if (this.currentSlide > 1) {
138
+ this.currentSlide--
139
+ }
140
+ },
141
+ nextSlide() {
142
+ if (this.currentSlide < this.slideLength) {
143
+ this.currentSlide++
144
+ }
145
+ },
146
+ validateCarousel() {
147
+ //Validating slides
148
+
149
+ if (Array.isArray(this.slides) && this.slideLength > 0) {
150
+ //Validate properties for all the slides
151
+ for (const slide of this.slides) {
152
+ this.validateProperties(
153
+ this.requiredProperties,
154
+ this.optionalProperties,
155
+ slide
156
+ )
157
+ }
158
+ } else {
159
+ let msg = `Le corrousel doit avoit au moins un element.`
160
+ this.errorsSlider.push(msg)
161
+ console.warn(
162
+ `%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
163
+ 'background: orange; color: white; display: block; margin:5px;'
164
+ )
165
+ }
166
+ },
167
+ //Validate the properties of a specific object (currentObject)
168
+ validateProperties(requiredProperties, optionalProperties, currentObject) {
169
+ let allProperties = requiredProperties.concat(optionalProperties)
170
+ let currentProperties = Object.keys(currentObject)
171
+ let wrongProperties = this.checkerWrong(allProperties, currentProperties)
172
+ let missingRequired = this.checkerMissing(
173
+ requiredProperties,
174
+ currentProperties
175
+ )
176
+
177
+ //Validate if all properties in currentObject are valid
178
+ if (wrongProperties.length > 0) {
179
+ console.warn(
180
+ `%c WARNING!>>> AppCompSlider : slides ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
181
+ 'background: orange; color: white; display: block; margin:5px;'
182
+ )
183
+ let msg = `Attribut(s) invalide(s): <i>${wrongProperties}</i> . Consultez la console pour plus de details.`
184
+ this.errorsSlider.push(msg)
185
+ }
186
+ //Validate if all required properties are present in currentObject
187
+ if (missingRequired.length > 0) {
188
+ console.warn(
189
+ `%c WARNING!>>> AppCompQuizSlider : slides missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
190
+ 'background: orange; color: white; display: block; margin:5px;'
191
+ )
192
+ let msg = `Une/certaines propriété(s) sont manquante(s). Consultez la console pour plus de details.`
193
+ this.errorsSlider.push(msg)
194
+ }
195
+ },
196
+ //Get all the invalids properties from the object
197
+ /*Add element from target array that are NOT in arr to the wrongArray*/
198
+ checkerWrong(arr, target) {
199
+ let wrongArray = []
200
+ target.every((v) => {
201
+ if (arr.includes(v)) {
202
+ return true
203
+ } else {
204
+ wrongArray.push(v)
205
+ return true
206
+ }
207
+ })
208
+ return wrongArray
209
+ },
210
+ //Get all the required properties that are missing from the object
211
+ /*Add element from the arr that are NOT in target arr to the missingArray*/
212
+ checkerMissing(arr, target) {
213
+ let missingArray = []
214
+ arr.every((v) => {
215
+ if (target.includes(v)) {
216
+ return true
217
+ } else {
218
+ missingArray.push(v)
219
+ return true
220
+ }
221
+ })
222
+ return missingArray
223
+ }
224
+ }
225
+ }
226
+ </script>
227
+ <style lang="scss">
228
+ #carousel {
229
+ width: max(100%, 350px);
230
+ }
231
+
232
+ .carousel-inner {
233
+ position: relative;
234
+ height: 100%;
235
+ width: 100%;
236
+ display: flex;
237
+ justify-content: center;
238
+ overflow: initial;
239
+ }
240
+
241
+ .carousel-slides {
242
+ position: relative;
243
+ height: 100%;
244
+ width: calc(
245
+ 100% - 136px
246
+ ); //add 68px each side of the carousel for the buttons
247
+ display: flex;
248
+ flex-direction: row;
249
+ overflow: hidden;
250
+ }
251
+
252
+ .carousel-slide {
253
+ min-width: 100%;
254
+ width: 100%;
255
+ display: flex;
256
+ flex-direction: row;
257
+ opacity: 0.5;
258
+ transition: all 0.6s ease-out;
259
+ position: relative;
260
+ @media screen and (max-width: 1000px) {
261
+ flex-direction: column;
262
+ }
263
+ &.current {
264
+ opacity: 1;
265
+ }
266
+ &.prev {
267
+ margin-left: -100%;
268
+ }
269
+ }
270
+
271
+ .carousel-image {
272
+ width: 60%;
273
+ height: 100%;
274
+ display: flex;
275
+ justify-content: center;
276
+ &.full-width {
277
+ width: 100%;
278
+ }
279
+ @media screen and (max-width: 1000px) {
280
+ width: 100%;
281
+ max-height: 250px;
282
+ }
283
+ img {
284
+ max-width: 100%;
285
+ width: 100%;
286
+ min-height: 300px;
287
+ object-fit: contain;
288
+ @media screen and (max-width: 1000px) {
289
+ min-height: 250px;
290
+ max-height: 250px;
291
+ }
292
+ }
293
+ }
294
+
295
+ .carousel-text {
296
+ width: 40%;
297
+ height: 100%;
298
+ padding: 48px 24px 32px 24px;
299
+
300
+ @media screen and (max-width: 1000px) {
301
+ width: 100%;
302
+ }
303
+ }
304
+
305
+ .carousel-index {
306
+ margin-top: 20px;
307
+ display: flex;
308
+ justify-content: center;
309
+ }
310
+
311
+ .carousel-controls {
312
+ position: absolute;
313
+ width: 75%;
314
+ top: calc(50% - 25px); //Center buttons
315
+
316
+ @media screen and (min-width: 510px) {
317
+ width: 100%;
318
+ }
319
+ & {
320
+ display: flex;
321
+ flex-direction: row;
322
+ justify-content: space-between;
323
+ z-index: 3;
324
+ user-select: none;
325
+ min-width: 300px;
326
+ }
327
+ }
328
+ </style>