hds-web 1.21.2 → 1.21.4
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.
- package/dist/index.css +2 -2
- package/dist/index.es.css +2 -2
- package/dist/index.es.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/HDS/components/Cards/StoryCard/index.js +2 -0
- package/src/HDS/components/Cards/StoryCard/storysm.js +113 -0
- package/src/HDS/components/Cards/StoryCard/storyxl.js +140 -0
- package/src/HDS/components/Cards/index.js +2 -1
- package/src/HDS/components/Carousels/customerStories.js +176 -0
- package/src/HDS/components/Carousels/index.js +2 -1
- package/src/HDS/components/Hero/h2.js +2 -3
- package/src/HDS/components/Tables/tableA.js +0 -1
- package/src/HDS/components/Tables/tableC.js +0 -1
- package/src/index.css +33 -0
- package/src/styles/tailwind.css +200 -5
package/package.json
CHANGED
@@ -0,0 +1,113 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { Icon } from "../../common-components/Icon";
|
4
|
+
import { HDSColor } from '../../../foundation/ColorPalette'
|
5
|
+
import { Typography } from '../../../foundation/Typography'
|
6
|
+
import { motion } from "framer-motion";
|
7
|
+
import { HDSButton } from '../../Buttons'
|
8
|
+
|
9
|
+
export default function StoryCard(props) {
|
10
|
+
return (
|
11
|
+
<>
|
12
|
+
<a
|
13
|
+
href={props.linkUrl}
|
14
|
+
className={`rounded-2xl hover:shadow-xl p-8 h-full flex flex-col justify-between group/sc border border-neutral-200 hover:border-opacity-0 min-h-[260px] group`}
|
15
|
+
>
|
16
|
+
|
17
|
+
<>
|
18
|
+
<div className='flex items-center justify-between'>
|
19
|
+
{props.brandImageUrl && props.brandImageAlt && (
|
20
|
+
<div className="max-w-[190px]">
|
21
|
+
<img src={props.brandImageUrl} alt={props.brandImageAlt} className='max-w-[100px]' />
|
22
|
+
</div>
|
23
|
+
)
|
24
|
+
|
25
|
+
}
|
26
|
+
{props.iconVariant &&
|
27
|
+
(
|
28
|
+
<div className="flex flex-row relative ">
|
29
|
+
<div className="group-hover/sc:opacity-0 left-0 absolute">
|
30
|
+
{/* <Icon
|
31
|
+
height={'w-6 h-6 stroke-[1.5px] stroke-blue-400'}
|
32
|
+
variant={props.iconArrowVariant}
|
33
|
+
strokeColor={props.iconArrowStrokeColor}
|
34
|
+
strokeClass={HDSColor(props.iconArrowStrokeClass)}
|
35
|
+
/> */}
|
36
|
+
</div>
|
37
|
+
{props.iconTag &&
|
38
|
+
(
|
39
|
+
<div className=" gap-2 transition-all duration-300 group-hover/sc:opacity-100 inline-flex flex-row translate-x-0 group-hover/sc:-translate-x-5">
|
40
|
+
<Icon
|
41
|
+
height={'w-6 h-6 stroke-[1.5px] stroke-blue-400'}
|
42
|
+
variant={props.iconArrowVariant}
|
43
|
+
strokeColor={props.iconArrowStrokeColor}
|
44
|
+
strokeClass={HDSColor(props.iconArrowStrokeClass)}
|
45
|
+
/>
|
46
|
+
<div
|
47
|
+
className=" opacity-0 group-hover/sc:opacity-100 transition-opacity duration-300 ">
|
48
|
+
<Typography textStyle='body3c' className='hidden group-hover/sc:block'>{props.iconTag}</Typography>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
)
|
52
|
+
}
|
53
|
+
</div>
|
54
|
+
|
55
|
+
)
|
56
|
+
}
|
57
|
+
</div>
|
58
|
+
{props.description &&
|
59
|
+
(
|
60
|
+
<div>
|
61
|
+
<div className="translate-y-10 group-hover/sc:translate-y-0 duration-300 transition-all">
|
62
|
+
<Typography
|
63
|
+
textStyle="body3"
|
64
|
+
className={`${HDSColor(props.descTextColor)} mt-2`}>
|
65
|
+
{props.description}
|
66
|
+
</Typography>
|
67
|
+
</div>
|
68
|
+
<div className="translate-y-8 transition-all group-hover/sc:translate-y-0 opacity-0 group-hover/sc:opacity-100 duration-300 group-hover/sc:flex">
|
69
|
+
<div className="flex">
|
70
|
+
<HDSButton
|
71
|
+
label={props.readMoreBtn.cta_text}
|
72
|
+
type='secondaryLink'
|
73
|
+
leftIconVariant='none'
|
74
|
+
rightIconVariant='none'
|
75
|
+
state='default'
|
76
|
+
size='sm'
|
77
|
+
rightAnimatedArrow={true}
|
78
|
+
rightAnimatedArrowColor='#3970FD'
|
79
|
+
animatedHoverStroke='#3970FD'
|
80
|
+
btnTextColorClass='text-blue-500'
|
81
|
+
btnTextHoverClass=''
|
82
|
+
className=' mt-[14px]'
|
83
|
+
/>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
|
89
|
+
)}
|
90
|
+
</>
|
91
|
+
|
92
|
+
</a>
|
93
|
+
</>
|
94
|
+
)
|
95
|
+
}
|
96
|
+
|
97
|
+
StoryCard.defaultProps = {
|
98
|
+
descTextColor: '',
|
99
|
+
iconTag: 'Customer Stories',
|
100
|
+
titleTextColor: '',
|
101
|
+
brandImageUrl: 'https://res.cloudinary.com/hasura-cms-uploads/image/upload/v1687778913/image_16_a725262c4e.png',
|
102
|
+
brandImageAlt: 'pipe',
|
103
|
+
linkUrl: '#',
|
104
|
+
iconVariant: 'videorecorder',
|
105
|
+
iconStrokeColor: 'blue-500',
|
106
|
+
iconArrowVariant: 'arrownarrowupright',
|
107
|
+
iconArrowStrokeColor: 'blue-400',
|
108
|
+
title: 'Webinar',
|
109
|
+
description: 'Model Level Authorization System for GraphQL with Hasura Model Level Authorization System for GraphQL with Hasura Model Level Authorization System for GraphQL with Hasura',
|
110
|
+
readMoreBtn: {
|
111
|
+
cta_text: 'Read More'
|
112
|
+
}
|
113
|
+
};
|
@@ -0,0 +1,140 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import { Typography } from '../../../foundation/Typography'
|
3
|
+
import { HDSButton } from '../../Buttons';
|
4
|
+
import { Icon } from "../../common-components";
|
5
|
+
|
6
|
+
export default function StoryCardXL(props) {
|
7
|
+
return (
|
8
|
+
<>
|
9
|
+
<div className="flex flex-col-reverse px-6 py-10 db-s:px-0 db-s:py-0 db-s:flex-row db:gap-2 max-w-7xl">
|
10
|
+
|
11
|
+
<div className="flex flex-col db-s:pl-20 db-s:pt-20 db-s:pb-[74px]">
|
12
|
+
{
|
13
|
+
props.tagline && (
|
14
|
+
<Typography textStyle='h6' className='text-blue-400 db-s:block uppercase mb-2 hidden '>{props.tagline}</Typography>
|
15
|
+
)
|
16
|
+
}
|
17
|
+
{props.brandImageURL &&
|
18
|
+
props.brandImageAlt && (
|
19
|
+
<>
|
20
|
+
<img src={props.brandImageURL} alt={props.brandImageAlt} className="max-w-[140px] db-s:block hidden " />
|
21
|
+
</>
|
22
|
+
)
|
23
|
+
|
24
|
+
}
|
25
|
+
{props.title &&
|
26
|
+
(
|
27
|
+
<div className="flex pt-6 flex-col gap-6">
|
28
|
+
<Typography textStyle='h3' className='text-neutral-1000 db-s:block hidden'>{props.title}</Typography>
|
29
|
+
{props.heroList &&
|
30
|
+
(
|
31
|
+
<div>
|
32
|
+
<div className="flex flex-col gap-4">
|
33
|
+
{props.heroList.map((value, index) => (
|
34
|
+
<div key={index} className='flex gap-5'>
|
35
|
+
<Icon
|
36
|
+
height='h-8 w-8 stroke-2' variant={value.heroIconVariant} strokeClass='stroke-neutral-800' />
|
37
|
+
<Typography
|
38
|
+
textStyle='sub2' className='text-neutral-700' >
|
39
|
+
{value.heroListTitle}
|
40
|
+
</Typography>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
))
|
44
|
+
|
45
|
+
|
46
|
+
}
|
47
|
+
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
)
|
51
|
+
}
|
52
|
+
</div>
|
53
|
+
)}
|
54
|
+
{props.CTA &&
|
55
|
+
<div className="mt-16 tb:mt-10 tb:flex">
|
56
|
+
<a href={props.CTA['url']}>
|
57
|
+
<HDSButton
|
58
|
+
label={props.CTA['text']}
|
59
|
+
type={props.CTA['type'] || 'secondary'}
|
60
|
+
size='md'
|
61
|
+
rightAnimatedArrowColor="#3970FD"
|
62
|
+
/>
|
63
|
+
</a>
|
64
|
+
</div>}
|
65
|
+
</div>
|
66
|
+
{(props.heroImageURL &&
|
67
|
+
props.heroImageAlt) ?
|
68
|
+
(
|
69
|
+
<div className="flex mt-4 tb:mt-0 justify-start db-s:justify-end db-s:pt-20 tb:max-w-[600px]">
|
70
|
+
<img src={props.heroImageURL} alt={props.heroImageAlt} className="rounded-xl db-s:rounded-none db-s:rounded-br-3xl db-s:rounded-tl-3xl max-w-[280px] tb:max-w-[400px] db-s:max-w-[522px] " />
|
71
|
+
</div>
|
72
|
+
)
|
73
|
+
:
|
74
|
+
(
|
75
|
+
<>
|
76
|
+
{props.video_url && (
|
77
|
+
<div className="flex mt-4 tb:mt-0 tb:items-end tb:max-w-[600px] db-s:min-w-[550px]">
|
78
|
+
<video
|
79
|
+
autoPlay
|
80
|
+
loop
|
81
|
+
playsInline
|
82
|
+
muted
|
83
|
+
src={props.video_url}
|
84
|
+
className=" rounded-xl db-s:rounded-none db-s:rounded-br-3xl db-s:rounded-tl-3xl"
|
85
|
+
/>
|
86
|
+
</div>)}
|
87
|
+
</>
|
88
|
+
)}
|
89
|
+
|
90
|
+
<div className="db-s:hidden pb-6">
|
91
|
+
{props.brandImageURL &&
|
92
|
+
props.brandImageAlt && (
|
93
|
+
<>
|
94
|
+
<img src={props.brandImageURL} alt={props.brandImageAlt} className="max-w-[140px] pb-6 " />
|
95
|
+
</>
|
96
|
+
)
|
97
|
+
|
98
|
+
}
|
99
|
+
<Typography textStyle='h3' className='text-neutral-1000'>{props.title}</Typography>
|
100
|
+
</div>
|
101
|
+
{
|
102
|
+
props.tagline && (
|
103
|
+
<Typography textStyle='h6' className='text-blue-400 db-s:hidden uppercase'>{props.tagline}</Typography>
|
104
|
+
)
|
105
|
+
}
|
106
|
+
</div>
|
107
|
+
|
108
|
+
</>
|
109
|
+
)
|
110
|
+
}
|
111
|
+
|
112
|
+
StoryCardXL.defaultProps = {
|
113
|
+
heroImageURL: 'https://res.cloudinary.com/dh8fp23nd/image/upload/v1690373781/website%20v3/optum_geyxv3.png',
|
114
|
+
heroImageAlt: 'optum',
|
115
|
+
heroIconVariant: 'calendar',
|
116
|
+
heroIconStrokeClass: 'stroke-neutral-1000',
|
117
|
+
heroListTitle: '100 days from concept to production',
|
118
|
+
brandImageURL: 'https://res.cloudinary.com/dh8fp23nd/image/upload/v1679302131/main-web/roadshow/optum_koz0nf.svg',
|
119
|
+
brandImageAlt: 'optum',
|
120
|
+
title: 'Healthcare giant Optum goes from concept to production in 100 days with Hasura',
|
121
|
+
description: 'description1',
|
122
|
+
CTA: {
|
123
|
+
text: 'Button Label',
|
124
|
+
},
|
125
|
+
heroList: [
|
126
|
+
{
|
127
|
+
heroIconVariant: 'calendar',
|
128
|
+
heroListTitle: '100 days from concept to production'
|
129
|
+
},
|
130
|
+
{
|
131
|
+
heroIconVariant: 'database03',
|
132
|
+
heroListTitle: 'Vastly improved access to relevant data'
|
133
|
+
},
|
134
|
+
{
|
135
|
+
heroIconVariant: 'settings01',
|
136
|
+
heroListTitle: 'Simpler data and API management'
|
137
|
+
}
|
138
|
+
]
|
139
|
+
// video_url: 'https://res.cloudinary.com/dh8fp23nd/video/upload/v1654760488/samples/sea-turtle.mp4'
|
140
|
+
}
|
@@ -0,0 +1,176 @@
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
2
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
3
|
+
import { Icon } from '../common-components';
|
4
|
+
|
5
|
+
export default function Carousels ({ components, variants }) {
|
6
|
+
const [FlowDirection, setFlowDirection] = useState(true);
|
7
|
+
const [CenterId, setCenterId] = useState(0);
|
8
|
+
const [LeftId, setLeftId] = useState(components.length - 1);
|
9
|
+
const [RightId, setRightId] = useState(1);
|
10
|
+
const [activeSlide, setActiveSlide] = useState(0);
|
11
|
+
const [isAutoSliding, setIsAutoSliding] = useState(true);
|
12
|
+
const handleAutoSlide = () => {
|
13
|
+
if (isAutoSliding) {
|
14
|
+
nextBtn();
|
15
|
+
}
|
16
|
+
};
|
17
|
+
|
18
|
+
useEffect(() => {
|
19
|
+
const intervalId = setInterval(handleAutoSlide, 3000);
|
20
|
+
return () => clearInterval(intervalId);
|
21
|
+
}, [CenterId, isAutoSliding]);
|
22
|
+
|
23
|
+
const nextBtn = () => {
|
24
|
+
if (LeftId === components.length - 1) {
|
25
|
+
setLeftId(0);
|
26
|
+
} else {
|
27
|
+
setLeftId(LeftId + 1);
|
28
|
+
}
|
29
|
+
if (CenterId === components.length - 1) {
|
30
|
+
setCenterId(0);
|
31
|
+
} else {
|
32
|
+
setCenterId(CenterId + 1);
|
33
|
+
}
|
34
|
+
|
35
|
+
if (RightId === components.length - 1) {
|
36
|
+
setRightId(0);
|
37
|
+
} else {
|
38
|
+
setRightId(RightId + 1);
|
39
|
+
}
|
40
|
+
setFlowDirection(true);
|
41
|
+
setActiveSlide((prevIndex) => (prevIndex === components.length - 1 ? 0 : prevIndex + 1));
|
42
|
+
|
43
|
+
setFlowDirection(true);
|
44
|
+
};
|
45
|
+
const prevBtn = () => {
|
46
|
+
setFlowDirection(false);
|
47
|
+
if (LeftId === 0) {
|
48
|
+
setLeftId(components.length - 1);
|
49
|
+
} else {
|
50
|
+
setLeftId(LeftId - 1);
|
51
|
+
}
|
52
|
+
if (CenterId === 0) {
|
53
|
+
setCenterId(components.length - 1);
|
54
|
+
} else {
|
55
|
+
setCenterId(CenterId - 1);
|
56
|
+
}
|
57
|
+
if (RightId === 0) {
|
58
|
+
setRightId(components.length - 1);
|
59
|
+
} else {
|
60
|
+
setRightId(RightId - 1);
|
61
|
+
}
|
62
|
+
setActiveSlide((prevIndex) => (prevIndex === 0 ? components.length - 1 : prevIndex - 1));
|
63
|
+
|
64
|
+
setFlowDirection(false);
|
65
|
+
};
|
66
|
+
|
67
|
+
const handleMouseEnter = () => {
|
68
|
+
setIsAutoSliding(false);
|
69
|
+
};
|
70
|
+
|
71
|
+
const handleMouseLeave = () => {
|
72
|
+
setIsAutoSliding(true);
|
73
|
+
};
|
74
|
+
if(components){
|
75
|
+
|
76
|
+
|
77
|
+
return (
|
78
|
+
<div
|
79
|
+
className='h-full'
|
80
|
+
onMouseEnter={handleMouseEnter}
|
81
|
+
onMouseLeave={handleMouseLeave}
|
82
|
+
>
|
83
|
+
<div
|
84
|
+
className="hidden db-s:grid relative h-full"
|
85
|
+
>
|
86
|
+
<motion.div className=" ">
|
87
|
+
<AnimatePresence initial={false}>
|
88
|
+
<motion.div
|
89
|
+
key={LeftId}
|
90
|
+
variants={variants}
|
91
|
+
initial={FlowDirection ? 'center' : 'leftHidden'}
|
92
|
+
animate="left"
|
93
|
+
exit={'leftHidden'}
|
94
|
+
className="carousel-item"
|
95
|
+
>
|
96
|
+
{components[LeftId]}
|
97
|
+
</motion.div>
|
98
|
+
<motion.div
|
99
|
+
variants={variants}
|
100
|
+
key={CenterId}
|
101
|
+
initial={FlowDirection ? 'right' : 'left'}
|
102
|
+
animate="center"
|
103
|
+
className="carousel-item"
|
104
|
+
>
|
105
|
+
{components[CenterId]}
|
106
|
+
</motion.div>
|
107
|
+
<motion.div
|
108
|
+
key={RightId}
|
109
|
+
variants={variants}
|
110
|
+
initial={FlowDirection ? 'rightHidden' : 'center'}
|
111
|
+
animate="right"
|
112
|
+
exit={'rightHidden'}
|
113
|
+
className="carousel-item"
|
114
|
+
>
|
115
|
+
{components[RightId]}
|
116
|
+
</motion.div>
|
117
|
+
</AnimatePresence>
|
118
|
+
</motion.div>
|
119
|
+
{/* slider bar */}
|
120
|
+
{/* <div className="flex justify-center mt-4">
|
121
|
+
{components.map((_, index) => (
|
122
|
+
<div
|
123
|
+
key={index}
|
124
|
+
className={`w-4 h-4 rounded-full mx-1 ${activeSlide === index ? 'bg-blue-500' : 'bg-gray-300'
|
125
|
+
}`}
|
126
|
+
></div>
|
127
|
+
))}
|
128
|
+
</div> */}
|
129
|
+
</div>
|
130
|
+
<div className="hidden db-s:flex mt-10 ">
|
131
|
+
<div className="gap-4 w-full h-full flex justify-center">
|
132
|
+
<motion.button
|
133
|
+
initial={{ opacity: 0, scale: 0 }}
|
134
|
+
animate={{ opacity: 1, scale: 1 }}
|
135
|
+
transition={{
|
136
|
+
type: 'spring',
|
137
|
+
duration: 0.5,
|
138
|
+
}}
|
139
|
+
whileHover={{ scale: 1.1 }}
|
140
|
+
whileTap={{ scale: 0.8 }}
|
141
|
+
|
142
|
+
className=" w-12 h-12 bg-neutral-0 shadow hover:bg-neutral-100 rounded-full flex justify-center items-center active:bg-neutral-200 "
|
143
|
+
onClick={prevBtn}
|
144
|
+
>
|
145
|
+
<Icon height={'h-6 w-6'} variant={'chevronleft'} strokeClass='stroke-neutral-800' />
|
146
|
+
</motion.button>
|
147
|
+
<motion.button
|
148
|
+
initial={{ opacity: 0, scale: 0 }}
|
149
|
+
animate={{ opacity: 1, scale: 1 }}
|
150
|
+
transition={{
|
151
|
+
type: 'spring',
|
152
|
+
duration: 0.5,
|
153
|
+
}}
|
154
|
+
whileHover={{ scale: 1.1 }}
|
155
|
+
whileTap={{ scale: 0.8 }}
|
156
|
+
className="w-12 h-12 bg-neutral-0 shadow hover:bg-neutral-100 rounded-full flex justify-center items-center active:bg-neutral-200"
|
157
|
+
onClick={nextBtn}
|
158
|
+
>
|
159
|
+
<Icon height={'h-6 w-6'} variant={'chevronright'} strokeClass='stroke-neutral-800' />
|
160
|
+
</motion.button>
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
<div className='db-s:hidden flex flex-row overflow-scroll pb-10 px-4 scrollbar-hide gap-2 mb-m:gap-4 tb-m:gap-10'>
|
164
|
+
{components.map((component, index) => (
|
165
|
+
<React.Fragment key={index}>
|
166
|
+
<div className='tb-l:min-w-[700px] tb:min-w-[500px] mb-s:min-w-[350px]'>
|
167
|
+
{component}
|
168
|
+
</div>
|
169
|
+
</React.Fragment>
|
170
|
+
))}
|
171
|
+
</div>
|
172
|
+
</div>
|
173
|
+
);
|
174
|
+
}
|
175
|
+
else return <></>;
|
176
|
+
};
|
@@ -2,4 +2,5 @@ export {default as Carousel} from './carousel';
|
|
2
2
|
export {default as CarouselCard} from './carouselCard';
|
3
3
|
export {default as CarouselB} from './carouselB';
|
4
4
|
export {default as HomepageCarouselPrimary} from './homeCarousel';
|
5
|
-
export {default as CustomCarousel} from './customCarousel';
|
5
|
+
export {default as CustomCarousel} from './customCarousel';
|
6
|
+
export {default as CustomerStories} from './customerStories';
|
@@ -5,7 +5,6 @@ import { HDSButton } from "../Buttons";
|
|
5
5
|
import { HDSColor } from "../../foundation/ColorPalette";
|
6
6
|
import { Icon } from "../common-components";
|
7
7
|
import { LinkCard } from '../Cards/Link';
|
8
|
-
import { v4 as uuidv4 } from 'uuid';
|
9
8
|
|
10
9
|
export default function HeroSecondary({ heroData, logo, scrollArrow, fontSize }) {
|
11
10
|
const [valumeMuteIcon, setValumeMuteIcon] = useState("volumex");
|
@@ -144,8 +143,8 @@ export default function HeroSecondary({ heroData, logo, scrollArrow, fontSize })
|
|
144
143
|
return (
|
145
144
|
heroData.linkCards && (
|
146
145
|
<div className="flex mt-16 px-20 pb-20 gap-6 justify-center">
|
147
|
-
{heroData.linkCards.map((card) => (
|
148
|
-
<div key={
|
146
|
+
{heroData.linkCards.map((card, index) => (
|
147
|
+
<div key={index} className="w-full">
|
149
148
|
<LinkCard
|
150
149
|
linkUrl={card.linkUrl}
|
151
150
|
cardBgColor={card.cardBgColor}
|
package/src/index.css
CHANGED
@@ -821,3 +821,36 @@ position: absolute;
|
|
821
821
|
opacity: 0;
|
822
822
|
}
|
823
823
|
}
|
824
|
+
|
825
|
+
|
826
|
+
|
827
|
+
.carousel-wrapper {
|
828
|
+
display: grid;
|
829
|
+
place-content: center;
|
830
|
+
border-radius: 2rem;
|
831
|
+
|
832
|
+
}
|
833
|
+
|
834
|
+
.carousel-content {
|
835
|
+
position: relative;
|
836
|
+
|
837
|
+
}
|
838
|
+
|
839
|
+
.carousel-item {
|
840
|
+
position: absolute;
|
841
|
+
background-position: center;
|
842
|
+
background-size: cover;
|
843
|
+
background-repeat: no-repeat;
|
844
|
+
|
845
|
+
}
|
846
|
+
|
847
|
+
.carousel-btns {
|
848
|
+
|
849
|
+
display: flex;
|
850
|
+
justify-content: center;
|
851
|
+
gap: 1rem;
|
852
|
+
z-index: 6;
|
853
|
+
|
854
|
+
|
855
|
+
}
|
856
|
+
|