@latte-macchiat-io/latte-vanilla-components 0.0.190 → 0.0.192

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 (101) hide show
  1. package/README.md +16 -6
  2. package/package.json +4 -1
  3. package/src/components/Actions/index.tsx +20 -0
  4. package/src/components/Actions/styles.css.ts +54 -0
  5. package/src/components/Button/index.tsx +29 -0
  6. package/src/components/Button/stories.tsx +4 -22
  7. package/src/components/Button/styles.css.ts +131 -0
  8. package/src/components/Carousel/{Carousel.tsx → index.tsx} +18 -115
  9. package/src/components/Carousel/styles.css.ts +176 -0
  10. package/src/components/Columns/index.tsx +36 -0
  11. package/src/components/Columns/styles.css.ts +70 -0
  12. package/src/components/ConsentCookie/ConsentCookie.css.ts +1 -1
  13. package/src/components/ConsentCookie/ConsentCookie.tsx +3 -3
  14. package/src/components/Footer/index.tsx +21 -0
  15. package/src/components/Footer/styles.css.ts +33 -0
  16. package/src/components/Form/Form.css.ts +1 -1
  17. package/src/components/Form/Row/Row.css.ts +1 -1
  18. package/src/components/Form/TextField/Input/Input.css.ts +1 -1
  19. package/src/components/Form/TextField/Label/Label.css.ts +1 -1
  20. package/src/components/Form/TextField/TextField.css.ts +1 -1
  21. package/src/components/Form/TextField/Textarea/Textarea.css.ts +1 -1
  22. package/src/components/Header/index.tsx +53 -0
  23. package/src/components/Header/styles.css.ts +89 -0
  24. package/src/components/Heading/index.tsx +22 -0
  25. package/src/components/Heading/styles.css.ts +66 -0
  26. package/src/components/Heading/types.tsx +1 -0
  27. package/src/components/Icon/index.tsx +25 -0
  28. package/src/components/Icon/style.css.ts +11 -0
  29. package/src/components/KeyNumber/index.tsx +51 -0
  30. package/src/components/KeyNumber/styles.css.ts +76 -0
  31. package/src/components/LanguageSwitcher/index.tsx +80 -0
  32. package/src/components/LanguageSwitcher/{LanguageSwitcher.css.ts → styles.css.ts} +1 -1
  33. package/src/components/Logo/index.tsx +13 -0
  34. package/src/components/Logo/styles.css.ts +14 -0
  35. package/src/components/Main/index.tsx +17 -0
  36. package/src/components/Main/styles.css.ts +14 -0
  37. package/src/components/Modal/index.tsx +42 -0
  38. package/src/components/Modal/stories.tsx +14 -358
  39. package/src/components/Modal/styles.css.ts +90 -0
  40. package/src/components/Nav/index.tsx +22 -0
  41. package/src/components/Nav/styles.css.ts +30 -0
  42. package/src/components/NavLegal/index.tsx +17 -0
  43. package/src/components/NavLegal/styles.css.ts +20 -0
  44. package/src/components/NavSocial/index.tsx +32 -0
  45. package/src/components/NavSocial/styles.css.ts +33 -0
  46. package/src/components/Section/index.tsx +20 -0
  47. package/src/components/Section/stories.tsx +5 -57
  48. package/src/components/Section/styles.css.ts +106 -0
  49. package/src/components/ThemeTest/ThemeTest.css.ts +11 -0
  50. package/src/components/ThemeTest/ThemeTest.tsx +12 -0
  51. package/src/components/ThemeToggle/ThemeToggle.tsx +30 -0
  52. package/src/components/Video/index.tsx +117 -0
  53. package/src/components/Video/styles.css.ts +200 -0
  54. package/src/index.ts +29 -41
  55. package/src/styles/mediaqueries.ts +2 -0
  56. package/src/styles/sprinkles.css.ts +11 -8
  57. package/src/theme/baseThemeValues.ts +1235 -0
  58. package/src/theme/contract.css.ts +676 -0
  59. package/src/{themes → theme}/createTheme.ts +40 -1
  60. package/src/theme/default.css.ts +10 -0
  61. package/src/utils/combineResponsive.ts +9 -0
  62. package/src/utils/generateResponsiveMedia.ts +19 -0
  63. package/src/components/Actions/Actions.css.ts +0 -113
  64. package/src/components/Actions/Actions.tsx +0 -132
  65. package/src/components/Button/Button.css.ts +0 -119
  66. package/src/components/Button/Button.tsx +0 -132
  67. package/src/components/Carousel/Carousel.css.ts +0 -179
  68. package/src/components/Columns/Columns.css.ts +0 -185
  69. package/src/components/Columns/Columns.tsx +0 -142
  70. package/src/components/Footer/Footer.css.ts +0 -108
  71. package/src/components/Footer/Footer.tsx +0 -130
  72. package/src/components/Header/Header.css.ts +0 -111
  73. package/src/components/Header/Header.tsx +0 -158
  74. package/src/components/Icon/Icon.css.ts +0 -101
  75. package/src/components/Icon/Icon.tsx +0 -159
  76. package/src/components/KeyNumber/KeyNumber.css.ts +0 -158
  77. package/src/components/KeyNumber/KeyNumber.tsx +0 -166
  78. package/src/components/LanguageSwitcher/LanguageSwitcher.tsx +0 -168
  79. package/src/components/Logo/Logo.css.ts +0 -98
  80. package/src/components/Logo/Logo.tsx +0 -137
  81. package/src/components/Main/Main.css.ts +0 -62
  82. package/src/components/Main/Main.tsx +0 -130
  83. package/src/components/Modal/Modal.css.ts +0 -203
  84. package/src/components/Modal/Modal.tsx +0 -194
  85. package/src/components/Nav/Nav.css.ts +0 -123
  86. package/src/components/Nav/Nav.tsx +0 -130
  87. package/src/components/NavLegal/NavLegal.css.ts +0 -121
  88. package/src/components/NavLegal/NavLegal.tsx +0 -133
  89. package/src/components/NavSocial/NavSocial.css.ts +0 -121
  90. package/src/components/NavSocial/NavSocial.tsx +0 -169
  91. package/src/components/Section/Section.css.ts +0 -101
  92. package/src/components/Section/Section.tsx +0 -130
  93. package/src/components/Video/Video.css.ts +0 -210
  94. package/src/components/Video/Video.tsx +0 -243
  95. package/src/components/VideoFullWidth/VideoFullWidth.css.ts +0 -50
  96. package/src/components/VideoFullWidth/VideoFullWidth.tsx +0 -152
  97. package/src/components/VideoFullWidth/export.tsx +0 -2
  98. package/src/themes/baseThemeValues.ts +0 -160
  99. package/src/themes/contract.css.ts +0 -83
  100. package/src/types/withClassName.ts +0 -4
  101. /package/src/{utils → components/ConsentCookie}/cookie.ts +0 -0
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import React from 'react';
3
- import { Section } from './Section';
4
- import { Button } from '../Button/Button';
3
+ import { Button } from '../..';
4
+ import { Section } from '.';
5
5
 
6
6
  const meta: Meta<typeof Section> = {
7
7
  title: 'Layout Components/Section',
@@ -41,16 +41,6 @@ The Section component provides consistent spacing and layout for content section
41
41
  control: 'boolean',
42
42
  description: 'Make the section take full viewport height',
43
43
  },
44
- spacing: {
45
- control: 'select',
46
- options: ['none', 'small', 'medium', 'large'],
47
- description: 'Amount of vertical padding',
48
- },
49
- as: {
50
- control: 'select',
51
- options: ['section', 'div', 'main', 'article', 'aside'],
52
- description: 'HTML element to render as',
53
- },
54
44
  },
55
45
  };
56
46
 
@@ -134,7 +124,6 @@ export const FullHeight: Story = {
134
124
 
135
125
  export const NoSpacing: Story = {
136
126
  args: {
137
- spacing: 'none',
138
127
  children: (
139
128
  <>
140
129
  <h2>No Spacing Section</h2>
@@ -146,7 +135,6 @@ export const NoSpacing: Story = {
146
135
 
147
136
  export const SmallSpacing: Story = {
148
137
  args: {
149
- spacing: 'sm',
150
138
  children: (
151
139
  <>
152
140
  <h2>Small Spacing Section</h2>
@@ -158,7 +146,6 @@ export const SmallSpacing: Story = {
158
146
 
159
147
  export const LargeSpacing: Story = {
160
148
  args: {
161
- spacing: 'lg',
162
149
  children: (
163
150
  <>
164
151
  <h2>Large Spacing Section</h2>
@@ -168,49 +155,10 @@ export const LargeSpacing: Story = {
168
155
  },
169
156
  };
170
157
 
171
- export const AsMain: Story = {
172
- args: {
173
- as: 'main',
174
- children: (
175
- <>
176
- <h1>Main Content Area</h1>
177
- <p>This section is rendered as a main element for semantic HTML.</p>
178
- </>
179
- ),
180
- },
181
- parameters: {
182
- docs: {
183
- description: {
184
- story: 'Section rendered as a main element for the primary content area.',
185
- },
186
- },
187
- },
188
- };
189
-
190
- export const AsArticle: Story = {
191
- args: {
192
- as: 'article',
193
- children: (
194
- <>
195
- <h2>Article Section</h2>
196
- <p>This section is rendered as an article element for standalone content.</p>
197
- <p>Perfect for blog posts, news articles, or any self-contained content.</p>
198
- </>
199
- ),
200
- },
201
- parameters: {
202
- docs: {
203
- description: {
204
- story: 'Section rendered as an article element for standalone content.',
205
- },
206
- },
207
- },
208
- };
209
-
210
158
  // Real-world Examples
211
159
  export const HeroSection: Story = {
212
160
  render: () => (
213
- <Section isFullHeight={true} align="center" backgroundColor="primary">
161
+ <Section isFullHeight={true} align="center">
214
162
  <div
215
163
  style={{
216
164
  color: 'white',
@@ -249,7 +197,7 @@ export const HeroSection: Story = {
249
197
 
250
198
  export const FeatureSection: Story = {
251
199
  render: () => (
252
- <Section spacing="lg">
200
+ <Section>
253
201
  <div style={{ maxWidth: '1200px', margin: '0 auto' }}>
254
202
  <div style={{ textAlign: 'center', marginBottom: '3rem' }}>
255
203
  <h2 style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>Why Choose Our Components?</h2>
@@ -317,7 +265,7 @@ export const FeatureSection: Story = {
317
265
 
318
266
  export const CallToActionSection: Story = {
319
267
  render: () => (
320
- <Section isDark={true} align="center" spacing="lg">
268
+ <Section isDark={true} align="center">
321
269
  <div style={{ color: 'white', textAlign: 'center', maxWidth: '600px', margin: '0 auto' }}>
322
270
  <h2 style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>Ready to Get Started?</h2>
323
271
  <p style={{ fontSize: '1.1rem', marginBottom: '2rem', opacity: 0.9 }}>
@@ -0,0 +1,106 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { recipe, type RecipeVariants } from '@vanilla-extract/recipes';
3
+
4
+ import { themeContract } from '../../theme/contract.css';
5
+ import { generateResponsiveMedia } from '../../utils/generateResponsiveMedia';
6
+
7
+ export const sectionRecipe = recipe({
8
+ base: [
9
+ {
10
+ width: '100%',
11
+ display: 'flex',
12
+ margin: '0 auto',
13
+ position: 'relative',
14
+ flexDirection: 'column',
15
+
16
+ '@media': {
17
+ ...generateResponsiveMedia({
18
+ paddingLeft: themeContract.global.paddingLeft,
19
+ paddingRight: themeContract.global.paddingRight,
20
+ }),
21
+ },
22
+ },
23
+ ],
24
+
25
+ variants: {
26
+ align: {
27
+ left: {
28
+ textAlign: 'left',
29
+ alignItems: 'flex-start',
30
+ },
31
+ center: {
32
+ textAlign: 'center',
33
+ alignItems: 'center',
34
+ },
35
+ right: {
36
+ textAlign: 'right',
37
+ alignItems: 'flex-end',
38
+ },
39
+ },
40
+ isDark: {
41
+ true: {
42
+ color: themeContract.colors.textLight,
43
+ },
44
+ false: {
45
+ color: themeContract.colors.text,
46
+ },
47
+ },
48
+ isFullHeight: {
49
+ true: {
50
+ minHeight: '100vh',
51
+ justifyContent: 'center',
52
+ },
53
+ false: {
54
+ minHeight: 'auto',
55
+ justifyContent: 'flex-start',
56
+ },
57
+ },
58
+ withPaddingTop: {
59
+ true: {
60
+ '@media': {
61
+ ...generateResponsiveMedia({
62
+ paddingTop: themeContract.section.paddingTop,
63
+ }),
64
+ },
65
+ },
66
+ false: { paddingTop: 'none' },
67
+ },
68
+ withPaddingBottom: {
69
+ true: {
70
+ '@media': {
71
+ ...generateResponsiveMedia({
72
+ paddingBottom: themeContract.section.paddingBottom,
73
+ }),
74
+ },
75
+ },
76
+ false: { paddingBottom: 'none' },
77
+ },
78
+ },
79
+
80
+ defaultVariants: {
81
+ align: 'left',
82
+ isDark: false,
83
+ isFullHeight: false,
84
+ withPaddingTop: true,
85
+ withPaddingBottom: true,
86
+ },
87
+ });
88
+
89
+ export const sectionContent = style([
90
+ {
91
+ width: '100%',
92
+ display: 'flex',
93
+ margin: '0 auto',
94
+ flexDirection: 'column',
95
+
96
+ maxWidth: themeContract.maxWidth,
97
+
98
+ '@media': {
99
+ ...generateResponsiveMedia({
100
+ gap: themeContract.section.gap,
101
+ }),
102
+ },
103
+ },
104
+ ]);
105
+
106
+ export type SectionVariants = RecipeVariants<typeof sectionRecipe>;
@@ -0,0 +1,11 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { themeContract } from '../../../theme/contract.css';
3
+
4
+ export const testStyle = style({
5
+ padding: themeContract.space.large,
6
+ backgroundColor: themeContract.colors.primary,
7
+ color: themeContract.colors.text,
8
+ borderRadius: themeContract.radii.medium,
9
+ margin: themeContract.space.medium,
10
+ border: `2px solid ${themeContract.colors.border}`,
11
+ });
@@ -0,0 +1,12 @@
1
+ import { testStyle } from './ThemeTest.css';
2
+
3
+ export function ThemeTest() {
4
+ return (
5
+ <div className={testStyle}>
6
+ <h3>Theme Test Component</h3>
7
+ <p>Background should be primary color</p>
8
+ <p>Text should be theme text color</p>
9
+ <p>This should change when you toggle the theme!</p>
10
+ </div>
11
+ );
12
+ }
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ export function ThemeToggle() {
6
+ const [theme, setTheme] = useState<'light' | 'dark'>('light');
7
+
8
+ useEffect(() => {
9
+ // Get initial theme from localStorage or system preference
10
+ const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null;
11
+ const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
12
+ const initialTheme = savedTheme || systemTheme;
13
+
14
+ setTheme(initialTheme);
15
+ document.documentElement.dataset.theme = initialTheme;
16
+ }, []);
17
+
18
+ const toggleTheme = () => {
19
+ const newTheme = theme === 'light' ? 'dark' : 'light';
20
+ setTheme(newTheme);
21
+ document.documentElement.dataset.theme = newTheme;
22
+ localStorage.setItem('theme', newTheme);
23
+ };
24
+
25
+ return (
26
+ <button onClick={toggleTheme} aria-label="Toggle theme">
27
+ {theme === 'light' ? '🌙' : '☀️'}
28
+ </button>
29
+ );
30
+ }
@@ -0,0 +1,117 @@
1
+ 'use client';
2
+
3
+ /* eslint-disable jsx-a11y/media-has-caption */
4
+
5
+ import { clsx } from 'clsx';
6
+ import { forwardRef, useEffect, useRef, useState } from 'react';
7
+ import {
8
+ closeButton,
9
+ pauseButton,
10
+ playButton,
11
+ posterImage,
12
+ soundButton,
13
+ videoElement,
14
+ videoPoster,
15
+ videoRecipe,
16
+ type VideoVariants,
17
+ } from './styles.css';
18
+
19
+ export type VideoProps = React.HTMLAttributes<HTMLDivElement> &
20
+ VideoVariants & {
21
+ css?: string;
22
+ video: string;
23
+ poster?: string;
24
+ isAutoPlay?: boolean;
25
+ startMuted?: boolean;
26
+ showControls?: boolean;
27
+ hidePlayButton?: boolean;
28
+ isPlayingFullScreen?: boolean;
29
+ onPlay?: () => void;
30
+ onClose?: () => void;
31
+ onEnded?: () => void;
32
+ };
33
+
34
+ export const Video = forwardRef<HTMLDivElement, VideoProps>(
35
+ (
36
+ {
37
+ video,
38
+ poster,
39
+ isAutoPlay = false,
40
+ startMuted = false,
41
+ showControls = false,
42
+ hidePlayButton = false,
43
+ isPlayingFullScreen = false,
44
+ onPlay,
45
+ onClose,
46
+ onEnded,
47
+ size,
48
+ css,
49
+ className,
50
+ },
51
+ ref
52
+ ) => {
53
+ const videoRef = useRef<HTMLVideoElement>(null);
54
+ const [isPlaying, setIsPlaying] = useState(false);
55
+ const [isMuted, setIsMuted] = useState(isAutoPlay || startMuted);
56
+
57
+ const playVideo = () => {
58
+ onPlay?.();
59
+ videoRef.current?.play();
60
+ setIsPlaying(true);
61
+ };
62
+
63
+ const closeVideo = () => {
64
+ onClose?.();
65
+ videoRef.current?.pause();
66
+ setIsPlaying(false);
67
+ };
68
+
69
+ const pauseVideo = () => {
70
+ videoRef.current?.pause();
71
+ setIsPlaying(false);
72
+ };
73
+
74
+ const toggleMutedVideo = () => {
75
+ const newIsMuted = !isMuted;
76
+ setIsMuted(newIsMuted);
77
+ if (videoRef.current) videoRef.current.muted = newIsMuted;
78
+ };
79
+
80
+ const handleVideoEnded = () => {
81
+ onEnded?.();
82
+ closeVideo();
83
+ };
84
+
85
+ useEffect(() => {
86
+ if (videoRef.current) videoRef.current.muted = isMuted;
87
+ }, [isMuted]);
88
+
89
+ return (
90
+ <div ref={ref} className={clsx(videoRecipe({ size }), css, className)}>
91
+ <video ref={videoRef} className={videoElement} playsInline muted={isMuted} autoPlay={isAutoPlay} onEnded={handleVideoEnded}>
92
+ <source src={video} type="video/mp4" />
93
+ </video>
94
+
95
+ {poster && (
96
+ <div className={videoPoster} data-playing={isPlaying}>
97
+ <img src={poster} alt="Video poster" className={posterImage} />
98
+ </div>
99
+ )}
100
+
101
+ {!hidePlayButton && !isAutoPlay && (
102
+ <button className={playButton} data-playing={isPlaying} onClick={playVideo} aria-label="Play video" type="button" />
103
+ )}
104
+
105
+ {isPlayingFullScreen && <button className={closeButton} onClick={closeVideo} aria-label="Close video" type="button" />}
106
+
107
+ {isPlaying && showControls && <button className={pauseButton} onClick={pauseVideo} aria-label="Pause video" type="button" />}
108
+
109
+ {showControls && (
110
+ <button className={soundButton} onClick={toggleMutedVideo} aria-label={isMuted ? 'Unmute video' : 'Mute video'} type="button" />
111
+ )}
112
+ </div>
113
+ );
114
+ }
115
+ );
116
+
117
+ Video.displayName = 'Video';
@@ -0,0 +1,200 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { calc } from '@vanilla-extract/css-utils';
3
+ import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
4
+
5
+ import { queries } from '../../styles/mediaqueries';
6
+ import { themeContract } from '../../theme/contract.css';
7
+ import { generateResponsiveMedia } from '../../utils/generateResponsiveMedia';
8
+
9
+ export const videoRecipe = recipe({
10
+ base: {
11
+ width: '100%',
12
+ height: '100%',
13
+ overflow: 'hidden',
14
+ position: 'absolute',
15
+
16
+ backgroundColor: themeContract.colors.background,
17
+ },
18
+
19
+ variants: {
20
+ size: {
21
+ fullWidth: { width: '100%', aspectRatio: '16/9' },
22
+ fullScreen: [
23
+ {
24
+ width: '100vw',
25
+ aspectRatio: '16/9',
26
+ position: 'relative',
27
+ marginLeft: calc(themeContract.global.paddingLeft.mobile).negate().toString(),
28
+ marginRight: calc(themeContract.global.paddingRight.mobile).negate().toString(),
29
+
30
+ '@media': {
31
+ [queries.sm]: {
32
+ marginLeft: calc(themeContract.global.paddingLeft.sm).negate().toString(),
33
+ marginRight: calc(themeContract.global.paddingRight.sm).negate().toString(),
34
+ },
35
+ [queries.md]: {
36
+ marginLeft: calc(themeContract.global.paddingLeft.md).negate().toString(),
37
+ marginRight: calc(themeContract.global.paddingRight.md).negate().toString(),
38
+ },
39
+ [queries.lg]: {
40
+ marginLeft: calc(themeContract.global.paddingLeft.lg).negate().toString(),
41
+ marginRight: calc(themeContract.global.paddingRight.lg).negate().toString(),
42
+ },
43
+ [queries.xl]: {
44
+ marginLeft: calc(themeContract.global.paddingLeft.xl).negate().toString(),
45
+ marginRight: calc(themeContract.global.paddingRight.xl).negate().toString(),
46
+ },
47
+ [queries['2xl']]: {
48
+ marginLeft: `calc((100vw - ${themeContract.maxWidth}) / -2)`,
49
+ marginRight: `calc((100vw - ${themeContract.maxWidth}) / -2)`,
50
+ },
51
+ },
52
+ },
53
+ ],
54
+ },
55
+ },
56
+
57
+ defaultVariants: {
58
+ size: 'fullWidth',
59
+ },
60
+ });
61
+
62
+ export type VideoVariants = RecipeVariants<typeof videoRecipe>;
63
+
64
+ export const videoElement = style({
65
+ top: '50%',
66
+ left: '50%',
67
+ width: 'auto',
68
+ minWidth: '100%',
69
+ minHeight: '100%',
70
+ position: 'absolute',
71
+ transform: 'translate(-50%, -50%)',
72
+ });
73
+
74
+ export const videoPoster = style({
75
+ top: 0,
76
+ left: 0,
77
+ opacity: 1,
78
+ width: '100%',
79
+ height: '100%',
80
+ position: 'absolute',
81
+ pointerEvents: 'auto',
82
+ transition: 'opacity 0.3s ease-in-out',
83
+
84
+ selectors: {
85
+ '&[data-playing="true"]': {
86
+ opacity: 0,
87
+ pointerEvents: 'none',
88
+ },
89
+ },
90
+ });
91
+
92
+ export const posterImage = style({
93
+ width: '100%',
94
+ height: '100%',
95
+ objectFit: 'cover',
96
+ });
97
+
98
+ export const playButton = style([
99
+ {
100
+ top: '50%',
101
+ left: '50%',
102
+ width: '40px',
103
+ height: '40px',
104
+ display: 'flex',
105
+ cursor: 'pointer',
106
+ alignItems: 'center',
107
+ position: 'absolute',
108
+ justifyContent: 'center',
109
+ transition: 'all 0.3s ease-in-out',
110
+ transform: 'translate(-50%, -50%)',
111
+
112
+ border: themeContract.video.playButton.border,
113
+ color: themeContract.video.playButton.iconColor,
114
+ borderRadius: themeContract.video.playButton.borderRadius,
115
+ backgroundColor: themeContract.video.playButton.backgroundColor,
116
+
117
+ selectors: {
118
+ '&[data-playing="true"]': {
119
+ opacity: 0,
120
+ pointerEvents: 'none',
121
+ },
122
+ },
123
+
124
+ '@media': {
125
+ ...generateResponsiveMedia({
126
+ width: themeContract.video.playButton.width,
127
+ height: themeContract.video.playButton.height,
128
+ }),
129
+ },
130
+ },
131
+ ]);
132
+
133
+ const controlButton = style({
134
+ border: 'none',
135
+ display: 'flex',
136
+ cursor: 'pointer',
137
+ position: 'absolute',
138
+ alignItems: 'center',
139
+ justifyContent: 'center',
140
+ transition: 'all 0.3s ease-in-out',
141
+ });
142
+
143
+ export const closeButton = style([
144
+ controlButton,
145
+ {
146
+ top: themeContract.space.md,
147
+ right: themeContract.space.md,
148
+ border: themeContract.video.closeButton.border,
149
+ color: themeContract.video.closeButton.iconColor,
150
+ borderRadius: themeContract.video.closeButton.borderRadius,
151
+ backgroundColor: themeContract.video.closeButton.backgroundColor,
152
+
153
+ '@media': {
154
+ ...generateResponsiveMedia({
155
+ width: themeContract.video.closeButton.width,
156
+ height: themeContract.video.closeButton.height,
157
+ }),
158
+ },
159
+ },
160
+ ]);
161
+
162
+ export const pauseButton = style([
163
+ controlButton,
164
+ {
165
+ right: '80px',
166
+
167
+ bottom: themeContract.space.md,
168
+ border: themeContract.video.pauseButton.border,
169
+ color: themeContract.video.pauseButton.iconColor,
170
+ borderRadius: themeContract.video.pauseButton.borderRadius,
171
+ backgroundColor: themeContract.video.pauseButton.backgroundColor,
172
+
173
+ '@media': {
174
+ ...generateResponsiveMedia({
175
+ width: themeContract.video.pauseButton.width,
176
+ height: themeContract.video.pauseButton.height,
177
+ }),
178
+ },
179
+ },
180
+ ]);
181
+
182
+ export const soundButton = style([
183
+ controlButton,
184
+
185
+ {
186
+ bottom: themeContract.space.md,
187
+ right: themeContract.space.md,
188
+ border: themeContract.video.soundButton.border,
189
+ color: themeContract.video.soundButton.iconColor,
190
+ borderRadius: themeContract.video.soundButton.borderRadius,
191
+ backgroundColor: themeContract.video.soundButton.backgroundColor,
192
+
193
+ '@media': {
194
+ ...generateResponsiveMedia({
195
+ width: themeContract.video.soundButton.width,
196
+ height: themeContract.video.soundButton.height,
197
+ }),
198
+ },
199
+ },
200
+ ]);