@@ -0,0 +1,218 @@
"use client" ;
/**
* Custom inline-SVG avatar art — a "pantheon" of gods & legends rendered as
* heraldic medallions (gradient disc + gold ring + a bold mythic emblem).
* Keyed by the same avatar ids used in types.ts AVATARS, so owned avatars keep
* working; the Avatar component renders this when art exists, else falls back to
* the emoji. No external assets.
*/
type Emblem =
| "crown" | "trident" | "bolt" | "sun" | "eye" | "ankh" | "lion" | "eagle"
| "owl" | "helmet" | "phoenix" | "laurel" | "star8" | "flame" | "moon"
| "dragon" | "wings" | "skull" | "gem" | "lyre" ;
interface AvatarArt {
nameFa : string ;
nameEn : string ;
c1 : string ; // disc gradient (top)
c2 : string ; // disc gradient (bottom)
ring : string ; // ring / accent
em : Emblem ;
emColor : string ;
}
/* ----------------------------- emblems ------------------------------- */
// Each emblem is drawn for a 100× 100 viewBox, roughly centred in 28..72,
// using currentColor so the wrapper sets the tint.
const EMBLEMS : Record < Emblem , React.ReactNode > = {
crown : (
< path d = "M26 64 L26 40 L38 50 L50 32 L62 50 L74 40 L74 64 Z M24 66 h52 v6 h-52 z" / >
) ,
trident : (
< >
< rect x = "47" y = "34" width = "6" height = "40" rx = "2" / >
< path d = "M30 40 q0 -14 10 -16 q-4 6 -2 14 M70 40 q0 -14 -10 -16 q4 6 2 14" / >
< path d = "M30 30 v12 M50 26 v12 M70 30 v12" stroke = "currentColor" strokeWidth = "5" fill = "none" strokeLinecap = "round" / >
< path d = "M30 42 h40" stroke = "currentColor" strokeWidth = "5" / >
< / >
) ,
bolt : < path d = "M54 24 L34 56 H48 L44 78 L68 44 H52 Z" / > ,
sun : (
< >
< circle cx = "50" cy = "50" r = "16" / >
< g stroke = "currentColor" strokeWidth = "4" strokeLinecap = "round" >
< path d = "M50 22 v8 M50 70 v8 M22 50 h8 M70 50 h8 M31 31 l6 6 M63 63 l6 6 M69 31 l-6 6 M37 63 l-6 6" / >
< / g >
< / >
) ,
eye : (
< >
< path d = "M26 50 Q50 32 74 50 Q50 68 26 50 Z" fill = "none" stroke = "currentColor" strokeWidth = "5" / >
< circle cx = "50" cy = "50" r = "8" / >
< path d = "M50 60 q-2 10 -12 12 M58 58 l10 12" stroke = "currentColor" strokeWidth = "4" fill = "none" strokeLinecap = "round" / >
< / >
) ,
ankh : (
< >
< ellipse cx = "50" cy = "38" rx = "11" ry = "13" fill = "none" stroke = "currentColor" strokeWidth = "6" / >
< rect x = "46" y = "50" width = "8" height = "28" rx = "2" / >
< rect x = "34" y = "56" width = "32" height = "7" rx = "2" / >
< / >
) ,
lion : (
< >
< g stroke = "currentColor" strokeWidth = "3" >
< path d = "M50 26 l8 8 10 -4 -3 11 9 7 -9 5 3 11 -10 -3 -8 8 -8 -8 -10 3 3 -11 -9 -5 9 -7 -3 -11 10 4 z" / >
< / g >
< circle cx = "50" cy = "52" r = "15" fill = "currentColor" / >
< circle cx = "44" cy = "50" r = "2.4" fill = "#1a1206" / >
< circle cx = "56" cy = "50" r = "2.4" fill = "#1a1206" / >
< path d = "M46 58 q4 4 8 0" stroke = "#1a1206" strokeWidth = "2.4" fill = "none" strokeLinecap = "round" / >
< / >
) ,
eagle : (
< >
< path d = "M50 32 q-22 2 -30 16 q16 -6 24 0 q-4 8 -2 18 l8 6 8 -6 q2 -10 -2 -18 q8 -6 24 0 q-8 -14 -30 -16 z" / >
< path d = "M50 56 l-4 14 h8 z" / >
< / >
) ,
owl : (
< >
< circle cx = "40" cy = "46" r = "12" fill = "none" stroke = "currentColor" strokeWidth = "5" / >
< circle cx = "60" cy = "46" r = "12" fill = "none" stroke = "currentColor" strokeWidth = "5" / >
< circle cx = "40" cy = "46" r = "4" / > < circle cx = "60" cy = "46" r = "4" / >
< path d = "M50 52 l-5 8 h10 z" / >
< path d = "M30 34 l6 8 M70 34 l-6 8" stroke = "currentColor" strokeWidth = "4" strokeLinecap = "round" / >
< / >
) ,
helmet : (
< >
< path d = "M30 46 a20 20 0 0 1 40 0 v18 h-12 v-10 h-4 v10 h-8 v-10 h-4 v10 h-12 z" / >
< rect x = "48" y = "22" width = "4" height = "14" / >
< path d = "M50 22 q10 -2 14 6 q-8 -2 -14 0 z" / >
< / >
) ,
phoenix : (
< >
< path d = "M50 28 q-6 10 -2 18 q-14 -8 -24 -2 q12 2 16 10 q-10 0 -16 8 q14 -4 22 2 q-2 8 4 14 q6 -6 4 -14 q8 -6 22 -2 q-6 -8 -16 -8 q4 -8 16 -10 q-10 -6 -24 2 q4 -8 -2 -18 z" / >
< / >
) ,
laurel : (
< >
< path d = "M34 70 Q22 50 34 30 M66 70 Q78 50 66 30" fill = "none" stroke = "currentColor" strokeWidth = "5" strokeLinecap = "round" / >
< g fill = "currentColor" >
< ellipse cx = "29" cy = "40" rx = "4" ry = "2.6" transform = "rotate(-40 29 40)" / >
< ellipse cx = "30" cy = "52" rx = "4" ry = "2.6" transform = "rotate(-20 30 52)" / >
< ellipse cx = "71" cy = "40" rx = "4" ry = "2.6" transform = "rotate(40 71 40)" / >
< ellipse cx = "70" cy = "52" rx = "4" ry = "2.6" transform = "rotate(20 70 52)" / >
< / g >
< path d = "M44 38 l5 5 11 -13" fill = "none" stroke = "currentColor" strokeWidth = "5" strokeLinecap = "round" strokeLinejoin = "round" / >
< / >
) ,
star8 : (
< path d = "M50 24 l6 16 16 -6 -10 14 14 8 -16 4 4 16 -14 -10 -10 14 -2 -16 -16 4 12 -12 -12 -12 16 4 2 -16 10 14 10 -14 -4 16 16 -4 -14 12 z" / >
) ,
flame : < path d = "M50 24 q10 14 6 24 q-2 6 -8 8 q4 -8 -2 -14 q-2 8 -8 10 q-8 4 -8 14 q0 14 22 14 q22 0 22 -16 q0 -12 -10 -22 q2 8 -4 10 q4 -12 -2 -22 z" / > ,
moon : (
< >
< path d = "M58 26 a24 24 0 1 0 0 48 a18 18 0 0 1 0 -48 z" / >
< path d = "M70 34 l2 5 5 2 -5 2 -2 5 -2 -5 -5 -2 5 -2 z" / >
< / >
) ,
dragon : (
< >
< path d = "M30 60 q-6 -18 10 -24 q-2 -8 6 -10 q-2 6 2 8 q10 -2 16 6 q8 0 10 8 q-6 -2 -10 2 q4 6 0 12 q-6 -6 -12 -4 q-8 6 -18 2 q-2 6 -8 6 q2 -6 -2 -8 z" / >
< circle cx = "44" cy = "44" r = "2.4" fill = "#1a1206" / >
< / >
) ,
wings : (
< >
< circle cx = "50" cy = "48" r = "9" / >
< path d = "M41 48 q-18 -10 -26 -2 q12 0 14 6 q-12 -2 -16 6 q14 -4 20 0 M59 48 q18 -10 26 -2 q-12 0 -14 6 q12 -2 16 6 q-14 -4 -20 0" fill = "none" stroke = "currentColor" strokeWidth = "4" strokeLinecap = "round" / >
< / >
) ,
skull : (
< >
< path d = "M32 46 a18 18 0 0 1 36 0 v8 q0 6 -6 8 v6 h-24 v-6 q-6 -2 -6 -8 z" / >
< circle cx = "42" cy = "48" r = "4.5" fill = "#160a0a" / >
< circle cx = "58" cy = "48" r = "4.5" fill = "#160a0a" / >
< path d = "M50 54 l-3 7 h6 z" fill = "#160a0a" / >
< / >
) ,
gem : (
< >
< path d = "M50 26 L70 42 L50 76 L30 42 Z" / >
< path d = "M30 42 H70 M50 26 L42 42 L50 76 M50 26 L58 42 L50 76" fill = "none" stroke = "#0b1020" strokeWidth = "2" opacity = "0.5" / >
< / >
) ,
lyre : (
< >
< path d = "M36 30 q-8 6 -6 26 M64 30 q8 6 6 26" fill = "none" stroke = "currentColor" strokeWidth = "5" strokeLinecap = "round" / >
< path d = "M36 30 q14 -6 28 0" fill = "none" stroke = "currentColor" strokeWidth = "5" strokeLinecap = "round" / >
< g stroke = "currentColor" strokeWidth = "2.4" > < path d = "M44 36 v30 M50 35 v32 M56 36 v30" / > < / g >
< path d = "M32 64 h36 l-6 8 h-24 z" / >
< / >
) ,
} ;
/* --------------- pantheon: id → god/legend + palette ----------------- */
const PANTHEON : [ string , AvatarArt ] [ ] = [
[ "a-fox" , { nameFa : "آتنا" , nameEn : "Athena" , c1 : "#1f7a6e" , c2 : "#0c2e2a" , ring : "#f4d27a" , em : "owl" , emColor : "#f6e7b6" } ] ,
[ "a-lion" , { nameFa : "شیردل" , nameEn : "Leonidas" , c1 : "#b5701c" , c2 : "#3a2207" , ring : "#ffd98a" , em : "lion" , emColor : "#ffe9b0" } ] ,
[ "a-owl" , { nameFa : "هرمس" , nameEn : "Hermes" , c1 : "#2f6fb0" , c2 : "#0e2240" , ring : "#cfe2ff" , em : "wings" , emColor : "#eaf3ff" } ] ,
[ "a-cat" , { nameFa : "باستت" , nameEn : "Bastet" , c1 : "#1d8f86" , c2 : "#0a2b29" , ring : "#ffd98a" , em : "ankh" , emColor : "#ffe9b0" } ] ,
[ "a-tiger" , { nameFa : "آرش" , nameEn : "Arash" , c1 : "#a8431f" , c2 : "#34110a" , ring : "#ffb27a" , em : "eagle" , emColor : "#ffe0c2" } ] ,
[ "a-panda" , { nameFa : "تور" , nameEn : "Thor" , c1 : "#566b86" , c2 : "#161f2e" , ring : "#bcd0ff" , em : "bolt" , emColor : "#eef4ff" } ] ,
[ "a-bear" , { nameFa : "اودین" , nameEn : "Odin" , c1 : "#475569" , c2 : "#13151b" , ring : "#cbd5e1" , em : "helmet" , emColor : "#eef2f7" } ] ,
[ "a-eagle" , { nameFa : "هوروس" , nameEn : "Horus" , c1 : "#2f7d7a" , c2 : "#0b2a2c" , ring : "#ffd98a" , em : "eagle" , emColor : "#ffe9b0" } ] ,
[ "a-wolf" , { nameFa : "فِنریر" , nameEn : "Fenrir" , c1 : "#3b4a63" , c2 : "#11151f" , ring : "#9fb4d6" , em : "lion" , emColor : "#cfd9ec" } ] ,
[ "a-shark" , { nameFa : "پوزایدون" , nameEn : "Poseidon" , c1 : "#1565a8" , c2 : "#08203a" , ring : "#7fd4ff" , em : "trident" , emColor : "#e6f6ff" } ] ,
[ "a-dragon" , { nameFa : "اژدها" , nameEn : "Drakon" , c1 : "#157a3e" , c2 : "#082416" , ring : "#9af0b0" , em : "dragon" , emColor : "#dcffe6" } ] ,
[ "a-unicorn" , { nameFa : "سیمرغ" , nameEn : "Simorgh" , c1 : "#b23a6a" , c2 : "#34101f" , ring : "#ffc6dd" , em : "phoenix" , emColor : "#ffe3ee" } ] ,
[ "a-peacock" , { nameFa : "هرا" , nameEn : "Hera" , c1 : "#136f86" , c2 : "#07232b" , ring : "#7fe0d6" , em : "eye" , emColor : "#e6fffb" } ] ,
[ "a-swan" , { nameFa : "آفرودیت" , nameEn : "Aphrodite" , c1 : "#9c5bd6" , c2 : "#2a1340" , ring : "#e9c8ff" , em : "wings" , emColor : "#f6ecff" } ] ,
[ "a-tophat" , { nameFa : "مرلین" , nameEn : "Merlin" , c1 : "#3b3170" , c2 : "#140e2c" , ring : "#c9b6ff" , em : "moon" , emColor : "#ece2ff" } ] ,
[ "a-diamond" , { nameFa : "ایشتار" , nameEn : "Ishtar" , c1 : "#1f6fae" , c2 : "#0a1f3a" , ring : "#bfe6ff" , em : "star8" , emColor : "#eaf6ff" } ] ,
[ "a-moneybag" , { nameFa : "پلوتوس" , nameEn : "Plutus" , c1 : "#b58a16" , c2 : "#3a2a06" , ring : "#ffe28a" , em : "gem" , emColor : "#fff2c2" } ] ,
[ "a-trophy" , { nameFa : "نیکه" , nameEn : "Nike" , c1 : "#b5901c" , c2 : "#3a2c07" , ring : "#ffe9a0" , em : "laurel" , emColor : "#fff4c8" } ] ,
[ "a-robot" , { nameFa : "تالوس" , nameEn : "Talos" , c1 : "#4a7c8c" , c2 : "#11242a" , ring : "#a8e0ee" , em : "gem" , emColor : "#e6fbff" } ] ,
[ "a-wizard" , { nameFa : "زئوس" , nameEn : "Zeus" , c1 : "#9a7b2a" , c2 : "#2e2208" , ring : "#ffe79a" , em : "bolt" , emColor : "#fff6cf" } ] ,
[ "a-ninja" , { nameFa : "شینوبی" , nameEn : "Shinobi" , c1 : "#2b3340" , c2 : "#0c0f14" , ring : "#8f9bb0" , em : "skull" , emColor : "#dfe5ee" } ] ,
[ "a-king" , { nameFa : "کوروش" , nameEn : "Cyrus" , c1 : "#9a6b1f" , c2 : "#2f2008" , ring : "#ffd98a" , em : "wings" , emColor : "#ffefc2" } ] ,
[ "a-genie" , { nameFa : "دیو" , nameEn : "Djinn" , c1 : "#7a2ea8" , c2 : "#260a3a" , ring : "#d6a8ff" , em : "flame" , emColor : "#f1ddff" } ] ,
[ "a-crown" , { nameFa : "شاهنشاه" , nameEn : "Shahanshah" , c1 : "#b58a16" , c2 : "#3a2a06" , ring : "#ffe28a" , em : "crown" , emColor : "#fff4c8" } ] ,
[ "a-gem" , { nameFa : "اهورا" , nameEn : "Ahura" , c1 : "#1f8fae" , c2 : "#082a3a" , ring : "#9fe8ff" , em : "sun" , emColor : "#eafbff" } ] ,
] ;
export const AVATAR_ART : Record < string , AvatarArt > = Object . fromEntries ( PANTHEON ) ;
export function hasAvatarArt ( id : string ) : boolean {
return ! ! AVATAR_ART [ id ] ;
}
export function avatarArtName ( id : string , locale : "fa" | "en" ) : string | null {
const a = AVATAR_ART [ id ] ;
return a ? ( locale === "fa" ? a.nameFa : a.nameEn ) : null ;
}
/** Render a god/legend medallion for the given avatar id (returns null if none). */
export function AvatarArtSvg ( { id , size } : { id : string ; size : number } ) {
const a = AVATAR_ART [ id ] ;
if ( ! a ) return null ;
const gid = ` avg- ${ id } ` ;
return (
< svg width = { size } height = { size } viewBox = "0 0 100 100" aria - hidden >
< defs >
< radialGradient id = { gid } cx = "42%" cy = "34%" r = "80%" >
< stop offset = "0" stopColor = { a . c1 } / >
< stop offset = "1" stopColor = { a . c2 } / >
< / radialGradient >
< / defs >
< circle cx = "50" cy = "50" r = "48" fill = { ` url(# ${ gid } ) ` } / >
< circle cx = "50" cy = "50" r = "46.5" fill = "none" stroke = { a . ring } strokeWidth = "2.5" opacity = "0.85" / >
< g style = { { color : a.emColor } } fill = "currentColor" stroke = "none" >
{ EMBLEMS [ a . em ] }
< / g >
< / svg >
) ;
}