@@ -269,16 +269,49 @@ const RING_MAP: Record<string, Record<string, string>> = {
269269 'ring-inset' : { '--hw-ring-inset' : 'inset' } ,
270270}
271271
272- // Shadow utilities - direct raw class to CSS
272+ // Shadow utilities - use CSS variable system for shadow color support
273+ // --hw-shadow holds the default shadow, --hw-shadow-colored replaces colors with var(--hw-shadow-color)
274+ // box-shadow references --hw-shadow which can be swapped to --hw-shadow-colored by a shadow-{color} utility
273275const SHADOW_MAP : Record < string , Record < string , string > > = {
274- 'shadow-sm' : { 'box-shadow' : '0 1px 2px 0 rgb(0 0 0 / 0.05)' } ,
275- 'shadow' : { 'box-shadow' : '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)' } ,
276- 'shadow-md' : { 'box-shadow' : '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)' } ,
277- 'shadow-lg' : { 'box-shadow' : '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)' } ,
278- 'shadow-xl' : { 'box-shadow' : '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)' } ,
279- 'shadow-2xl' : { 'box-shadow' : '0 25px 50px -12px rgb(0 0 0 / 0.25)' } ,
280- 'shadow-inner' : { 'box-shadow' : 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)' } ,
281- 'shadow-none' : { 'box-shadow' : '0 0 #0000' } ,
276+ 'shadow-sm' : {
277+ '--hw-shadow' : '0 1px 2px 0 rgb(0 0 0 / 0.05)' ,
278+ '--hw-shadow-colored' : '0 1px 2px 0 var(--hw-shadow-color)' ,
279+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
280+ } ,
281+ 'shadow' : {
282+ '--hw-shadow' : '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)' ,
283+ '--hw-shadow-colored' : '0 1px 3px 0 var(--hw-shadow-color), 0 1px 2px -1px var(--hw-shadow-color)' ,
284+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
285+ } ,
286+ 'shadow-md' : {
287+ '--hw-shadow' : '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)' ,
288+ '--hw-shadow-colored' : '0 4px 6px -1px var(--hw-shadow-color), 0 2px 4px -2px var(--hw-shadow-color)' ,
289+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
290+ } ,
291+ 'shadow-lg' : {
292+ '--hw-shadow' : '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)' ,
293+ '--hw-shadow-colored' : '0 10px 15px -3px var(--hw-shadow-color), 0 4px 6px -4px var(--hw-shadow-color)' ,
294+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
295+ } ,
296+ 'shadow-xl' : {
297+ '--hw-shadow' : '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)' ,
298+ '--hw-shadow-colored' : '0 20px 25px -5px var(--hw-shadow-color), 0 8px 10px -6px var(--hw-shadow-color)' ,
299+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
300+ } ,
301+ 'shadow-2xl' : {
302+ '--hw-shadow' : '0 25px 50px -12px rgb(0 0 0 / 0.25)' ,
303+ '--hw-shadow-colored' : '0 25px 50px -12px var(--hw-shadow-color)' ,
304+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
305+ } ,
306+ 'shadow-inner' : {
307+ '--hw-shadow' : 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)' ,
308+ '--hw-shadow-colored' : 'inset 0 2px 4px 0 var(--hw-shadow-color)' ,
309+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
310+ } ,
311+ 'shadow-none' : {
312+ '--hw-shadow' : '0 0 #0000' ,
313+ 'box-shadow' : 'var(--hw-ring-offset-shadow, 0 0 #0000), var(--hw-ring-shadow, 0 0 #0000), var(--hw-shadow)' ,
314+ } ,
282315}
283316
284317// Border radius - direct raw class to CSS
@@ -1285,6 +1318,8 @@ export class CSSGenerator {
12851318 private screenBreakpoints : Map < string , string >
12861319 // Cache for utility+value combinations that don't match any rule (negative cache)
12871320 private noMatchCache : Set < string > = new Set ( )
1321+ // Preserve extend colors for CSS variable generation (only custom colors, not defaults)
1322+ private extendColors : Record < string , string | Record < string , string > > | null = null
12881323
12891324 constructor ( private config : CrosswindConfig ) {
12901325 // Merge preset themes into the main config theme
@@ -1296,6 +1331,11 @@ export class CSSGenerator {
12961331 }
12971332 }
12981333
1334+ // Save extend colors before merging (for CSS variable generation)
1335+ if ( config . theme . extend ?. colors ) {
1336+ this . extendColors = config . theme . extend . colors as Record < string , string | Record < string , string > >
1337+ }
1338+
12991339 // Merge theme.extend into theme (allows users to add custom values without replacing defaults)
13001340 if ( config . theme . extend ) {
13011341 const { extend, ...baseTheme } = this . config . theme
@@ -2094,10 +2134,12 @@ export class CSSGenerator {
20942134
20952135 /**
20962136 * Generate :root CSS variables from theme colors
2137+ * Uses only extend colors (custom) if available, to avoid dumping 300+ default Tailwind colors.
20972138 * Flattens nested color objects: { monokai: { bg: '#2d2a2e' } } -> --monokai-bg: #2d2a2e
20982139 */
20992140 private generateCSSVariables ( ) : string | null {
2100- const colors = this . config . theme . colors
2141+ // Prefer extend colors (user's custom colors only), fall back to all theme colors
2142+ const colors = this . extendColors || this . config . theme . colors
21012143 if ( ! colors || Object . keys ( colors ) . length === 0 ) return null
21022144
21032145 const vars : string [ ] = [ ]
0 commit comments