spoko-design-system 1.20.0 → 1.21.0

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 (92) hide show
  1. package/.claude/settings.json +48 -48
  2. package/.github/dependabot.yml +11 -11
  3. package/.github/todo.yml +3 -3
  4. package/.github/workflows/claude.yml +37 -37
  5. package/.github/workflows/code-quality.yml +72 -72
  6. package/.github/workflows/deploy.yml +43 -43
  7. package/.husky/README.md +41 -41
  8. package/.husky/commit-msg +1 -1
  9. package/.husky/pre-commit +40 -40
  10. package/.prettierignore +14 -14
  11. package/.prettierrc +30 -30
  12. package/.stackblitzrc +5 -5
  13. package/.vscode/extensions.json +4 -4
  14. package/.vscode/launch.json +11 -11
  15. package/.vscode/settings.json +21 -21
  16. package/CHANGELOG.md +470 -462
  17. package/CLAUDE.md +268 -268
  18. package/LICENSE +21 -21
  19. package/README.md +303 -303
  20. package/TOOLTIPS.md +236 -236
  21. package/astro.config.mjs +84 -84
  22. package/commitlint.config.js +3 -3
  23. package/dev-dist/sw.js +91 -91
  24. package/dev-dist/workbox-c676b6d3.js +3391 -3391
  25. package/eslint.config.js +70 -70
  26. package/icon.config.ts +348 -348
  27. package/index.ts +78 -78
  28. package/package.json +160 -160
  29. package/public/arrow-bottom.svg +7 -7
  30. package/public/fonts/lg.svg +53 -53
  31. package/public/fonts/vwhead-bold-demo.html +549 -549
  32. package/public/fonts/vwhead-regular-demo.html +549 -549
  33. package/public/fonts/vwtext-bold-demo.html +549 -549
  34. package/public/fonts/vwtext-regular-demo.html +549 -549
  35. package/public/github.svg +3 -3
  36. package/public/grid_dot.svg +4 -4
  37. package/public/linkedin.svg +44 -44
  38. package/public/make-scrollable-code-focusable.js +3 -3
  39. package/public/pagefind.yml +3 -3
  40. package/public/polo.blue.svg +29 -29
  41. package/public/spoko.space.svg +71 -71
  42. package/public/twitter.svg +46 -46
  43. package/renovate.json +6 -6
  44. package/sandbox.config.json +11 -11
  45. package/sonar-project.properties +26 -26
  46. package/src/components/Category/CategoriesCarousel.astro +3 -7
  47. package/src/pages/components/badges.mdx +57 -57
  48. package/src/pages/components/breadcrumbs.mdx +139 -139
  49. package/src/pages/components/buttons.mdx +359 -359
  50. package/src/pages/components/card.mdx +294 -294
  51. package/src/pages/components/carousel.mdx +62 -62
  52. package/src/pages/components/copyright.mdx +42 -42
  53. package/src/pages/components/details-list.mdx +207 -207
  54. package/src/pages/components/features-list.mdx +37 -37
  55. package/src/pages/components/flags.mdx +49 -49
  56. package/src/pages/components/fuck-russia.mdx +39 -39
  57. package/src/pages/components/hand-drive.mdx +78 -78
  58. package/src/pages/components/headline.mdx +337 -337
  59. package/src/pages/components/image.mdx +513 -513
  60. package/src/pages/components/input.mdx +367 -367
  61. package/src/pages/components/jumbotron.mdx +530 -530
  62. package/src/pages/components/modal.mdx +212 -212
  63. package/src/pages/components/post-header.mdx +64 -64
  64. package/src/pages/components/pr-code.mdx +213 -213
  65. package/src/pages/components/product-engine.mdx +418 -418
  66. package/src/pages/components/product-number.mdx +58 -58
  67. package/src/pages/components/product-tile.mdx +51 -51
  68. package/src/pages/components/quote.mdx +33 -33
  69. package/src/pages/components/slimbanner.mdx +260 -260
  70. package/src/pages/components/table.mdx +108 -108
  71. package/src/pages/core/colors.mdx +21 -21
  72. package/src/pages/core/grid.mdx +193 -193
  73. package/src/pages/core/introduction.mdx +77 -77
  74. package/src/pages/core/tooltips.mdx +491 -491
  75. package/src/pages/patterns/introduction.mdx +60 -60
  76. package/src/styles/_variables.scss +70 -70
  77. package/tailwind.config.cjs +8 -8
  78. package/tsconfig.json +28 -28
  79. package/uno-config/index.ts +269 -269
  80. package/uno-config/theme/breakpoints.ts +9 -9
  81. package/uno-config/theme/colors.ts +65 -65
  82. package/uno-config/theme/dimensions.ts +17 -17
  83. package/uno-config/theme/effects.ts +14 -14
  84. package/uno-config/theme/grid.ts +10 -10
  85. package/uno-config/theme/index.ts +26 -26
  86. package/uno-config/theme/shortcuts/buttons.ts +53 -53
  87. package/uno-config/theme/shortcuts/components.ts +124 -124
  88. package/uno-config/theme/shortcuts/index.ts +20 -20
  89. package/uno-config/theme/shortcuts/jumbotron.ts +71 -71
  90. package/uno-config/theme/shortcuts/layout.ts +75 -75
  91. package/uno-config/theme/typography.ts +29 -29
  92. package/uno.config.ts +2 -2
@@ -1,270 +1,270 @@
1
- // uno-config/index.ts
2
- import type { UserConfig, UserShortcuts } from 'unocss'
3
- import { defineConfig } from 'unocss';
4
-
5
- // REQUIRED IMPORTS: These imports are used in the createSdsConfig function
6
- // Removing or commenting out any of these will break the UnoCSS configuration
7
- import {
8
- transformerDirectives, // Used in transformers array
9
- transformerVariantGroup, // Used in transformers array
10
- presetAttributify, // Used in presets array
11
- presetIcons, // Used in presets array with specific configuration
12
- } from 'unocss';
13
-
14
- // These presets must be imported explicitly to be used in the configuration
15
- import presetUno from '@unocss/preset-uno'; // Primary UnoCSS preset
16
- import presetTypography from '@unocss/preset-typography'; // Typography preset
17
- import presetWebFonts from '@unocss/preset-web-fonts'; // Web fonts preset
18
-
19
- import { shortcuts } from './theme/shortcuts';
20
- import { theme } from './theme';
21
-
22
- // Static imports for all icon collections (prevents Vite module runner issues)
23
- import antDesignIcons from '@iconify-json/ant-design/icons.json';
24
- import biIcons from '@iconify-json/bi/icons.json';
25
- import bxIcons from '@iconify-json/bx/icons.json';
26
- import carbonIcons from '@iconify-json/carbon/icons.json';
27
- import circleFlagsIcons from '@iconify-json/circle-flags/icons.json';
28
- import eiIcons from '@iconify-json/ei/icons.json';
29
- import elIcons from '@iconify-json/el/icons.json';
30
- import eosIcons from '@iconify-json/eos-icons/icons.json';
31
- import etIcons from '@iconify-json/et/icons.json';
32
- import flowbiteIcons from '@iconify-json/flowbite/icons.json';
33
- import fluentIcons from '@iconify-json/fluent/icons.json';
34
- import fluentEmojiIcons from '@iconify-json/fluent-emoji/icons.json';
35
- import icIcons from '@iconify-json/ic/icons.json';
36
- import iconParkOutlineIcons from '@iconify-json/icon-park-outline/icons.json';
37
- import laIcons from '@iconify-json/la/icons.json';
38
- import lucideIcons from '@iconify-json/lucide/icons.json';
39
- import materialSymbolsLightIcons from '@iconify-json/material-symbols-light/icons.json';
40
- import mdiIcons from '@iconify-json/mdi/icons.json';
41
- import notoV1Icons from '@iconify-json/noto-v1/icons.json';
42
- import octiconIcons from '@iconify-json/octicon/icons.json';
43
- import phIcons from '@iconify-json/ph/icons.json';
44
- import simpleIcons from '@iconify-json/simple-icons/icons.json';
45
- import systemUiconsIcons from '@iconify-json/system-uicons/icons.json';
46
- import uilIcons from '@iconify-json/uil/icons.json';
47
- import vscodeIcons from '@iconify-json/vscode-icons/icons.json';
48
- import streamlineFreehandColorIcons from '@iconify-json/streamline-freehand-color/icons.json';
49
-
50
- // List of peer selectors we want to preserve during build
51
- const peerSelectorClasses = [
52
- // Focus state classes
53
- 'peer-focus:text-blue-light',
54
- 'peer-focus:dark:text-blue-lightest',
55
- 'peer-focus:scale-75',
56
- 'peer-focus:-translate-y-6',
57
- 'peer-focus:-translate-y-4',
58
- 'peer-focus:start-0',
59
-
60
- // Placeholder shown classes
61
- 'peer-placeholder-shown:scale-100',
62
- 'peer-placeholder-shown:translate-y-0',
63
-
64
- // Not placeholder shown classes
65
- 'peer-not-placeholder-shown:scale-75',
66
- 'peer-not-placeholder-shown:-translate-y-6',
67
- 'peer-not-placeholder-shown:-translate-y-4',
68
- ];
69
-
70
- interface CustomConfig extends Partial<UserConfig> {
71
- shortcuts?: UserShortcuts;
72
- theme?: Partial<typeof theme>;
73
- }
74
-
75
- /**
76
- * Creates a UnoCSS configuration with Spoko Design System defaults
77
- *
78
- * IMPORTANT: This function requires all the imported UnoCSS presets and transformers.
79
- * Do not remove any imports at the top of this file as they are necessary for
80
- * proper functioning of the UnoCSS configuration.
81
- *
82
- * @param customConfig - Optional custom configuration to merge with defaults
83
- * @returns Complete UnoCSS configuration
84
- */
85
- export function createSdsConfig(customConfig: CustomConfig = {}) {
86
- return defineConfig({
87
- // Optimizations for static builds
88
- ...(process.env.NODE_ENV === 'production' && {
89
- inspector: false,
90
- hmr: false,
91
- }),
92
-
93
- // Transform directives and variant groups
94
- transformers: [
95
- transformerDirectives(),
96
- transformerVariantGroup(),
97
- ],
98
- shortcuts: {
99
- ...shortcuts,
100
- ...(customConfig.shortcuts || {})
101
- },
102
- theme: {
103
- ...theme,
104
- ...(customConfig.theme || {})
105
- },
106
- // Enhanced variants to better handle peer selectors
107
- variants: [
108
- // Add specific peer variant support
109
- (matcher) => {
110
- if (!matcher.startsWith('peer-'))
111
- return matcher;
112
-
113
- const peerVariant = matcher.slice(5);
114
- const selectorMap = {
115
- 'focus:': (s) => `.peer:focus ~ ${s}`,
116
- 'hover:': (s) => `.peer:hover ~ ${s}`,
117
- 'placeholder-shown:': (s) => `.peer:placeholder-shown ~ ${s}`,
118
- 'not-placeholder-shown:': (s) => `.peer:not(:placeholder-shown) ~ ${s}`,
119
- };
120
-
121
- // Check for nested variants like 'peer-focus:text-blue'
122
- for (const [key, selectorFn] of Object.entries(selectorMap)) {
123
- if (peerVariant.startsWith(key)) {
124
- return {
125
- matcher: peerVariant.slice(key.length),
126
- selector: selectorFn,
127
- };
128
- }
129
- }
130
-
131
- // Default peer handling
132
- return {
133
- matcher: peerVariant,
134
- selector: (s) => `.peer:${peerVariant} ~ ${s}`,
135
- };
136
- },
137
- ],
138
- // Optimized safelist for static Astro builds
139
- safelist: [
140
- // Layout and grid classes that might be used dynamically
141
- 'md:grid-cols-product',
142
-
143
- // Component-specific classes for static generation
144
- 'breadcrumb-link-disabled',
145
- 'breadcrumb-link',
146
- 'breadcrumb-item',
147
- 'features-list-caption',
148
- 'features-list-ul',
149
- 'features-list-item',
150
- 'category-link-base',
151
- 'category-link-active',
152
-
153
- // Essential peer and input classes
154
- 'peer',
155
- 'resize-none',
156
- 'origin-top-left',
157
- 'transform-gpu',
158
-
159
- // Dynamic icons from ProductDetailsList component
160
- 'i-lucide-book-text',
161
- 'i-lucide-link',
162
- 'i-simple-icons-youtube',
163
- 'i-simple-icons-vimeo',
164
-
165
- // All peer selectors from the list (needed for floating labels)
166
- ...peerSelectorClasses,
167
- ],
168
- // Optimized extractors for static Astro builds
169
- extractors: [
170
- {
171
- name: 'astro-static',
172
- extract({ code, id }) {
173
- const result = new Set();
174
-
175
- // Only extract from class attributes to prevent false positives
176
- const classRegex = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
177
- let match;
178
- while ((match = classRegex.exec(code)) !== null) {
179
- match[1].split(/\s+/).forEach(cls => {
180
- // Only add classes that don't look like malformed icon names
181
- // Filter out patterns like i-lucide-link-Validate, i-simple-icons-youtube-case, etc.
182
- if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
183
- result.add(cls);
184
- }
185
- });
186
- }
187
-
188
- // For .astro files, extract from dynamic class bindings
189
- if (id && id.endsWith('.astro')) {
190
- const dynamicClassRegex = /class:\w+\s*=\s*["'`]([^"'`]+)["'`]/g;
191
- while ((match = dynamicClassRegex.exec(code)) !== null) {
192
- match[1].split(/\s+/).forEach(cls => {
193
- if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
194
- result.add(cls);
195
- }
196
- });
197
- }
198
- }
199
-
200
- return result;
201
- },
202
- },
203
- ],
204
- // IMPORTANT: All of these presets are required for proper functioning
205
- presets: [
206
- presetUno(),
207
- presetAttributify(),
208
- presetIcons({
209
- scale: 1.2,
210
- warn: false, // Disabled to prevent false positives from JS code scanning
211
- prefix: 'i-',
212
- extraProperties: {
213
- 'display': 'inline-block',
214
- 'vertical-align': 'middle',
215
- },
216
- collections: {
217
- // All icon collections with static imports to prevent Vite module runner issues
218
- 'ant-design': antDesignIcons,
219
- 'bi': biIcons,
220
- 'bx': bxIcons,
221
- 'carbon': carbonIcons,
222
- 'circle-flags': circleFlagsIcons,
223
- 'ei': eiIcons,
224
- 'el': elIcons,
225
- 'eos-icons': eosIcons,
226
- 'et': etIcons,
227
- 'flowbite': flowbiteIcons,
228
- 'fluent': fluentIcons,
229
- 'fluent-emoji': fluentEmojiIcons,
230
- 'ic': icIcons,
231
- 'icon-park-outline': iconParkOutlineIcons,
232
- 'la': laIcons,
233
- 'lucide': lucideIcons,
234
- 'material-symbols-light': materialSymbolsLightIcons,
235
- 'mdi': mdiIcons,
236
- 'noto-v1': notoV1Icons,
237
- 'octicon': octiconIcons,
238
- 'ph': phIcons,
239
- 'simple-icons': simpleIcons,
240
- 'system-uicons': systemUiconsIcons,
241
- 'uil': uilIcons,
242
- 'vscode-icons': vscodeIcons,
243
- 'streamline-freehand-color': streamlineFreehandColorIcons,
244
- }
245
- }),
246
- presetTypography(),
247
- presetWebFonts({
248
- provider: 'none',
249
- fonts: theme.fontFamily
250
- })
251
- ],
252
-
253
- // Additional optimizations for static Astro builds
254
- preflights: [
255
- {
256
- getCSS: () => `
257
- /* Optimized base styles for static builds */
258
- *,*::before,*::after{box-sizing:border-box}
259
- html{line-height:1.5;-webkit-text-size-adjust:100%}
260
- body{margin:0;font-family:vw_textregular,system-ui,sans-serif}
261
- `
262
- }
263
- ],
264
-
265
- ...customConfig
266
- });
267
- }
268
-
269
- export * from './theme';
1
+ // uno-config/index.ts
2
+ import type { UserConfig, UserShortcuts } from 'unocss'
3
+ import { defineConfig } from 'unocss';
4
+
5
+ // REQUIRED IMPORTS: These imports are used in the createSdsConfig function
6
+ // Removing or commenting out any of these will break the UnoCSS configuration
7
+ import {
8
+ transformerDirectives, // Used in transformers array
9
+ transformerVariantGroup, // Used in transformers array
10
+ presetAttributify, // Used in presets array
11
+ presetIcons, // Used in presets array with specific configuration
12
+ } from 'unocss';
13
+
14
+ // These presets must be imported explicitly to be used in the configuration
15
+ import presetUno from '@unocss/preset-uno'; // Primary UnoCSS preset
16
+ import presetTypography from '@unocss/preset-typography'; // Typography preset
17
+ import presetWebFonts from '@unocss/preset-web-fonts'; // Web fonts preset
18
+
19
+ import { shortcuts } from './theme/shortcuts';
20
+ import { theme } from './theme';
21
+
22
+ // Static imports for all icon collections (prevents Vite module runner issues)
23
+ import antDesignIcons from '@iconify-json/ant-design/icons.json';
24
+ import biIcons from '@iconify-json/bi/icons.json';
25
+ import bxIcons from '@iconify-json/bx/icons.json';
26
+ import carbonIcons from '@iconify-json/carbon/icons.json';
27
+ import circleFlagsIcons from '@iconify-json/circle-flags/icons.json';
28
+ import eiIcons from '@iconify-json/ei/icons.json';
29
+ import elIcons from '@iconify-json/el/icons.json';
30
+ import eosIcons from '@iconify-json/eos-icons/icons.json';
31
+ import etIcons from '@iconify-json/et/icons.json';
32
+ import flowbiteIcons from '@iconify-json/flowbite/icons.json';
33
+ import fluentIcons from '@iconify-json/fluent/icons.json';
34
+ import fluentEmojiIcons from '@iconify-json/fluent-emoji/icons.json';
35
+ import icIcons from '@iconify-json/ic/icons.json';
36
+ import iconParkOutlineIcons from '@iconify-json/icon-park-outline/icons.json';
37
+ import laIcons from '@iconify-json/la/icons.json';
38
+ import lucideIcons from '@iconify-json/lucide/icons.json';
39
+ import materialSymbolsLightIcons from '@iconify-json/material-symbols-light/icons.json';
40
+ import mdiIcons from '@iconify-json/mdi/icons.json';
41
+ import notoV1Icons from '@iconify-json/noto-v1/icons.json';
42
+ import octiconIcons from '@iconify-json/octicon/icons.json';
43
+ import phIcons from '@iconify-json/ph/icons.json';
44
+ import simpleIcons from '@iconify-json/simple-icons/icons.json';
45
+ import systemUiconsIcons from '@iconify-json/system-uicons/icons.json';
46
+ import uilIcons from '@iconify-json/uil/icons.json';
47
+ import vscodeIcons from '@iconify-json/vscode-icons/icons.json';
48
+ import streamlineFreehandColorIcons from '@iconify-json/streamline-freehand-color/icons.json';
49
+
50
+ // List of peer selectors we want to preserve during build
51
+ const peerSelectorClasses = [
52
+ // Focus state classes
53
+ 'peer-focus:text-blue-light',
54
+ 'peer-focus:dark:text-blue-lightest',
55
+ 'peer-focus:scale-75',
56
+ 'peer-focus:-translate-y-6',
57
+ 'peer-focus:-translate-y-4',
58
+ 'peer-focus:start-0',
59
+
60
+ // Placeholder shown classes
61
+ 'peer-placeholder-shown:scale-100',
62
+ 'peer-placeholder-shown:translate-y-0',
63
+
64
+ // Not placeholder shown classes
65
+ 'peer-not-placeholder-shown:scale-75',
66
+ 'peer-not-placeholder-shown:-translate-y-6',
67
+ 'peer-not-placeholder-shown:-translate-y-4',
68
+ ];
69
+
70
+ interface CustomConfig extends Partial<UserConfig> {
71
+ shortcuts?: UserShortcuts;
72
+ theme?: Partial<typeof theme>;
73
+ }
74
+
75
+ /**
76
+ * Creates a UnoCSS configuration with Spoko Design System defaults
77
+ *
78
+ * IMPORTANT: This function requires all the imported UnoCSS presets and transformers.
79
+ * Do not remove any imports at the top of this file as they are necessary for
80
+ * proper functioning of the UnoCSS configuration.
81
+ *
82
+ * @param customConfig - Optional custom configuration to merge with defaults
83
+ * @returns Complete UnoCSS configuration
84
+ */
85
+ export function createSdsConfig(customConfig: CustomConfig = {}) {
86
+ return defineConfig({
87
+ // Optimizations for static builds
88
+ ...(process.env.NODE_ENV === 'production' && {
89
+ inspector: false,
90
+ hmr: false,
91
+ }),
92
+
93
+ // Transform directives and variant groups
94
+ transformers: [
95
+ transformerDirectives(),
96
+ transformerVariantGroup(),
97
+ ],
98
+ shortcuts: {
99
+ ...shortcuts,
100
+ ...(customConfig.shortcuts || {})
101
+ },
102
+ theme: {
103
+ ...theme,
104
+ ...(customConfig.theme || {})
105
+ },
106
+ // Enhanced variants to better handle peer selectors
107
+ variants: [
108
+ // Add specific peer variant support
109
+ (matcher) => {
110
+ if (!matcher.startsWith('peer-'))
111
+ return matcher;
112
+
113
+ const peerVariant = matcher.slice(5);
114
+ const selectorMap = {
115
+ 'focus:': (s) => `.peer:focus ~ ${s}`,
116
+ 'hover:': (s) => `.peer:hover ~ ${s}`,
117
+ 'placeholder-shown:': (s) => `.peer:placeholder-shown ~ ${s}`,
118
+ 'not-placeholder-shown:': (s) => `.peer:not(:placeholder-shown) ~ ${s}`,
119
+ };
120
+
121
+ // Check for nested variants like 'peer-focus:text-blue'
122
+ for (const [key, selectorFn] of Object.entries(selectorMap)) {
123
+ if (peerVariant.startsWith(key)) {
124
+ return {
125
+ matcher: peerVariant.slice(key.length),
126
+ selector: selectorFn,
127
+ };
128
+ }
129
+ }
130
+
131
+ // Default peer handling
132
+ return {
133
+ matcher: peerVariant,
134
+ selector: (s) => `.peer:${peerVariant} ~ ${s}`,
135
+ };
136
+ },
137
+ ],
138
+ // Optimized safelist for static Astro builds
139
+ safelist: [
140
+ // Layout and grid classes that might be used dynamically
141
+ 'md:grid-cols-product',
142
+
143
+ // Component-specific classes for static generation
144
+ 'breadcrumb-link-disabled',
145
+ 'breadcrumb-link',
146
+ 'breadcrumb-item',
147
+ 'features-list-caption',
148
+ 'features-list-ul',
149
+ 'features-list-item',
150
+ 'category-link-base',
151
+ 'category-link-active',
152
+
153
+ // Essential peer and input classes
154
+ 'peer',
155
+ 'resize-none',
156
+ 'origin-top-left',
157
+ 'transform-gpu',
158
+
159
+ // Dynamic icons from ProductDetailsList component
160
+ 'i-lucide-book-text',
161
+ 'i-lucide-link',
162
+ 'i-simple-icons-youtube',
163
+ 'i-simple-icons-vimeo',
164
+
165
+ // All peer selectors from the list (needed for floating labels)
166
+ ...peerSelectorClasses,
167
+ ],
168
+ // Optimized extractors for static Astro builds
169
+ extractors: [
170
+ {
171
+ name: 'astro-static',
172
+ extract({ code, id }) {
173
+ const result = new Set();
174
+
175
+ // Only extract from class attributes to prevent false positives
176
+ const classRegex = /class(?:Name)?=["'`]([^"'`]+)["'`]/g;
177
+ let match;
178
+ while ((match = classRegex.exec(code)) !== null) {
179
+ match[1].split(/\s+/).forEach(cls => {
180
+ // Only add classes that don't look like malformed icon names
181
+ // Filter out patterns like i-lucide-link-Validate, i-simple-icons-youtube-case, etc.
182
+ if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
183
+ result.add(cls);
184
+ }
185
+ });
186
+ }
187
+
188
+ // For .astro files, extract from dynamic class bindings
189
+ if (id && id.endsWith('.astro')) {
190
+ const dynamicClassRegex = /class:\w+\s*=\s*["'`]([^"'`]+)["'`]/g;
191
+ while ((match = dynamicClassRegex.exec(code)) !== null) {
192
+ match[1].split(/\s+/).forEach(cls => {
193
+ if (cls && !cls.match(/^i-(lucide|simple-icons|mdi|ant-design|bi|bx|carbon|el|eos-icons|fluent|flowbite|la|octicon|uil|icon-park-outline|ph|ic|material-symbols-light|et|system-uicons|vscode-icons|streamline-freehand-color)-\w+-(case|return|if|const|Validate|items|validatedItems|Grouping|function|switch|default)/i) && !cls.includes('Grouping')) {
194
+ result.add(cls);
195
+ }
196
+ });
197
+ }
198
+ }
199
+
200
+ return result;
201
+ },
202
+ },
203
+ ],
204
+ // IMPORTANT: All of these presets are required for proper functioning
205
+ presets: [
206
+ presetUno(),
207
+ presetAttributify(),
208
+ presetIcons({
209
+ scale: 1.2,
210
+ warn: false, // Disabled to prevent false positives from JS code scanning
211
+ prefix: 'i-',
212
+ extraProperties: {
213
+ 'display': 'inline-block',
214
+ 'vertical-align': 'middle',
215
+ },
216
+ collections: {
217
+ // All icon collections with static imports to prevent Vite module runner issues
218
+ 'ant-design': antDesignIcons,
219
+ 'bi': biIcons,
220
+ 'bx': bxIcons,
221
+ 'carbon': carbonIcons,
222
+ 'circle-flags': circleFlagsIcons,
223
+ 'ei': eiIcons,
224
+ 'el': elIcons,
225
+ 'eos-icons': eosIcons,
226
+ 'et': etIcons,
227
+ 'flowbite': flowbiteIcons,
228
+ 'fluent': fluentIcons,
229
+ 'fluent-emoji': fluentEmojiIcons,
230
+ 'ic': icIcons,
231
+ 'icon-park-outline': iconParkOutlineIcons,
232
+ 'la': laIcons,
233
+ 'lucide': lucideIcons,
234
+ 'material-symbols-light': materialSymbolsLightIcons,
235
+ 'mdi': mdiIcons,
236
+ 'noto-v1': notoV1Icons,
237
+ 'octicon': octiconIcons,
238
+ 'ph': phIcons,
239
+ 'simple-icons': simpleIcons,
240
+ 'system-uicons': systemUiconsIcons,
241
+ 'uil': uilIcons,
242
+ 'vscode-icons': vscodeIcons,
243
+ 'streamline-freehand-color': streamlineFreehandColorIcons,
244
+ }
245
+ }),
246
+ presetTypography(),
247
+ presetWebFonts({
248
+ provider: 'none',
249
+ fonts: theme.fontFamily
250
+ })
251
+ ],
252
+
253
+ // Additional optimizations for static Astro builds
254
+ preflights: [
255
+ {
256
+ getCSS: () => `
257
+ /* Optimized base styles for static builds */
258
+ *,*::before,*::after{box-sizing:border-box}
259
+ html{line-height:1.5;-webkit-text-size-adjust:100%}
260
+ body{margin:0;font-family:vw_textregular,system-ui,sans-serif}
261
+ `
262
+ }
263
+ ],
264
+
265
+ ...customConfig
266
+ });
267
+ }
268
+
269
+ export * from './theme';
270
270
  export * from './theme/shortcuts';
@@ -1,10 +1,10 @@
1
- // theme/breakpoints.ts
2
- export const breakpoints = {
3
- sm: '640px',
4
- md: '768px',
5
- lg: '1024px',
6
- xl: '1280px',
7
- '2xl': '1536px',
8
- '3xl': '1920px',
9
- '4xl': '2400px',
1
+ // theme/breakpoints.ts
2
+ export const breakpoints = {
3
+ sm: '640px',
4
+ md: '768px',
5
+ lg: '1024px',
6
+ xl: '1280px',
7
+ '2xl': '1536px',
8
+ '3xl': '1920px',
9
+ '4xl': '2400px',
10
10
  };