@@ -200,6 +200,71 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
200200 } ;
201201 } , [ enable3D , handleMovement , resetCardPosition ] ) ;
202202
203+ // Determine if we're in dark mode by checking for the .dark class on html
204+ const isDarkMode = typeof document !== 'undefined' &&
205+ document . documentElement . classList . contains ( 'dark' ) ;
206+
207+ // Handle custom colors in dark mode
208+ const isCustomBorderColor = borderColor !== "#4299e1" ;
209+ const isCustomBackgroundColor = backgroundColor !== "#ebf8ff" ;
210+
211+ // For custom colors, darken them in dark mode but preserve their hue
212+ const darkModeBorderColor = isDarkMode
213+ ? isCustomBorderColor
214+ // If it's a custom color, darken it but preserve the hue
215+ ? adjustColorForDarkMode ( borderColor )
216+ // Default dark blue for the default border
217+ : "#1e40af"
218+ : borderColor ;
219+
220+ // For custom background colors, darken them significantly in dark mode
221+ const darkModeBackgroundColor = isDarkMode
222+ ? isCustomBackgroundColor
223+ // If it's a custom background, darken it but preserve the hue
224+ ? adjustColorForDarkMode ( backgroundColor , 0.3 ) // More darkening for backgrounds
225+ // Default dark blue background
226+ : "#0f172a"
227+ : backgroundColor ;
228+
229+ // Helper function to adjust colors for dark mode
230+ function adjustColorForDarkMode ( color : string , darkFactor = 0.6 ) {
231+ // Simple color darkening for hex colors
232+ if ( color . startsWith ( '#' ) ) {
233+ // Convert hex to RGB
234+ const r = parseInt ( color . slice ( 1 , 3 ) , 16 ) ;
235+ const g = parseInt ( color . slice ( 3 , 5 ) , 16 ) ;
236+ const b = parseInt ( color . slice ( 5 , 7 ) , 16 ) ;
237+
238+ // Darken the color
239+ const darkenedR = Math . floor ( r * darkFactor ) ;
240+ const darkenedG = Math . floor ( g * darkFactor ) ;
241+ const darkenedB = Math . floor ( b * darkFactor ) ;
242+
243+ // Convert back to hex
244+ return `#${ darkenedR . toString ( 16 ) . padStart ( 2 , '0' ) } ${ darkenedG . toString ( 16 ) . padStart ( 2 , '0' ) } ${ darkenedB . toString ( 16 ) . padStart ( 2 , '0' ) } ` ;
245+ }
246+
247+ return color ;
248+ }
249+
250+ // Determine text colors based on background darkness
251+ const isDarkBackground = isDarkMode || isColorDark ( backgroundColor ) ;
252+
253+ // Helper function to determine if a color is dark
254+ function isColorDark ( color : string ) : boolean {
255+ if ( color . startsWith ( '#' ) ) {
256+ const r = parseInt ( color . slice ( 1 , 3 ) , 16 ) ;
257+ const g = parseInt ( color . slice ( 3 , 5 ) , 16 ) ;
258+ const b = parseInt ( color . slice ( 5 , 7 ) , 16 ) ;
259+
260+ // Calculate perceived brightness (YIQ formula)
261+ const yiq = ( ( r * 299 ) + ( g * 587 ) + ( b * 114 ) ) / 1000 ;
262+ return yiq < 128 ; // Less than 128 is considered dark
263+ }
264+
265+ return false ;
266+ }
267+
203268 return (
204269 < div
205270 ref = { ( node ) => {
@@ -219,32 +284,52 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
219284 className
220285 ) }
221286 style = { {
222- backgroundColor : backgroundColor ,
223- boxShadow : `0 10px 30px -5px rgba(0, 0, 0, 0.3)` ,
224- border : `8px solid ${ borderColor } ` ,
287+ backgroundColor : darkModeBackgroundColor ,
288+ boxShadow : isDarkMode
289+ ? `0 10px 30px -5px rgba(0, 0, 0, 0.7), 0 0 15px rgba(255, 255, 255, 0.1)`
290+ : `0 10px 30px -5px rgba(0, 0, 0, 0.3)` ,
291+ border : `8px solid ${ darkModeBorderColor } ` ,
225292 transformStyle : 'preserve-3d' ,
226293 } }
227294 { ...props }
228295 >
229- { /* Glare effect overlay */ }
296+ { /* Glare effect overlay - reduce intensity in dark mode */ }
230297 < div
231298 ref = { glareRef }
232299 className = "absolute inset-0 z-20 pointer-events-none"
233300 style = { {
234301 borderRadius : 'inherit' ,
302+ opacity : isDarkMode ? 0.7 : 1 ,
235303 } }
236304 />
237305
238306 { /* Card header with title and attribute */ }
239- < div className = "flex justify-between items-center p-3 border-b border-gray-200 bg-white/90" >
307+ < div className = { cn (
308+ "flex justify-between items-center p-3 border-b" ,
309+ isDarkMode || isDarkBackground
310+ ? "border-gray-700 bg-gray-800/90 text-white"
311+ : "border-gray-200 bg-white/90 text-gray-900"
312+ ) } >
240313 < div >
241- < h3 className = "font-bold text-lg" > { title } </ h3 >
242- { subtitle && < p className = "text-xs text-gray-500" > { subtitle } </ p > }
314+ < h3 className = { cn (
315+ "font-bold text-lg" ,
316+ isDarkMode || isDarkBackground ? "text-white" : "text-gray-900"
317+ ) } > { title } </ h3 >
318+ { subtitle && < p className = { cn (
319+ "text-xs" ,
320+ isDarkMode || isDarkBackground ? "text-gray-300" : "text-gray-500"
321+ ) } > { subtitle } </ p > }
243322 </ div >
244323 { attributeValue && (
245324 < div className = "flex items-center" >
246- < span className = "font-bold text-xl" > { attributeValue } </ span >
247- { attributeLabel && < span className = "text-xs ml-1" > { attributeLabel } </ span > }
325+ < span className = { cn (
326+ "font-bold text-xl" ,
327+ isDarkMode || isDarkBackground ? "text-white" : "text-gray-900"
328+ ) } > { attributeValue } </ span >
329+ { attributeLabel && < span className = { cn (
330+ "text-xs ml-1" ,
331+ isDarkMode || isDarkBackground ? "text-gray-300" : "text-gray-700"
332+ ) } > { attributeLabel } </ span > }
248333 </ div >
249334 ) }
250335 </ div >
@@ -256,20 +341,34 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
256341 backgroundImage : `url(${ imageUrl } )` ,
257342 transform : 'translateZ(20px)' , // 3D effect for the image
258343 transformStyle : 'preserve-3d' ,
344+ backgroundColor : isDarkMode ? '#1e293b' : '#f8fafc' , // Subtle background for image area
259345 } }
260346 />
261347
262348 { /* Card content */ }
263- < div className = "p-4 bg-white/90" >
349+ < div className = { cn (
350+ "p-4" ,
351+ isDarkMode || isDarkBackground
352+ ? "bg-gray-800/95 text-gray-100"
353+ : "bg-white/90 text-gray-800"
354+ ) } >
264355 { description && (
265- < p className = "text-sm" > { description } </ p >
356+ < p className = { cn (
357+ "text-sm" ,
358+ isDarkMode || isDarkBackground ? "text-gray-200" : "text-gray-700"
359+ ) } > { description } </ p >
266360 ) }
267361 { children }
268362 </ div >
269363
270364 { /* Card footer */ }
271365 { footer && (
272- < div className = "absolute bottom-0 left-0 right-0 p-2 text-xs text-center bg-gray-100 border-t border-gray-200" >
366+ < div className = { cn (
367+ "absolute bottom-0 left-0 right-0 p-2 text-xs text-center border-t" ,
368+ isDarkMode || isDarkBackground
369+ ? "bg-gray-900 border-gray-700 text-gray-300"
370+ : "bg-gray-100 border-gray-200 text-gray-600"
371+ ) } >
273372 { footer }
274373 </ div >
275374 ) }
0 commit comments