Added Magical Rarity Effects with Glowing Shadows & Particles

�� Rarity-Based Visual Effects:
- Mythic/Legendary: Golden glow with 3-layer pulsing animation
- Rare/Holo: Purple glow with shimmering particles
- Uncommon: Blue glow with subtle twinkling
- Enchanted/Secret: Rainbow cycling glow with rotating particles

💫 Dynamic Particle Systems:
- Radial gradient overlays for sparkle effects
- Animated opacity and rotation for enchanted cards
- Multiple particle layers for depth and richness
- Smooth pulsing animations with different timings

🎨 Enhanced Visual Hierarchy:
- Rarity-specific border colors and shadows
- Hover intensification of glow effects
- Side panel inherits rarity styling
- Pulsing rarity indicator dots in panel headers

 Performance Optimized:
- CSS-only animations using hardware acceleration
- Efficient keyframe animations
- Proper z-index layering
- Responsive particle effects

🎯 Smart Rarity Detection:
- Flexible string matching for various rarity names
- Supports MTG, Pokemon, Lorcana rarity systems
- Fallback to standard styling for common cards
- Case-insensitive rarity recognition

Cards now have that premium, magical feel! 🃏
This commit is contained in:
Randall Stillwell 2025-07-26 00:01:04 -05:00
parent 1387ecaccb
commit d537474a61
2 changed files with 271 additions and 3 deletions

View file

@ -21,6 +21,50 @@ export default function CardItem({
setImageError(true);
};
// Get rarity-based styling
const getRarityEffects = (rarity) => {
const rarityLower = rarity?.toLowerCase() || '';
if (rarityLower.includes('mythic') || rarityLower.includes('legendary')) {
return {
glow: 'rarity-glow-mythic',
particles: 'rarity-particles-mythic',
border: 'border-yellow-400',
shadow: 'shadow-yellow-400/50'
};
} else if (rarityLower.includes('rare') || rarityLower.includes('holo')) {
return {
glow: 'rarity-glow-rare',
particles: 'rarity-particles-rare',
border: 'border-purple-400',
shadow: 'shadow-purple-400/50'
};
} else if (rarityLower.includes('uncommon')) {
return {
glow: 'rarity-glow-uncommon',
particles: 'rarity-particles-uncommon',
border: 'border-blue-400',
shadow: 'shadow-blue-400/30'
};
} else if (rarityLower.includes('enchanted') || rarityLower.includes('secret')) {
return {
glow: 'rarity-glow-enchanted',
particles: 'rarity-particles-enchanted',
border: 'border-pink-400',
shadow: 'shadow-pink-400/60'
};
}
return {
glow: '',
particles: '',
border: 'border-gray-200',
shadow: ''
};
};
const rarityEffects = getRarityEffects(card.rarity);
if (viewMode === 'list') {
return (
<div className={`flex items-center p-4 border rounded-lg transition-all duration-200 ${
@ -134,8 +178,13 @@ export default function CardItem({
<div className={`relative bg-white rounded-xl border transition-all duration-300 overflow-hidden ${
isSelected
? 'border-purple-500 shadow-xl ring-2 ring-purple-200'
: 'border-gray-200 group-hover:border-gray-300 group-hover:shadow-lg'
}`}>
: `${rarityEffects.border} group-hover:border-gray-300 group-hover:shadow-lg ${rarityEffects.shadow ? `shadow-lg ${rarityEffects.shadow}` : ''}`
} ${rarityEffects.glow}`}>
{/* Rarity Particles */}
{rarityEffects.particles && (
<div className={`absolute inset-0 pointer-events-none ${rarityEffects.particles}`}></div>
)}
{/* Selection Checkbox */}
<div className="absolute top-3 left-3 z-20">
<input
@ -193,7 +242,11 @@ export default function CardItem({
? 'opacity-100 translate-x-0 pointer-events-auto'
: 'opacity-0 translate-x-2 pointer-events-none group-hover:opacity-100 group-hover:translate-x-0 group-hover:pointer-events-auto delay-300 group-hover:delay-500'
}`}>
<div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-2xl h-full overflow-hidden">
<div className={`bg-white dark:bg-gray-800 rounded-xl border shadow-2xl h-full overflow-hidden ${
rarityEffects.border !== 'border-gray-200'
? `${rarityEffects.border} dark:${rarityEffects.border.replace('border-', 'border-')} ${rarityEffects.glow}`
: 'border-gray-200 dark:border-gray-700'
}`}>
{/* Panel Header */}
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-start justify-between mb-2">
@ -262,6 +315,21 @@ export default function CardItem({
{card.game}
</span>
<span className="text-sm text-gray-600 dark:text-gray-400">{card.set_name}</span>
{rarityEffects.glow && (
<div className="flex items-center space-x-1">
<div className={`w-2 h-2 rounded-full ${
card.rarity?.toLowerCase().includes('mythic') || card.rarity?.toLowerCase().includes('legendary')
? 'bg-yellow-400 shadow-sm shadow-yellow-400/50'
: card.rarity?.toLowerCase().includes('rare') || card.rarity?.toLowerCase().includes('holo')
? 'bg-purple-400 shadow-sm shadow-purple-400/50'
: card.rarity?.toLowerCase().includes('uncommon')
? 'bg-blue-400 shadow-sm shadow-blue-400/50'
: card.rarity?.toLowerCase().includes('enchanted') || card.rarity?.toLowerCase().includes('secret')
? 'bg-pink-400 shadow-sm shadow-pink-400/50'
: 'bg-gray-400'
} animate-pulse`}></div>
</div>
)}
</div>
</div>

View file

@ -396,3 +396,203 @@ body {
transform: translateX(0);
transition: all 300ms ease-out;
}
/* Rarity Effects */
/* Mythic/Legendary - Golden glow */
.rarity-glow-mythic {
box-shadow:
0 0 20px rgba(251, 191, 36, 0.4),
0 0 40px rgba(251, 191, 36, 0.3),
0 0 60px rgba(251, 191, 36, 0.2);
animation: mythic-pulse 3s ease-in-out infinite;
}
@keyframes mythic-pulse {
0%, 100% {
box-shadow:
0 0 20px rgba(251, 191, 36, 0.4),
0 0 40px rgba(251, 191, 36, 0.3),
0 0 60px rgba(251, 191, 36, 0.2);
}
50% {
box-shadow:
0 0 30px rgba(251, 191, 36, 0.6),
0 0 60px rgba(251, 191, 36, 0.4),
0 0 90px rgba(251, 191, 36, 0.3);
}
}
.rarity-particles-mythic::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at 20% 30%, rgba(251, 191, 36, 0.3) 0%, transparent 50%),
radial-gradient(circle at 80% 70%, rgba(251, 191, 36, 0.2) 0%, transparent 50%),
radial-gradient(circle at 60% 20%, rgba(251, 191, 36, 0.25) 0%, transparent 50%);
animation: mythic-sparkle 4s ease-in-out infinite;
border-radius: inherit;
}
@keyframes mythic-sparkle {
0%, 100% { opacity: 0.3; }
50% { opacity: 0.7; }
}
/* Rare - Purple glow */
.rarity-glow-rare {
box-shadow:
0 0 15px rgba(168, 85, 247, 0.4),
0 0 30px rgba(168, 85, 247, 0.3),
0 0 45px rgba(168, 85, 247, 0.2);
animation: rare-pulse 2.5s ease-in-out infinite;
}
@keyframes rare-pulse {
0%, 100% {
box-shadow:
0 0 15px rgba(168, 85, 247, 0.4),
0 0 30px rgba(168, 85, 247, 0.3),
0 0 45px rgba(168, 85, 247, 0.2);
}
50% {
box-shadow:
0 0 25px rgba(168, 85, 247, 0.5),
0 0 50px rgba(168, 85, 247, 0.4),
0 0 75px rgba(168, 85, 247, 0.3);
}
}
.rarity-particles-rare::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at 30% 40%, rgba(168, 85, 247, 0.2) 0%, transparent 40%),
radial-gradient(circle at 70% 60%, rgba(168, 85, 247, 0.15) 0%, transparent 40%);
animation: rare-shimmer 3s ease-in-out infinite;
border-radius: inherit;
}
@keyframes rare-shimmer {
0%, 100% { opacity: 0.2; }
50% { opacity: 0.5; }
}
/* Uncommon - Blue glow */
.rarity-glow-uncommon {
box-shadow:
0 0 10px rgba(96, 165, 250, 0.3),
0 0 20px rgba(96, 165, 250, 0.2);
animation: uncommon-pulse 2s ease-in-out infinite;
}
@keyframes uncommon-pulse {
0%, 100% {
box-shadow:
0 0 10px rgba(96, 165, 250, 0.3),
0 0 20px rgba(96, 165, 250, 0.2);
}
50% {
box-shadow:
0 0 15px rgba(96, 165, 250, 0.4),
0 0 30px rgba(96, 165, 250, 0.3);
}
}
.rarity-particles-uncommon::before {
content: '';
position: absolute;
inset: 0;
background: radial-gradient(circle at 40% 30%, rgba(96, 165, 250, 0.15) 0%, transparent 30%);
animation: uncommon-twinkle 2.5s ease-in-out infinite;
border-radius: inherit;
}
@keyframes uncommon-twinkle {
0%, 100% { opacity: 0.1; }
50% { opacity: 0.3; }
}
/* Enchanted/Secret - Pink/Rainbow glow */
.rarity-glow-enchanted {
box-shadow:
0 0 25px rgba(244, 114, 182, 0.5),
0 0 50px rgba(244, 114, 182, 0.4),
0 0 75px rgba(244, 114, 182, 0.3);
animation: enchanted-pulse 2s ease-in-out infinite;
}
@keyframes enchanted-pulse {
0%, 100% {
box-shadow:
0 0 25px rgba(244, 114, 182, 0.5),
0 0 50px rgba(244, 114, 182, 0.4),
0 0 75px rgba(244, 114, 182, 0.3);
}
33% {
box-shadow:
0 0 30px rgba(168, 85, 247, 0.5),
0 0 60px rgba(168, 85, 247, 0.4),
0 0 90px rgba(168, 85, 247, 0.3);
}
66% {
box-shadow:
0 0 30px rgba(59, 130, 246, 0.5),
0 0 60px rgba(59, 130, 246, 0.4),
0 0 90px rgba(59, 130, 246, 0.3);
}
}
.rarity-particles-enchanted::before {
content: '';
position: absolute;
inset: 0;
background:
radial-gradient(circle at 25% 25%, rgba(244, 114, 182, 0.3) 0%, transparent 40%),
radial-gradient(circle at 75% 75%, rgba(168, 85, 247, 0.2) 0%, transparent 40%),
radial-gradient(circle at 50% 50%, rgba(59, 130, 246, 0.25) 0%, transparent 40%);
animation: enchanted-rainbow 3s ease-in-out infinite;
border-radius: inherit;
}
@keyframes enchanted-rainbow {
0%, 100% {
opacity: 0.4;
transform: rotate(0deg);
}
33% {
opacity: 0.6;
transform: rotate(120deg);
}
66% {
opacity: 0.5;
transform: rotate(240deg);
}
}
/* Hover enhancement for rarity effects */
.card-item-container:hover .rarity-glow-mythic {
box-shadow:
0 0 30px rgba(251, 191, 36, 0.6),
0 0 60px rgba(251, 191, 36, 0.5),
0 0 90px rgba(251, 191, 36, 0.4);
}
.card-item-container:hover .rarity-glow-rare {
box-shadow:
0 0 25px rgba(168, 85, 247, 0.6),
0 0 50px rgba(168, 85, 247, 0.5),
0 0 75px rgba(168, 85, 247, 0.4);
}
.card-item-container:hover .rarity-glow-uncommon {
box-shadow:
0 0 20px rgba(96, 165, 250, 0.5),
0 0 40px rgba(96, 165, 250, 0.4);
}
.card-item-container:hover .rarity-glow-enchanted {
box-shadow:
0 0 35px rgba(244, 114, 182, 0.7),
0 0 70px rgba(244, 114, 182, 0.6),
0 0 105px rgba(244, 114, 182, 0.5);
}