@latte-macchiat-io/latte-vanilla-components 0.0.167 → 0.0.168

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 (60) hide show
  1. package/dist/Actions.css.ts +113 -0
  2. package/dist/Button.css.ts +119 -0
  3. package/dist/Carousel.css.ts +180 -0
  4. package/dist/Columns.css.ts +185 -0
  5. package/dist/ConsentCookie.css.ts +167 -0
  6. package/dist/Footer.css.ts +108 -0
  7. package/dist/Form.css.ts +64 -0
  8. package/dist/Header.css.ts +111 -0
  9. package/dist/Icon.css.ts +102 -0
  10. package/dist/Input.css.ts +106 -0
  11. package/dist/KeyNumber.css.ts +158 -0
  12. package/dist/Label.css.ts +58 -0
  13. package/dist/LanguageSwitcher.css.ts +120 -0
  14. package/dist/Logo.css.ts +98 -0
  15. package/dist/Main.css.ts +62 -0
  16. package/dist/Modal.css.ts +203 -0
  17. package/dist/Nav.css.ts +123 -0
  18. package/dist/NavLegal.css.ts +121 -0
  19. package/dist/NavSocial.css.ts +121 -0
  20. package/dist/Row.css.ts +70 -0
  21. package/dist/Section.css.ts +101 -0
  22. package/dist/TextField.css.ts +139 -0
  23. package/dist/Textarea.css.ts +121 -0
  24. package/dist/Video.css.ts +210 -0
  25. package/dist/VideoFullWidth.css.ts +50 -0
  26. package/dist/contract.css.ts +83 -0
  27. package/dist/default.css.ts +9 -0
  28. package/dist/sprinkles.css.ts +82 -0
  29. package/dist/styles.css.ts +40 -0
  30. package/package.json +4 -3
  31. package/src/components/Actions/Actions.css.ts +113 -0
  32. package/src/components/Button/Button.css.ts +119 -0
  33. package/src/components/Carousel/Carousel.css.ts +180 -0
  34. package/src/components/Columns/Columns.css.ts +185 -0
  35. package/src/components/ConsentCookie/ConsentCookie.css.ts +167 -0
  36. package/src/components/Footer/Footer.css.ts +108 -0
  37. package/src/components/Form/Form.css.ts +64 -0
  38. package/src/components/Form/Row/Row.css.ts +70 -0
  39. package/src/components/Form/TextField/Input/Input.css.ts +106 -0
  40. package/src/components/Form/TextField/Label/Label.css.ts +58 -0
  41. package/src/components/Form/TextField/TextField.css.ts +139 -0
  42. package/src/components/Form/TextField/Textarea/Textarea.css.ts +121 -0
  43. package/src/components/Header/Header.css.ts +111 -0
  44. package/src/components/Header/HeaderOverlay/styles.css.ts +33 -0
  45. package/src/components/Header/ToggleNav/styles.css.ts +40 -0
  46. package/src/components/Icon/Icon.css.ts +102 -0
  47. package/src/components/KeyNumber/KeyNumber.css.ts +158 -0
  48. package/src/components/LanguageSwitcher/LanguageSwitcher.css.ts +120 -0
  49. package/src/components/Logo/Logo.css.ts +98 -0
  50. package/src/components/Main/Main.css.ts +62 -0
  51. package/src/components/Modal/Modal.css.ts +203 -0
  52. package/src/components/Nav/Nav.css.ts +123 -0
  53. package/src/components/NavLegal/NavLegal.css.ts +121 -0
  54. package/src/components/NavSocial/NavSocial.css.ts +121 -0
  55. package/src/components/Section/Section.css.ts +101 -0
  56. package/src/components/Video/Video.css.ts +210 -0
  57. package/src/components/VideoFullWidth/VideoFullWidth.css.ts +50 -0
  58. package/src/styles/sprinkles.css.ts +82 -0
  59. package/src/theme/contract.css.ts +83 -0
  60. package/src/theme/default.css.ts +9 -0
@@ -0,0 +1,121 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
3
+ import { themeContract } from '../../../../theme/contract.css';
4
+
5
+ const textareaBase = style({
6
+ appearance: 'none',
7
+ backgroundColor: themeContract.colors.background,
8
+ border: `1px solid ${themeContract.colors.border}`,
9
+ borderRadius: themeContract.radii.md,
10
+ color: themeContract.colors.text,
11
+ fontFamily: themeContract.fonts.body,
12
+ fontSize: themeContract.fontSizes.sm,
13
+ lineHeight: themeContract.lineHeights.normal,
14
+ padding: `${themeContract.space.sm} ${themeContract.space.md}`,
15
+ transition: 'all 0.2s ease-in-out',
16
+ width: '100%',
17
+ resize: 'vertical',
18
+ minHeight: '80px',
19
+
20
+ '::placeholder': {
21
+ color: themeContract.colors.textSecondary,
22
+ },
23
+
24
+ ':hover': {
25
+ borderColor: themeContract.colors.primary,
26
+ },
27
+
28
+ ':focus': {
29
+ outline: '2px solid',
30
+ outlineColor: themeContract.colors.primary,
31
+ outlineOffset: '2px',
32
+ borderColor: themeContract.colors.primary,
33
+ },
34
+
35
+ ':disabled': {
36
+ backgroundColor: themeContract.colors.surface,
37
+ color: themeContract.colors.textSecondary,
38
+ cursor: 'not-allowed',
39
+ opacity: '0.6',
40
+ resize: 'none',
41
+ },
42
+
43
+ selectors: {
44
+ '&[data-error="true"]': {
45
+ borderColor: themeContract.colors.error,
46
+ },
47
+ '&[data-error="true"]:focus': {
48
+ outlineColor: themeContract.colors.error,
49
+ borderColor: themeContract.colors.error,
50
+ },
51
+ },
52
+ });
53
+
54
+ export const textareaRecipe = recipe({
55
+ base: textareaBase,
56
+
57
+ variants: {
58
+ size: {
59
+ sm: {
60
+ fontSize: themeContract.fontSizes.xs,
61
+ padding: `${themeContract.space.xs} ${themeContract.space.sm}`,
62
+ minHeight: '60px',
63
+ },
64
+ md: {},
65
+ lg: {
66
+ fontSize: themeContract.fontSizes.md,
67
+ padding: `${themeContract.space.md} ${themeContract.space.lg}`,
68
+ minHeight: '100px',
69
+ },
70
+ },
71
+ variant: {
72
+ default: {},
73
+ filled: {
74
+ backgroundColor: themeContract.colors.surface,
75
+ border: 'none',
76
+
77
+ ':focus': {
78
+ backgroundColor: themeContract.colors.background,
79
+ border: `1px solid ${themeContract.colors.primary}`,
80
+ },
81
+ },
82
+ outlined: {
83
+ backgroundColor: 'transparent',
84
+ },
85
+ underlined: {
86
+ backgroundColor: 'transparent',
87
+ border: 'none',
88
+ borderBottom: `1px solid ${themeContract.colors.border}`,
89
+ borderRadius: 0,
90
+ padding: `${themeContract.space.sm} 0`,
91
+
92
+ ':focus': {
93
+ borderBottom: `2px solid ${themeContract.colors.primary}`,
94
+ outline: 'none',
95
+ },
96
+ },
97
+ },
98
+ resize: {
99
+ vertical: {
100
+ resize: 'vertical',
101
+ },
102
+ horizontal: {
103
+ resize: 'horizontal',
104
+ },
105
+ both: {
106
+ resize: 'both',
107
+ },
108
+ none: {
109
+ resize: 'none',
110
+ },
111
+ },
112
+ },
113
+
114
+ defaultVariants: {
115
+ size: 'md',
116
+ variant: 'default',
117
+ resize: 'vertical',
118
+ },
119
+ });
120
+
121
+ export type TextareaVariants = RecipeVariants<typeof textareaRecipe>;
@@ -0,0 +1,210 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
3
+ import { themeContract } from '../../theme/contract.css';
4
+
5
+ const videoBase = style({
6
+ position: 'relative',
7
+ overflow: 'hidden',
8
+ backgroundColor: themeContract.colors.background,
9
+ });
10
+
11
+ const videoElement = style({
12
+ top: '50%',
13
+ left: '50%',
14
+ width: 'auto',
15
+ minWidth: '100%',
16
+ minHeight: '100%',
17
+ position: 'absolute',
18
+ transform: 'translate(-50%, -50%)',
19
+ });
20
+
21
+ const videoPoster = style({
22
+ top: 0,
23
+ left: 0,
24
+ width: '100%',
25
+ height: '100%',
26
+ position: 'absolute',
27
+ opacity: 1,
28
+ transition: 'opacity 0.3s ease-in-out',
29
+ pointerEvents: 'auto',
30
+
31
+ // selectors: {
32
+ // '&[data-playing="true"]': {
33
+ // opacity: 0,
34
+ // pointerEvents: 'none',
35
+ // },
36
+ // },
37
+ });
38
+
39
+ const posterImage = style({
40
+ width: '100%',
41
+ height: '100%',
42
+ minWidth: '100%',
43
+ minHeight: '100%',
44
+ objectFit: 'cover',
45
+ });
46
+
47
+ const playButton = style({
48
+ position: 'absolute',
49
+ top: '50%',
50
+ left: '50%',
51
+ transform: 'translate(-50%, -50%)',
52
+ border: 'none',
53
+ borderRadius: themeContract.radii.full,
54
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
55
+ color: themeContract.colors.background,
56
+ cursor: 'pointer',
57
+ transition: 'all 0.3s ease-in-out',
58
+ display: 'flex',
59
+ alignItems: 'center',
60
+ justifyContent: 'center',
61
+ opacity: 1,
62
+ pointerEvents: 'auto',
63
+
64
+ ':hover': {
65
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
66
+ transform: 'translate(-50%, -50%) scale(1.1)',
67
+ },
68
+
69
+ ':focus': {
70
+ outline: '2px solid',
71
+ outlineColor: themeContract.colors.primary,
72
+ outlineOffset: '2px',
73
+ },
74
+
75
+ // selectors: {
76
+ // '&[data-playing="true"]': {
77
+ // opacity: 0,
78
+ // pointerEvents: 'none',
79
+ // },
80
+ // '&[data-hidden="true"]': {
81
+ // display: 'none',
82
+ // },
83
+ // },
84
+ });
85
+
86
+ const controlButton = style({
87
+ position: 'absolute',
88
+ border: 'none',
89
+ borderRadius: themeContract.radii.md,
90
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
91
+ color: themeContract.colors.background,
92
+ cursor: 'pointer',
93
+ transition: 'all 0.3s ease-in-out',
94
+ display: 'flex',
95
+ alignItems: 'center',
96
+ justifyContent: 'center',
97
+
98
+ // ':hover': {
99
+ // backgroundColor: 'rgba(0, 0, 0, 0.9)',
100
+ // },
101
+
102
+ // ':focus': {
103
+ // outline: '2px solid',
104
+ // outlineColor: themeContract.colors.primary,
105
+ // outlineOffset: '2px',
106
+ // },
107
+ });
108
+
109
+ const closeButton = style([
110
+ controlButton,
111
+ {
112
+ top: themeContract.space.md,
113
+ right: themeContract.space.md,
114
+ width: '40px',
115
+ height: '40px',
116
+
117
+ '@media': {
118
+ 'screen and (min-width: 768px)': {
119
+ width: '48px',
120
+ height: '48px',
121
+ top: themeContract.space.lg,
122
+ right: themeContract.space.lg,
123
+ },
124
+ },
125
+ },
126
+ ]);
127
+
128
+ const pauseButton = style([
129
+ controlButton,
130
+ {
131
+ bottom: themeContract.space.md,
132
+ right: '80px',
133
+ width: '40px',
134
+ height: '40px',
135
+
136
+ '@media': {
137
+ 'screen and (min-width: 768px)': {
138
+ width: '48px',
139
+ height: '48px',
140
+ bottom: themeContract.space.lg,
141
+ right: '100px',
142
+ },
143
+ },
144
+ },
145
+ ]);
146
+
147
+ const soundButton = style([
148
+ controlButton,
149
+ {
150
+ bottom: themeContract.space.md,
151
+ right: themeContract.space.md,
152
+ width: '40px',
153
+ height: '40px',
154
+
155
+ '@media': {
156
+ 'screen and (min-width: 768px)': {
157
+ width: '48px',
158
+ height: '48px',
159
+ bottom: themeContract.space.lg,
160
+ right: themeContract.space.lg,
161
+ },
162
+ },
163
+ },
164
+ ]);
165
+
166
+ export const videoRecipe = recipe({
167
+ base: videoBase,
168
+
169
+ variants: {
170
+ size: {
171
+ sm: {
172
+ width: '300px',
173
+ height: '200px',
174
+ },
175
+ md: {
176
+ width: '500px',
177
+ height: '300px',
178
+ },
179
+ lg: {
180
+ width: '800px',
181
+ height: '450px',
182
+ },
183
+ fullWidth: {
184
+ width: '100vw',
185
+ height: 0,
186
+ paddingBottom: '56.25%', // 16:9 aspect ratio
187
+ position: 'relative',
188
+ },
189
+ },
190
+ aspectRatio: {
191
+ '16:9': {
192
+ aspectRatio: '16/9',
193
+ },
194
+ '4:3': {
195
+ aspectRatio: '4/3',
196
+ },
197
+ '1:1': {
198
+ aspectRatio: '1/1',
199
+ },
200
+ },
201
+ },
202
+
203
+ defaultVariants: {
204
+ size: 'md',
205
+ aspectRatio: '16:9',
206
+ },
207
+ });
208
+
209
+ export { videoElement, videoPoster, posterImage, playButton, closeButton, pauseButton, soundButton };
210
+ export type VideoVariants = RecipeVariants<typeof videoRecipe>;
@@ -0,0 +1,50 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { recipe, RecipeVariants } from '@vanilla-extract/recipes';
3
+ import { themeContract } from '../../theme/contract.css';
4
+
5
+ const videoFullWidthBase = style({
6
+ height: 0,
7
+ width: '100vw',
8
+ overflow: 'hidden',
9
+ position: 'relative',
10
+ paddingBottom: '56.25%', // 16:9 aspect ratio
11
+ backgroundColor: themeContract.colors.background,
12
+
13
+ // Break out of container padding
14
+ marginLeft: `calc(-50vw + 50%)`,
15
+ marginRight: `calc(-50vw + 50%)`,
16
+
17
+ '@media': {
18
+ 'screen and (min-width: 768px)': {
19
+ marginLeft: `calc(-50vw + 50%)`,
20
+ marginRight: `calc(-50vw + 50%)`,
21
+ },
22
+ },
23
+ });
24
+
25
+ export const videoFullWidthRecipe = recipe({
26
+ base: videoFullWidthBase,
27
+
28
+ variants: {
29
+ aspectRatio: {
30
+ '16:9': {
31
+ paddingBottom: '56.25%',
32
+ },
33
+ '4:3': {
34
+ paddingBottom: '75%',
35
+ },
36
+ '1:1': {
37
+ paddingBottom: '100%',
38
+ },
39
+ '21:9': {
40
+ paddingBottom: '42.86%',
41
+ },
42
+ },
43
+ },
44
+
45
+ defaultVariants: {
46
+ aspectRatio: '16:9',
47
+ },
48
+ });
49
+
50
+ export type VideoFullWidthVariants = RecipeVariants<typeof videoFullWidthRecipe>;
@@ -0,0 +1,83 @@
1
+ import { createThemeContract } from '@vanilla-extract/css';
2
+
3
+ // Define a theme contract with design tokens
4
+ // This contract can then be reused to create multiple themes or overrides on a global level
5
+ export const themeContract = createThemeContract({
6
+ colors: {
7
+ primary: null,
8
+ secondary: null,
9
+ accent: null,
10
+ background: null,
11
+ surface: null,
12
+ text: null,
13
+ textSecondary: null,
14
+ textLight: null,
15
+ border: null,
16
+ error: null,
17
+ warning: null,
18
+ success: null,
19
+ info: null,
20
+ },
21
+ space: {
22
+ none: null,
23
+ xs: null,
24
+ sm: null,
25
+ md: null,
26
+ lg: null,
27
+ xl: null,
28
+ '2xl': null,
29
+ },
30
+ radii: {
31
+ none: null,
32
+ sm: null,
33
+ md: null,
34
+ lg: null,
35
+ xl: null,
36
+ full: null,
37
+ },
38
+ fonts: {
39
+ body: null,
40
+ heading: null,
41
+ mono: null,
42
+ },
43
+ fontSizes: {
44
+ xs: null,
45
+ sm: null,
46
+ md: null,
47
+ lg: null,
48
+ xl: null,
49
+ '2xl': null,
50
+ '3xl': null,
51
+ '4xl': null,
52
+ },
53
+ fontWeights: {
54
+ light: null,
55
+ normal: null,
56
+ medium: null,
57
+ semibold: null,
58
+ bold: null,
59
+ },
60
+ lineHeights: {
61
+ tight: null,
62
+ normal: null,
63
+ relaxed: null,
64
+ },
65
+ shadows: {
66
+ none: null,
67
+ sm: null,
68
+ md: null,
69
+ lg: null,
70
+ xl: null,
71
+ },
72
+ maxWidth: null,
73
+ section: {
74
+ paddingTop: null,
75
+ paddingBottom: null,
76
+ },
77
+ header: {
78
+ height: null,
79
+ },
80
+ footer: {
81
+ height: null,
82
+ },
83
+ });
@@ -0,0 +1,9 @@
1
+ import { createGlobalTheme } from '@vanilla-extract/css';
2
+ import { baseDarkTheme, baseLightTheme } from './baseThemeValues';
3
+ import { themeContract } from './contract.css';
4
+
5
+ // Create the default light theme at the root
6
+ createGlobalTheme('html', themeContract, baseLightTheme);
7
+
8
+ // Apply dark theme when data-theme="dark"
9
+ createGlobalTheme('html[data-theme="dark"]', themeContract, baseDarkTheme);
@@ -0,0 +1,82 @@
1
+ import { createSprinkles, defineProperties } from '@vanilla-extract/sprinkles';
2
+ import { queries } from './mediaqueries';
3
+ import { themeContract } from '../theme';
4
+
5
+ const responsiveProperties = defineProperties({
6
+ conditions: {
7
+ mobile: {},
8
+ sm: { '@media': queries.sm },
9
+ md: { '@media': queries.md },
10
+ lg: { '@media': queries.lg },
11
+ xl: { '@media': queries.xl },
12
+ '2xl': { '@media': queries['2xl'] },
13
+ },
14
+ defaultCondition: 'mobile',
15
+
16
+ properties: {
17
+ // Spacing
18
+ padding: themeContract.space,
19
+ paddingTop: themeContract.space,
20
+ paddingBottom: themeContract.space,
21
+ paddingLeft: themeContract.space,
22
+ paddingRight: themeContract.space,
23
+ margin: themeContract.space,
24
+ marginTop: themeContract.space,
25
+ marginBottom: themeContract.space,
26
+ marginLeft: themeContract.space,
27
+ marginRight: themeContract.space,
28
+ gap: themeContract.space,
29
+
30
+ // Layout
31
+ display: ['none', 'block', 'inline', 'inline-block', 'flex', 'inline-flex', 'grid', 'inline-grid'],
32
+ flexDirection: ['row', 'column', 'row-reverse', 'column-reverse'],
33
+ // alignItems: ['stretch', 'flex-start', 'center', 'flex-end', 'baseline'],
34
+ justifyContent: ['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly'],
35
+ flexWrap: ['nowrap', 'wrap', 'wrap-reverse'],
36
+ flex: ['1', 'auto', 'initial', 'none'],
37
+
38
+ // Dimensions
39
+ width: ['auto', '100%', '50%', '33.333333%', '25%', 'fit-content', 'min-content', 'max-content'],
40
+ height: ['auto', '100%', '100vh', 'fit-content', 'min-content', 'max-content'],
41
+ minWidth: ['0', '100%', 'fit-content', 'min-content', 'max-content'],
42
+ maxWidth: [themeContract.maxWidth],
43
+ minHeight: ['0', '100%', '100vh'],
44
+
45
+ // Position
46
+ position: ['static', 'relative', 'absolute', 'fixed', 'sticky'],
47
+ top: themeContract.space,
48
+ bottom: themeContract.space,
49
+ left: themeContract.space,
50
+ right: themeContract.space,
51
+ zIndex: [0, 10, 20, 30, 40, 50],
52
+
53
+ // Typography
54
+ fontSize: themeContract.fontSizes,
55
+ fontFamily: themeContract.fonts,
56
+ lineHeight: themeContract.lineHeights,
57
+ textAlign: ['left', 'center', 'right', 'justify'],
58
+ fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'],
59
+
60
+ // Colors
61
+ color: themeContract.colors,
62
+ backgroundColor: themeContract.colors,
63
+
64
+ // Border
65
+ borderRadius: themeContract.radii,
66
+ borderWidth: ['0', '1px', '2px', '4px'],
67
+ borderStyle: ['none', 'solid', 'dashed', 'dotted'],
68
+ borderColor: themeContract.colors,
69
+
70
+ // Effects
71
+ boxShadow: themeContract.shadows,
72
+ opacity: ['0', '0.25', '0.5', '0.75', '1'],
73
+
74
+ // Overflow
75
+ overflow: ['visible', 'hidden', 'scroll', 'auto'],
76
+ overflowX: ['visible', 'hidden', 'scroll', 'auto'],
77
+ overflowY: ['visible', 'hidden', 'scroll', 'auto'],
78
+ },
79
+ });
80
+
81
+ export const sprinkles = createSprinkles(responsiveProperties);
82
+ export type Sprinkles = Parameters<typeof sprinkles>[0];
@@ -0,0 +1,40 @@
1
+ import { createVar, style, globalStyle } from '@vanilla-extract/css';
2
+
3
+ export const vars = {
4
+ displayOnDesktop: createVar(),
5
+ };
6
+
7
+ export const toggleNavStyle = style({
8
+ border: 0,
9
+ width: '25px',
10
+ height: '12px',
11
+ zIndex: 60,
12
+ marginLeft: 0,
13
+ cursor: 'pointer',
14
+ position: 'relative',
15
+
16
+ '@media': {
17
+ 'screen and (min-width: 1024px)': {
18
+ display: vars.displayOnDesktop,
19
+ },
20
+ },
21
+ });
22
+
23
+ export const toggleNavBarStyle = style({
24
+ height: '2px',
25
+ width: '25px',
26
+ marginBottom: '8px',
27
+ display: 'block',
28
+ position: 'relative',
29
+ transformOrigin: 'center center',
30
+ transition: 'all 0.5s ease-in-out',
31
+ });
32
+
33
+ // Style dynamique pour chaque ligne via data attribute
34
+ globalStyle(`${toggleNavBarStyle}[data-open="true"]:nth-of-type(1)`, {
35
+ transform: 'rotate(45deg) translate(4px, 3px)',
36
+ });
37
+
38
+ globalStyle(`${toggleNavBarStyle}[data-open="true"]:nth-of-type(2)`, {
39
+ transform: 'rotate(-45deg) translate(4px, -3px)',
40
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latte-macchiat-io/latte-vanilla-components",
3
- "version": "0.0.167",
3
+ "version": "0.0.168",
4
4
  "description": "Beautiful components for amazing projects, with a touch of Vanilla 🥤",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "files": [
17
17
  "dist",
18
- "dist/**/*.css"
18
+ "src/**/*.css.ts"
19
19
  ],
20
20
  "peerDependencies": {
21
21
  "framer-motion": "^12.4.7",
@@ -58,7 +58,8 @@
58
58
  "typescript": "5.6.3",
59
59
  "typescript-eslint": "^8.21.0",
60
60
  "vite": "^6.0.11",
61
- "vite-plugin-dts": "^4.5.0"
61
+ "vite-plugin-dts": "^4.5.0",
62
+ "vite-plugin-static-copy": "^3.1.2"
62
63
  },
63
64
  "engines": {
64
65
  "node": ">=20.9.0",