design: update logo to crossed wrench and brush

Logo Redesign:
- Simple, beautiful crossed design (wrench × brush in X formation)
- Wrench: Bottom-left to top-right with purple gradient
- Brush: Top-left to bottom-right with orange-red gradient
- Center circle at intersection with purple-to-cyan gradient
- Clean, minimal aesthetic with smooth animations

Favicon Update:
- Matching crossed design scaled for 64x64
- Clear visibility at small sizes
- Professional and memorable icon

Visual Elements:
- Wrench: Indigo (#667eea) to Purple (#a855f7) gradient
- Brush handle: Amber (#f59e0b) to Red (#ef4444) gradient
- Brush ferrule: Gray metal finish
- Brush bristles: Green (#10b981) to Cyan (#06b6d4) gradient
- Center: Purple to Cyan radial gradient

Animations:
- Initial rotation animation on logo
- Progressive drawing of wrench and brush
- Bristles expand effect
- Center circle pops in with spring animation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-09 15:49:32 +01:00
parent 41c77dce9d
commit 2d421c9cac
2 changed files with 114 additions and 82 deletions

View File

@@ -11,93 +11,107 @@ export default function Logo({ className = '', size = 120 }: { className?: strin
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
initial={{ opacity: 0, rotate: -45 }}
animate={{ opacity: 1, rotate: 0 }}
transition={{ duration: 0.8, ease: 'easeOut' }}
>
{/* Suitcase body */}
<motion.rect
x="50"
y="85"
width="100"
height="70"
rx="6"
stroke="url(#gradient1)"
strokeWidth="5"
fill="rgba(139, 92, 246, 0.15)"
{/* Wrench (bottom-left to top-right) */}
<motion.g
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 1.2, ease: 'easeInOut' }}
/>
>
{/* Wrench handle */}
<motion.line
x1="60"
y1="140"
x2="115"
y2="85"
stroke="url(#wrenchGradient)"
strokeWidth="8"
strokeLinecap="round"
/>
{/* Wrench head (open end) */}
<motion.path
d="M 115 85 L 125 75 M 115 85 L 125 95"
stroke="url(#wrenchGradient)"
strokeWidth="8"
strokeLinecap="round"
/>
</motion.g>
{/* Suitcase handle */}
<motion.path
d="M 85 85 Q 100 60, 115 85"
stroke="url(#gradient1)"
strokeWidth="5"
fill="none"
strokeLinecap="round"
{/* Brush (top-left to bottom-right) */}
<motion.g
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ duration: 1, delay: 0.2, ease: 'easeInOut' }}
/>
{/* Suitcase latch */}
<motion.rect
x="95"
y="82"
width="10"
height="8"
rx="2"
fill="url(#gradient1)"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5, delay: 0.8 }}
/>
{/* Brush handle */}
<motion.g
initial={{ opacity: 0, y: -15 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 1, ease: 'easeOut' }}
transition={{ duration: 1.2, delay: 0.3, ease: 'easeInOut' }}
>
<rect
x="97"
y="100"
width="6"
height="35"
fill="url(#brushHandle)"
rx="3"
{/* Brush handle */}
<motion.line
x1="75"
y1="60"
x2="115"
y2="100"
stroke="url(#brushHandleGradient)"
strokeWidth="6"
strokeLinecap="round"
/>
{/* Brush ferrule (metal part) */}
<motion.ellipse
cx="120"
cy="105"
rx="6"
ry="10"
fill="url(#ferruleGradient)"
transform="rotate(45 120 105)"
/>
{/* Brush bristles */}
<motion.g
initial={{ scaleY: 0.5, opacity: 0 }}
animate={{ scaleY: 1, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.8, ease: 'easeOut' }}
>
<motion.line x1="123" y1="108" x2="135" y2="120" stroke="url(#bristlesGradient)" strokeWidth="2.5" strokeLinecap="round" />
<motion.line x1="126" y1="111" x2="140" y2="125" stroke="url(#bristlesGradient)" strokeWidth="2.5" strokeLinecap="round" />
<motion.line x1="129" y1="114" x2="143" y2="128" stroke="url(#bristlesGradient)" strokeWidth="2.5" strokeLinecap="round" />
<motion.line x1="120" y1="111" x2="130" y2="121" stroke="url(#bristlesGradient)" strokeWidth="2.5" strokeLinecap="round" />
<motion.line x1="117" y1="114" x2="125" y2="122" stroke="url(#bristlesGradient)" strokeWidth="2.5" strokeLinecap="round" />
</motion.g>
</motion.g>
{/* Brush bristles */}
<motion.g
initial={{ opacity: 0, scaleY: 0.5 }}
animate={{ opacity: 1, scaleY: 1 }}
transition={{ duration: 0.6, delay: 1.3, ease: 'easeOut' }}
style={{ transformOrigin: '100px 135px' }}
>
<path
d="M 88 135 L 90 145 L 92 143 L 94 146 L 96 144 L 98 147 L 100 145 L 102 147 L 104 144 L 106 146 L 108 143 L 110 145 L 112 135 Z"
fill="url(#brushBristles)"
/>
</motion.g>
{/* Center circle (intersection) */}
<motion.circle
cx="100"
cy="100"
r="12"
fill="url(#centerGradient)"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ duration: 0.5, delay: 1, type: 'spring', stiffness: 200 }}
/>
{/* Gradient definitions */}
<defs>
<linearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#a855f7" />
<stop offset="100%" stopColor="#6366f1" />
<linearGradient id="wrenchGradient" x1="60" y1="140" x2="125" y2="75">
<stop offset="0%" stopColor="#667eea" />
<stop offset="100%" stopColor="#a855f7" />
</linearGradient>
<linearGradient id="brushHandle" x1="0%" y1="0%" x2="0%" y2="100%">
<linearGradient id="brushHandleGradient" x1="75" y1="60" x2="115" y2="100">
<stop offset="0%" stopColor="#f59e0b" />
<stop offset="100%" stopColor="#ef4444" />
</linearGradient>
<linearGradient id="brushBristles" x1="0%" y1="0%" x2="0%" y2="100%">
<linearGradient id="ferruleGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#94a3b8" />
<stop offset="100%" stopColor="#64748b" />
</linearGradient>
<linearGradient id="bristlesGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#10b981" />
<stop offset="100%" stopColor="#06b6d4" />
</linearGradient>
<linearGradient id="centerGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#a855f7" />
<stop offset="100%" stopColor="#06b6d4" />
</linearGradient>
</defs>
</motion.svg>
);