@dotcraft/avatar 0.7.8 → 0.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react'
1
+ import { useId, type CSSProperties, type ReactNode } from 'react'
2
2
  import type { BackId } from './items.js'
3
3
  import { Detail, Glow, Silhouette as S, useClipId } from './DecorationShapes.js'
4
4
  import { CloudDragon, CloudDragonFront } from './CloudDragon.js'
@@ -32,6 +32,17 @@ const dragonWing = {
32
32
  outer: 'M272 500C160 380 60 300 20 340c0 60 60 100 100 130-60 30-100 90-80 150 60 10 130-20 190-70-40 60-40 120 0 150 60-20 100-90 110-160Z',
33
33
  inner: 'M262 530C170 430 90 370 60 396c4 44 50 76 84 100-50 24-84 74-70 122 50 4 110-24 160-66-30 48-30 96 0 122 44-18 78-76 86-134Z',
34
34
  }
35
+ const dragonEmbers = [
36
+ [24, 346, -20, -200, 18], [110, 410, 30, -230, 13], [190, 440, -10, -180, 15],
37
+ [46, 612, -40, -170, 16], [120, 560, 20, -210, 12], [232, 690, -30, -190, 14],
38
+ ]
39
+ function DragonEmbers() {
40
+ return <g className="dca-fx" transform="rotate(-6 272 560)">
41
+ {dragonEmbers.map(([x, y, dx, dy, r], i) => <g key={i} className="dca-fx-wing-ember" style={{ '--dca-dx': `${dx}px`, '--dca-dy': `${dy}px`, animationDelay: `${(i % 3) * .14}s` } as CSSProperties}>
42
+ <circle cx={x} cy={y} r={r + 9} fill="#fff" /><circle cx={x} cy={y} r={r} fill="#ff7a2a" /><circle cx={x} cy={y} r={r * .5} fill="#ffd36b" />
43
+ </g>)}
44
+ </g>
45
+ }
35
46
 
36
47
  function SunRays() {
37
48
  const rays = Array.from({ length: 12 }, (_, index) => {
@@ -61,41 +72,36 @@ function SolarPanel() {
61
72
  }
62
73
 
63
74
  const bladePath = 'M-40-22H720L780 0 720 22H-40Z'
75
+ const bladeGlow = 'M-40-30H724L796 0 724 30H-40Z'
64
76
  function Sword({ blade, glow, guard, children }: { blade: string; glow: string; guard: string; children?: ReactNode }) {
65
77
  const clip = useClipId()
66
78
  return <>
67
79
  <defs><clipPath id={clip}><path d={bladePath} /></clipPath></defs>
68
- <Glow blur={16} className="dca-fx-pulse"><path d="M-40-30H724L796 0 724 30H-40Z" fill={glow} opacity=".85" /></Glow>
69
- <circle cx="-166" r="22" fill={guard} stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
70
- <rect x="-160" y="-16" width="108" height="32" rx="12" fill="#2b2f3a" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
71
- <S d={bladePath} fill={blade} stroke={16} />
72
- {children}
73
- <g clipPath={`url(#${clip})`}><g transform="translate(689 0) scale(.3 1)"><g className="dca-fx dca-fx-sheen" fill="#fff"><path d="M3-30h67l-73 60h-67Z" opacity=".85" /></g></g></g>
74
- <rect x="-64" y="-62" width="24" height="124" rx="10" fill={guard} stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
80
+ <g className="dca-fx-sword-sheathed"><Glow blur={16} className="dca-fx-pulse"><path d={bladeGlow} fill={glow} opacity=".85" /></Glow></g>
81
+ <g className="dca-fx dca-fx-sword-drawn" transform="translate(-100 0)"><Glow blur={16}><path d={bladeGlow} fill={glow} /></Glow></g>
82
+ <g className="dca-fx-sword-draw">
83
+ <circle cx="-166" r="22" fill={guard} stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
84
+ <rect x="-160" y="-16" width="108" height="32" rx="12" fill="#2b2f3a" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
85
+ <S d={bladePath} fill={blade} stroke={16} />
86
+ {children}
87
+ <g clipPath={`url(#${clip})`}><g transform="translate(689 0) scale(.3 1)"><g className="dca-fx dca-fx-sheen" fill="#fff"><path d="M3-30h67l-73 60h-67Z" opacity=".85" /></g></g></g>
88
+ <rect x="-64" y="-62" width="24" height="124" rx="10" fill={guard} stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
89
+ </g>
75
90
  <rect x="-14" y="-36" width="30" height="72" rx="10" fill="#8b95a5" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
76
91
  </>
77
92
  }
93
+ const slashTrail = { outer: 'M-620 0Q0-360 620 0Q0-120-620 0Z', core: 'M-500-18Q0-286 500-18Q0-150-500-18Z' }
94
+ function Slash({ fill, core, delay }: { fill: string; core: string; delay?: string }) {
95
+ return <g transform="translate(512 600) rotate(34)"><g className="dca-fx dca-fx-sword-slash" style={{ transformOrigin: '-620px 0px', animationDelay: delay }}>
96
+ <path d={slashTrail.outer} fill={fill} stroke="#fff" strokeWidth="16" strokeLinejoin="round" paintOrder="stroke fill" />
97
+ <path d={slashTrail.core} fill={core} />
98
+ </g></g>
99
+ }
78
100
  const leftShoulder = 'translate(265 392) rotate(43)'
79
101
 
80
102
  const guitarBody = 'M-86 0C-86-48-48-86 0-86 42-86 66-62 90-54 110-46 124-64 160-64 196-64 224-36 224 0 224 36 196 64 160 64 124 64 110 46 90 54 66 62 42 86 0 86-48 86-86 48-86 0Z'
81
103
 
82
104
  const orbit = { transform: 'translate(512 760) rotate(-12)', rx: 450, ry: 104 }
83
- const orbitBodies: { key: string; delay?: string; art: ReactNode }[] = [
84
- { key: 'a', art: <><ellipse rx="64" ry="18" fill="none" stroke="#fff" strokeWidth="22" transform="rotate(-18)" /><ellipse rx="64" ry="18" fill="none" stroke="#ffe08a" strokeWidth="9" transform="rotate(-18)" /><circle r="44" fill="#fff" /><circle r="34" fill="#f6b500" /><path d="M-64 0a64 18 0 0 0 128 0" fill="none" stroke="#ffe08a" strokeWidth="9" transform="rotate(-18)" /></> },
85
- { key: 'b', delay: '-2.67s', art: <><circle r="34" fill="#fff" /><circle r="25" fill="#c9d2ff" /></> },
86
- { key: 'c', delay: '-5.33s', art: <><circle r="26" fill="#fff" /><circle r="17" fill="#ff9ad9" /></> },
87
- ]
88
- function OrbitBodies({ side }: { side: 'front' | 'back' }) {
89
- return <>{orbitBodies.map(body => <g key={body.key} className={`dca-fx dca-fx-orbit dca-fx-orbit-${side} dca-fx-orbit-${body.key}`} style={body.delay ? { animationDelay: body.delay } : undefined}>{body.art}</g>)}</>
90
- }
91
- function OrbitArc({ side }: { side: 'front' | 'back' }) {
92
- const sweep = side === 'back' ? 1 : 0
93
- const outer = `M${-orbit.rx} 0A${orbit.rx} ${orbit.ry} 0 0 ${sweep} ${orbit.rx} 0`
94
- return <>
95
- <path d={outer} fill="none" stroke="#fff" strokeWidth="46" />
96
- <path d={outer} fill="none" stroke="#b9c4ff" strokeWidth="30" />
97
- </>
98
- }
99
105
 
100
106
  const koiOrbit = `${orbit.transform} scale(.88)`
101
107
  const koi = <>
@@ -104,8 +110,53 @@ const koi = <>
104
110
  <ellipse cx="-10" cy="-22" rx="48" ry="24" transform="rotate(8 -10 -22)" fill="#fff4ef" />
105
111
  </>
106
112
  function KoiBodies({ side }: { side: 'front' | 'back' }) {
107
- const art = side === 'front' ? koi : <g transform="scale(-1 1)">{koi}</g>
108
- return <>{['a', 'c'].map(key => <g key={key} className={`dca-fx-orbit dca-fx-orbit-${side} dca-fx-orbit-${key}`} style={key === 'c' ? { animationDelay: '-4s' } : undefined}>{art}</g>)}</>
113
+ return <>{[['a', '-2.8s'], ['b', '-7.467s']].map(([key, delay]) => <g key={key} className={`dca-fx-orbit-${side} dca-fx-koi-${key}`} style={{ animationDelay: delay }}>
114
+ <g><g transform="scale(-1 1)">{koi}</g></g>
115
+ </g>)}</>
116
+ }
117
+
118
+ const finRack = { x: 330, y: 480 }
119
+ const finCrown = { x: 512, y: 400, rx: 470, ry: 360 }
120
+ const funnels = [{ dock: -140, length: 346, crown: -168 }, { dock: -126, length: 372, crown: -140 }, { dock: -112, length: 392, crown: -112 }]
121
+ const rad = Math.PI / 180
122
+ function finFlight({ dock, length, crown }: typeof funnels[number], index: number) {
123
+ const tx = finCrown.x + finCrown.rx * Math.cos(crown * rad), ty = finCrown.y + finCrown.ry * Math.sin(crown * rad)
124
+ const heading = Math.atan2(ty - finCrown.y, tx - finCrown.x)
125
+ const dx = tx - length * Math.cos(heading) - finRack.x, dy = ty - length * Math.sin(heading) - finRack.y
126
+ const c = Math.cos(dock * rad), s = Math.sin(dock * rad)
127
+ return { '--dca-dx': `${n0(dx * c + dy * s)}px`, '--dca-dy': `${n0(dy * c - dx * s)}px`, '--dca-turn': `${n0(heading / rad - dock)}deg`, '--dca-delay': `${(-index * .08).toFixed(2)}s` } as CSSProperties
128
+ }
129
+ function finPlate(l: number) {
130
+ const top = (x: number) => n0(-28 - 24 * x / l), bottom = (x: number) => n0(28 + 18 * x / (l - 56))
131
+ return {
132
+ outline: `M0-28L${l}-52L${l - 56} 46L0 28Z`,
133
+ bevel: `M0-28L${l - 36} ${top(l - 36)}L${l - 66} 0H0Z`,
134
+ cap: `M${l - 36} ${top(l - 36)}L${l}-52L${l - 56} 46L${l - 92} ${bottom(l - 92)}Z`,
135
+ }
136
+ }
137
+ function FinFunnels() {
138
+ const glow = `dca-glow-${useId().replace(/:/g, '')}`
139
+ const fin = (spec: typeof funnels[number], index: number) => {
140
+ const l = spec.length, plate = finPlate(l)
141
+ return <g key={index} transform={`translate(${finRack.x} ${finRack.y}) rotate(${spec.dock})`}>
142
+ <g className="dca-fx-fin" style={finFlight(spec, index)}>
143
+ <g className="dca-fx-fin-bob" style={{ animationDelay: `${-index * 1.1}s` }}>
144
+ <g transform={`translate(${l - 26} -3)`}>
145
+ <g className="dca-fx dca-fx-fin-beam"><path d="M0-13H112a13 13 0 0 1 0 26H0a13 13 0 0 1 0-26Z" fill="#4de3ff" stroke="#fff" strokeWidth="12" strokeLinejoin="round" paintOrder="stroke fill" /><path d="M6 0H112" stroke="#fff" strokeWidth="8" strokeLinecap="round" /></g>
146
+ </g>
147
+ <S d={plate.outline} fill="#c9d2ff" />
148
+ <path d={plate.bevel} fill="#8b95a5" />
149
+ <path d={plate.cap} fill="#4de3ff" />
150
+ <circle className="dca-fx dca-fx-pulse" cx={l - 40} cy="-3" r="54" fill={`url(#${glow})`} />
151
+ <circle className="dca-fx dca-fx-fin-flash" cx={l - 26} cy="-3" r="84" fill={`url(#${glow})`} />
152
+ </g>
153
+ </g>
154
+ </g>
155
+ }
156
+ return <>
157
+ <defs><radialGradient id={glow}><stop offset="0" stopColor="#4de3ff" stopOpacity=".85" /><stop offset=".5" stopColor="#4de3ff" stopOpacity=".35" /><stop offset="1" stopColor="#4de3ff" stopOpacity="0" /></radialGradient></defs>
158
+ {mirrored(<>{funnels.map(fin)}</>)}
159
+ </>
109
160
  }
110
161
 
111
162
  // The tail spirals inward so its tip ends behind the antenna light or the hat crown.
@@ -121,6 +172,10 @@ function cometTail(width: number) {
121
172
  }
122
173
 
123
174
  const halo = { cx: 512, cy: 229, r: 168 }
175
+ function haloArc(from: number, to: number) {
176
+ const at = (deg: number) => `${n0(halo.cx + halo.r * Math.cos(deg * Math.PI / 180))} ${n0(halo.cy + halo.r * Math.sin(deg * Math.PI / 180))}`
177
+ return `M${at(from)}A${halo.r} ${halo.r} 0 0 1 ${at(to)}`
178
+ }
124
179
 
125
180
  function Floatie({ side }: { side: 'front' | 'back' }) {
126
181
  const arc = (dy: number) => `M${-orbit.rx} ${dy}A${orbit.rx} ${orbit.ry} 0 0 ${side === 'back' ? 1 : 0} ${orbit.rx} ${dy}`
@@ -139,10 +194,27 @@ function TeslaCoil() {
139
194
  <rect x="180" y="226" width="64" height="190" rx="14" fill="#c9d2ff" stroke="#fff" strokeWidth="18" paintOrder="stroke fill" />
140
195
  <path d="M180 270h64M180 306h64M180 342h64M180 378h64" stroke="#8b95a5" strokeWidth="12" />
141
196
  <ellipse cx="212" cy="212" rx="84" ry="36" fill="#8b95a5" stroke="#fff" strokeWidth="18" paintOrder="stroke fill" />
142
- <ellipse cx="212" cy="204" rx="46" ry="13" fill="#5b6577" />
197
+ <ellipse className="dca-fx-tesla-top" cx="212" cy="204" rx="46" ry="13" fill="#5b6577" />
143
198
  </>
144
199
  }
145
- const teslaArc = 'M212 186L246 142L296 160L330 104L384 124L420 76L470 96L512 58L556 92L604 72L642 122L694 104L728 156L776 138L812 186'
200
+ const teslaArcs = [
201
+ 'M212 186L246 142L296 160L330 104L384 124L420 76L470 96L512 58L556 92L604 72L642 122L694 104L728 156L776 138L812 186',
202
+ 'M212 186L234 128L290 138L312 82L378 94L408 44L468 66L520 32L566 68L624 46L652 98L714 86L738 136L794 132L812 186',
203
+ 'M212 186L268 166L286 116L352 138L376 90L444 110L476 68L532 96L576 64L620 98L672 84L690 134L752 122L772 168L812 186',
204
+ ]
205
+ const teslaBolt = 'M212 186L252 116L302 146L338 64L404 98L440 22L502 58L534 6L590 54L626 26L680 100L718 76L770 138L812 186'
206
+ const teslaArcTimes = [['.6s', '0s'], ['.75s', '-.25s'], ['.9s', '-.6s']]
207
+ function Bolt({ d, width }: { d: string; width: number }) {
208
+ return <><path d={d} stroke="#fff" strokeWidth={width + 14} /><path d={d} stroke="#4de3ff" strokeWidth={width} /><path d={d} stroke="#fff" strokeWidth={width * .3} /></>
209
+ }
210
+ function TeslaSparks() {
211
+ return <g className="dca-fx">
212
+ <path className="dca-fx-tesla-spark" d="M212 108l16 56 56 22-56 22-16 56-16-56-56-22 56-22Z" fill="#a8f3ff" stroke="#fff" strokeWidth="12" strokeLinejoin="round" paintOrder="stroke fill" />
213
+ {[[-110, -70], [-130, 20], [-40, -120]].map(([dx, dy], i) => <g key={i} className="dca-fx-tesla-bit" style={{ '--dca-dx': `${dx}px`, '--dca-dy': `${dy}px` } as CSSProperties}>
214
+ <circle cx="212" cy="186" r="24" fill="#fff" /><circle cx="212" cy="186" r="14" fill="#4de3ff" />
215
+ </g>)}
216
+ </g>
217
+ }
146
218
 
147
219
  const dragonTail = 'M313 773 275 795 241 809 211 815 184 815 161 810 140 799 121 782 106 759 94 729 88 693 88 651 94 605 58 595 44 645 38 694 40 739 49 782 66 820 92 854 125 880 165 898 211 905 260 903 313 890 367 867Z'
148
220
 
@@ -225,9 +297,13 @@ export function BackDecoration({ id }: { id: BackId }) {
225
297
  <Glow blur={22} className="dca-fx-pulse">{mirrored(<path d={angelWing.outer} fill="#fff7dc" opacity=".6" />)}</Glow>
226
298
  <Wings {...angelWing} fill="#fff" lining="#dfe4ff" outline="#b9c4ff" flap="dca-fx-flap-slow" />
227
299
  </>
228
- case 'dragon-wings': return <Wings {...dragonWing} fill="#b23a48" lining="#7f2634">
229
- <g className="dca-fx dca-fx-pulse" fill="#ffb347"><circle cx="30" cy="350" r="14" /><circle cx="48" cy="618" r="12" /><circle cx="236" cy="704" r="12" /></g>
230
- </Wings>
300
+ case 'dragon-wings': return mirrored(<>
301
+ <Wing outer={dragonWing.outer} fill="#b23a48" flap="dca-fx-dragon-flap">
302
+ <path className="dca-fx-wing-ignite" d={dragonWing.inner} fill="#7f2634" />
303
+ <g className="dca-fx-wing-hot" fill="#ffb347"><g className="dca-fx dca-fx-pulse"><circle cx="30" cy="350" r="14" /><circle cx="48" cy="618" r="12" /><circle cx="236" cy="704" r="12" /></g></g>
304
+ </Wing>
305
+ <DragonEmbers />
306
+ </>)
231
307
  case 'crescent-moon': return <>
232
308
  <path d="M330 130a190 190 0 1 0 176 254a150 150 0 0 1-176-254Z" fill="#f6d365" stroke="#fff" strokeWidth="18" strokeLinejoin="round" paintOrder="stroke fill" />
233
309
  <path className="dca-fx dca-fx-sparkle-solo" d="M720 150l12 30 30 12-30 12-12 30-12-30-30-12 30-12Z" fill="#fff3c4" stroke="#fff" strokeWidth="10" strokeLinejoin="round" paintOrder="stroke fill" />
@@ -284,6 +360,8 @@ export function BackDecoration({ id }: { id: BackId }) {
284
360
  <path d="M826 334C840 384 834 424 800 460" stroke="#3c4658" strokeWidth="22" strokeLinecap="round" />
285
361
  </>
286
362
  case 'twin-blades': return <>
363
+ <Slash fill="#9fb2ff" core="#eef1ff" />
364
+ <g transform="matrix(-1 0 0 1 1024 0)"><Slash fill="#7fe8d8" core="#eafffa" delay=".14s" /></g>
287
365
  <g transform={leftShoulder}><Sword blade="#1f2330" glow="#9fb2ff" guard="#3c4658"><path d="M-28-13H718L772-3" stroke="#dfe6f5" strokeWidth="9" strokeLinecap="round" strokeLinejoin="round" /></Sword></g>
288
366
  <g transform="matrix(-1 0 0 1 1024 0)"><g transform={leftShoulder}><Sword blade="#8fdccf" glow="#7fe8d8" guard="#a7b1c0"><path d="M-28 0H728" stroke="#e6fbf6" strokeWidth="10" strokeLinecap="round" /></Sword></g></g>
289
367
  </>
@@ -299,12 +377,15 @@ export function BackDecoration({ id }: { id: BackId }) {
299
377
  <Glow blur={24} className="dca-fx-pulse"><circle cx={halo.cx} cy={halo.cy} r={halo.r} fill="none" stroke="#ffe08a" strokeWidth="74" opacity=".65" /></Glow>
300
378
  <circle cx={halo.cx} cy={halo.cy} r={halo.r} fill="none" stroke="#fff" strokeWidth="54" />
301
379
  <circle cx={halo.cx} cy={halo.cy} r={halo.r} fill="none" stroke="#f6b500" strokeWidth="34" />
380
+ <Glow blur={28} className="dca-fx-halo-flare"><circle cx={halo.cx} cy={halo.cy} r={halo.r} fill="none" stroke="#fff3c4" strokeWidth="92" /></Glow>
381
+ <circle className="dca-fx dca-fx-halo-flare" cx={halo.cx} cy={halo.cy} r={halo.r} fill="none" stroke="#ffe48a" strokeWidth="34" />
382
+ <g className="dca-fx dca-fx-halo-glint" style={{ transformOrigin: `${halo.cx}px ${halo.cy}px` }} strokeLinecap="round">
383
+ <path d={haloArc(-214, -126)} stroke="#ffe08a" strokeWidth="24" />
384
+ <path d={haloArc(-160, -126)} stroke="#fff3c4" strokeWidth="28" />
385
+ <path d={haloArc(-140, -124)} stroke="#fff" strokeWidth="30" />
386
+ </g>
302
387
  </>
303
- case 'orbit-ring': return <g transform={orbit.transform}>
304
- <Glow blur={22} className="dca-fx-pulse"><ellipse rx={orbit.rx} ry={orbit.ry} fill="none" stroke="#b9c4ff" strokeWidth="60" opacity=".55" /></Glow>
305
- <OrbitArc side="back" />
306
- <OrbitBodies side="back" />
307
- </g>
388
+ case 'fin-funnels': return <FinFunnels />
308
389
  case 'koi-orbit': return <g transform={koiOrbit}><KoiBodies side="back" /></g>
309
390
  case 'peeking-cat': return <g transform="translate(786 376) rotate(24) scale(1.1)">
310
391
  <S d="M-100 14C-100-46-58-84 0-84S100-46 100 14 60 96 0 96-100 74-100 14ZM-92-24-86-138-22-76ZM92-24 86-138 22-76Z" fill="#ed985f" />
@@ -350,13 +431,17 @@ export function BackDecoration({ id }: { id: BackId }) {
350
431
  </g>
351
432
  </>
352
433
  case 'tesla-coils': return <>
434
+ <Glow blur={16} className="dca-fx-tesla-glow">{mirrored(<ellipse cx="212" cy="200" rx="74" ry="34" fill="#4de3ff" />)}</Glow>
353
435
  {mirrored(<TeslaCoil />)}
354
- <Glow blur={14} className="dca-fx-node"><path d={teslaArc} stroke="#4de3ff" strokeWidth="44" strokeLinejoin="round" /></Glow>
355
- <g className="dca-fx-node" strokeLinejoin="round" strokeLinecap="round">
356
- <path d={teslaArc} stroke="#fff" strokeWidth="34" />
357
- <path d={teslaArc} stroke="#4de3ff" strokeWidth="20" />
358
- <path d={teslaArc} stroke="#fff" strokeWidth="6" />
436
+ <g className="dca-fx-tesla-crackle" strokeLinejoin="round" strokeLinecap="round">
437
+ <Glow blur={14} className="dca-fx-node"><path d={teslaArcs.join('')} stroke="#4de3ff" strokeWidth="44" /></Glow>
438
+ {teslaArcs.map((d, i) => <g key={d} className={i ? 'dca-fx dca-fx-tesla-arc dca-fx-tesla-arc-alt' : 'dca-fx-tesla-arc'} style={{ animationDuration: teslaArcTimes[i][0], animationDelay: teslaArcTimes[i][1] }}><Bolt d={d} width={20} /></g>)}
359
439
  </g>
440
+ <g className="dca-fx dca-fx-tesla-discharge" strokeLinejoin="round" strokeLinecap="round">
441
+ <Glow blur={18}><path d={teslaBolt} stroke="#7fefff" strokeWidth="76" />{mirrored(<circle cx="212" cy="190" r="70" fill="#7fefff" />)}</Glow>
442
+ <Bolt d={teslaBolt} width={36} />
443
+ </g>
444
+ {mirrored(<TeslaSparks />)}
360
445
  </>
361
446
  case 'great-wave': return <Water masses={[curl, swell]} />
362
447
  case 'cloud-dragon': return <CloudDragon />
@@ -366,14 +451,10 @@ export function BackDecoration({ id }: { id: BackId }) {
366
451
 
367
452
  export function BackFrontDecoration({ id }: { id: BackId }) {
368
453
  switch (id) {
369
- case 'orbit-ring': return <g data-back-front={id} transform={orbit.transform}>
370
- <OrbitArc side="front" />
371
- <OrbitBodies side="front" />
372
- </g>
373
454
  case 'koi-orbit': return <g data-back-front={id} transform={koiOrbit}><KoiBodies side="front" /></g>
374
455
  case 'donut-floatie': return <g data-back-front={id}><Floatie side="front" /></g>
375
456
  case 'cloud-dragon': return <g data-back-front={id}><CloudDragonFront /></g>
376
457
  default: return null
377
458
  }
378
459
  }
379
- export function hasFrontPart(id: BackId): boolean { return id === 'orbit-ring' || id === 'koi-orbit' || id === 'donut-floatie' || id === 'cloud-dragon' }
460
+ export function hasFrontPart(id: BackId): boolean { return id === 'koi-orbit' || id === 'donut-floatie' || id === 'cloud-dragon' }
@@ -130,10 +130,14 @@ export function FaceDecoration({ id }: { id: FaceId }) {
130
130
  <path d="M404 792q108 36 216 0" stroke="#fff" strokeWidth="24" strokeLinecap="round" fill="none" />
131
131
  <path d="M404 792q108 36 216 0" stroke="#3c4658" strokeWidth="10" strokeLinecap="round" fill="none" />
132
132
  <Glow blur={14} className="dca-fx-pulse"><path d={crystal} fill="#5eead4" stroke="#5eead4" strokeWidth="18" opacity=".9" /></Glow>
133
- <S d={crystal} fill="#5eead4" stroke={12} />
134
- <path d="M512 814c12 14 26 28 26 40a26 26 0 0 1-26 26Z" fill="#2cc5b0" />
133
+ <g className="dca-fx-pendant" style={{ transformOrigin: '512px 812px' }}>
134
+ <S d={crystal} fill="#5eead4" stroke={12} />
135
+ <path d="M512 814c12 14 26 28 26 40a26 26 0 0 1-26 26Z" fill="#2cc5b0" />
136
+ <Detail><path d="M500 842q-7 10-3 22" stroke="#ccfbf1" strokeWidth="7" strokeLinecap="round" fill="none" /></Detail>
137
+ <path className="dca-fx dca-fx-facet-flash" d={crystal} fill="#f0fdfa" style={{ animationDuration: '11s', animationDelay: '3s' }} />
138
+ <path className="dca-fx dca-fx-star-pop" d="M536 794Q542 828 566 834Q542 840 536 874Q530 840 506 834Q530 828 536 794Z" fill="#f0fdfa" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" style={{ animationDuration: '11s', animationDelay: '3.05s' }} />
139
+ </g>
135
140
  <circle cx="512" cy="812" r="8" fill="#efc65c" stroke="#fff" strokeWidth="8" paintOrder="stroke fill" />
136
- <Detail><path d="M500 842q-7 10-3 22" stroke="#ccfbf1" strokeWidth="7" strokeLinecap="round" fill="none" /></Detail>
137
141
  </>
138
142
  default: return null
139
143
  }
@@ -1,5 +1,7 @@
1
+ import { useId } from 'react'
1
2
  import type { HandId } from './items.js'
2
3
  import { Glow, Plane, useClipId } from './DecorationShapes.js'
4
+ import { lock, tube, type Pt } from './spine.js'
3
5
 
4
6
  const mark = 'var(--dca-held-mark, #3161f7)'
5
7
  const accent = 'var(--dca-held-accent, #f6b500)'
@@ -71,18 +73,7 @@ export function HandDecoration({ id }: { id: HandId }) {
71
73
  <rect x="777" y="712" width="46" height="18" rx="6" fill="#8b95a5" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
72
74
  <rect x="783" y="726" width="34" height="90" rx="12" fill="#2a3140" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
73
75
  </g>}
74
- {id === 'thunder-hammer' && <g transform="translate(233 640) rotate(-12) scale(.86) translate(-800 -700)">
75
- <Glow blur={16} className="dca-fx-pulse"><rect x="708" y="456" width="184" height="120" rx="28" fill="#4de3ff" opacity=".55" /></Glow>
76
- <rect x="787" y="556" width="26" height="186" rx="12" fill="#3c4658" stroke="#fff" strokeWidth="16" paintOrder="stroke fill" />
77
- <rect x="778" y="734" width="44" height="28" rx="10" fill="#8b95a5" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
78
- <rect x="715" y="466" width="170" height="100" rx="20" fill="#aab4c3" stroke="#fff" strokeWidth="18" paintOrder="stroke fill" />
79
- <path d="M735 466h14v100h-14q-20 0-20-20v-60q0-20 20-20ZM865 466h-14v100h14q20 0 20-20v-60q0-20-20-20Z" fill="#737e90" />
80
- <rect x="777" y="466" width="46" height="100" fill={mark} />
81
- {['M740 458l-24-26 26-8-18-40', 'M860 458l18-28-26-6 26-36', 'M712 510l-22 2 12 14-14 10'].map((d, index) =>
82
- <g key={d} className="dca-fx dca-fx-node" fill="none" strokeLinejoin="miter" style={index ? { animationDelay: `${index * .6}s` } : undefined}>
83
- <path d={d} stroke="#4de3ff" strokeWidth="20" /><path d={d} stroke="#f2feff" strokeWidth="8" />
84
- </g>)}
85
- </g>}
76
+ {id === 'thunder-hammer' && <ThunderHammer />}
86
77
  {id === 'paintbrush' && <g transform="translate(233 640) rotate(-25) translate(-800 -720)">
87
78
  <rect x="788" y="660" width="24" height="180" rx="12" fill="#e0ad84" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
88
79
  <rect x="780" y="626" width="40" height="40" rx="6" fill="#8b95a5" stroke="#fff" strokeWidth="12" paintOrder="stroke fill" />
@@ -288,18 +279,78 @@ export function HandDecoration({ id }: { id: HandId }) {
288
279
  </g>
289
280
  }
290
281
 
282
+ function burst(cx: number, cy: number, r: number, inner: number, points: number, turn = 0) {
283
+ return `M${Array.from({ length: points * 2 }, (_, i) => {
284
+ const a = ((i * 180) / points + turn) * Math.PI / 180, d = i % 2 ? inner : r
285
+ return `${Math.round(cx + d * Math.sin(a))} ${Math.round(cy - d * Math.cos(a))}`
286
+ }).join('L')}Z`
287
+ }
288
+ function Halo({ color, shapes }: { color: string; shapes: [number, number, number, number][] }) {
289
+ const id = `dca-glow-${useId().replace(/:/g, '')}`
290
+ return <>
291
+ <defs><radialGradient id={id}><stop offset=".35" stopColor={color} stopOpacity=".8" /><stop offset=".7" stopColor={color} stopOpacity=".35" /><stop offset="1" stopColor={color} stopOpacity="0" /></radialGradient></defs>
292
+ <g className="dca-fx dca-fx-pulse" fill={`url(#${id})`}>{shapes.map(([cx, cy, rx, ry]) => <ellipse key={`${cx}-${cy}`} cx={cx} cy={cy} rx={rx} ry={ry} />)}</g>
293
+ </>
294
+ }
295
+
296
+ const hammerArcs = ['M740 458l-24-26 26-8-18-40', 'M860 458l18-28-26-6 26-36', 'M712 510l-22 2 12 14-14 10']
297
+ const hammerBolt = 'M836 128H884L850 236H878L836 350H860L800 456L812 374H786L818 262H790Z'
298
+ const hammerSparks = ([[-112, 128, 20], [-72, 138, 24], [-34, 120, 18], [4, 142, 22], [44, 124, 18], [80, 116, 16]] as const)
299
+ .map(([a, d, r]) => burst(800 + d * Math.sin(a * Math.PI / 180), 456 - d * Math.cos(a * Math.PI / 180), r, r * .36, 4))
300
+ function ThunderHammer() {
301
+ return <g transform="translate(233 640) rotate(-12) scale(.86) translate(-800 -700)">
302
+ <g className="dca-fx-hammer-lift" style={{ transformOrigin: '800px 700px' }}>
303
+ <g className="dca-fx-hammer-twirl" style={{ transformOrigin: '800px 516px' }}>
304
+ <g className="dca-fx-hammer-charge" style={{ transformOrigin: '800px 516px' }}><Halo color="#4de3ff" shapes={[[800, 516, 132, 96]]} /></g>
305
+ </g>
306
+ <rect x="787" y="556" width="26" height="186" rx="12" fill="#3c4658" stroke="#fff" strokeWidth="16" paintOrder="stroke fill" />
307
+ <rect x="778" y="734" width="44" height="28" rx="10" fill="#8b95a5" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
308
+ <g className="dca-fx-hammer-twirl" style={{ transformOrigin: '800px 516px' }}>
309
+ <rect x="715" y="466" width="170" height="100" rx="20" fill="#aab4c3" stroke="#fff" strokeWidth="18" paintOrder="stroke fill" />
310
+ <path d="M735 466h14v100h-14q-20 0-20-20v-60q0-20 20-20ZM865 466h-14v100h14q20 0 20-20v-60q0-20-20-20Z" fill="#737e90" />
311
+ <rect x="777" y="466" width="46" height="100" fill={mark} />
312
+ {hammerArcs.map((d, index) =>
313
+ <g key={d} className="dca-fx dca-fx-node" fill="none" strokeLinejoin="miter" style={index ? { animationDelay: `${index * .6}s` } : undefined}>
314
+ <path d={d} stroke="#4de3ff" strokeWidth="20" /><path d={d} stroke="#f2feff" strokeWidth="8" />
315
+ </g>)}
316
+ </g>
317
+ <path className="dca-fx dca-fx-hammer-bolt" d={hammerBolt} fill="#4de3ff" stroke="#fff" strokeWidth="14" strokeLinejoin="round" paintOrder="stroke fill" style={{ transformOrigin: '860px 128px' }} />
318
+ <g className="dca-fx dca-fx-hammer-flash" style={{ transformOrigin: '800px 456px' }}>
319
+ <path d={burst(800, 456, 86, 38, 8, 22.5)} fill="#4de3ff" stroke="#fff" strokeWidth="14" strokeLinejoin="round" paintOrder="stroke fill" />
320
+ <path d={burst(800, 456, 46, 22, 8, 22.5)} fill="#e6fbff" />
321
+ </g>
322
+ <g className="dca-fx dca-fx-hammer-sparks" fill="#4de3ff" stroke="#fff" strokeWidth="10" strokeLinejoin="round" paintOrder="stroke fill" style={{ transformOrigin: '800px 456px' }}>
323
+ {hammerSparks.map(d => <path key={d} d={d} />)}
324
+ </g>
325
+ </g>
326
+ </g>
327
+ }
328
+
329
+ const keySparks = ([[-112, 118, 18], [-66, 130, 22], [-24, 120, 18], [16, 112, 16]] as const)
330
+ .map(([a, d, r]) => burst(755 + d * Math.sin(a * Math.PI / 180), 465 - d * Math.cos(a * Math.PI / 180), r, r * .36, 4))
291
331
  function MasterKey() {
292
332
  const clip = useClipId()
293
333
  const shape = 'M728 422H818V712H782V508H728V486H746V470H728V452H750V436H728Z'
294
334
  const bow = 'M800 718a54 54 0 1 1 0 108 54 54 0 1 1 0-108Zm0 34a20 20 0 1 0 0 40 20 20 0 1 0 0-40Z'
295
335
  return <g transform="translate(233 640) rotate(-12) scale(.9) translate(-800 -760)">
296
336
  <defs><clipPath id={clip}><path d={shape} /><path d={bow} /></clipPath></defs>
297
- <Glow blur={16} className="dca-fx-pulse"><path d="M772 410h56v326h-56ZM716 412h70v108h-70Z" fill="#ffd970" opacity=".8" /></Glow>
298
- <path d={shape} fill="#efc65c" stroke="#fff" strokeWidth="16" strokeLinejoin="round" paintOrder="stroke fill" />
299
- <path d={bow} fill="#efc65c" fillRule="evenodd" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
300
- <path d="M812 432v270" stroke="#c99139" strokeWidth="7" />
301
- <rect x="774" y="700" width="52" height="26" rx="8" fill="#c99139" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
302
- <g clipPath={`url(#${clip})`}><g transform="translate(800 740) rotate(-90) scale(.45 1)"><g className="dca-fx dca-fx-sheen" fill="#fff3c4"><path d="M3-80h67l-73 160h-67Z" opacity=".9" /></g></g></g>
337
+ <g className="dca-fx-key-push" style={{ transformOrigin: '800px 760px' }}>
338
+ <g className="dca-fx-key-turn" style={{ transformOrigin: '800px 760px' }}>
339
+ <Halo color="#ffd970" shapes={[[800, 566, 54, 196], [752, 466, 66, 78]]} />
340
+ <g className="dca-fx dca-fx-key-burst" style={{ transformOrigin: '755px 465px' }}>
341
+ <path d={burst(755, 465, 100, 42, 8)} fill="#ffd970" stroke="#fff" strokeWidth="14" strokeLinejoin="round" paintOrder="stroke fill" />
342
+ <path d={burst(755, 465, 56, 26, 8)} fill="#fff3c4" />
343
+ </g>
344
+ <path d={shape} fill="#efc65c" stroke="#fff" strokeWidth="16" strokeLinejoin="round" paintOrder="stroke fill" />
345
+ <path d={bow} fill="#efc65c" fillRule="evenodd" stroke="#fff" strokeWidth="14" paintOrder="stroke fill" />
346
+ <path d="M812 432v270" stroke="#c99139" strokeWidth="7" />
347
+ <rect x="774" y="700" width="52" height="26" rx="8" fill="#c99139" stroke="#fff" strokeWidth="10" paintOrder="stroke fill" />
348
+ <g clipPath={`url(#${clip})`}><g transform="translate(800 740) rotate(-90) scale(.45 1)"><g className="dca-fx dca-fx-sheen" fill="#fff3c4"><path d="M3-80h67l-73 160h-67Z" opacity=".9" /></g></g></g>
349
+ <g className="dca-fx dca-fx-key-sparks" fill="#f6b500" stroke="#fff" strokeWidth="10" strokeLinejoin="round" paintOrder="stroke fill" style={{ transformOrigin: '755px 465px' }}>
350
+ {keySparks.map(d => <path key={d} d={d} />)}
351
+ </g>
352
+ </g>
353
+ </g>
303
354
  </g>
304
355
  }
305
356
 
@@ -311,24 +362,41 @@ const petDragonBody = [
311
362
  'M806 532c34 0 48 34 46 64-2 34-24 54-50 54s-40-20-38-54c2-30 14-64 42-64Z',
312
363
  'M826 512c0-22-16-38-38-38-18 0-32 8-40 20-10 4-18 10-18 20 0 10 10 16 24 16 14 10 30 14 46 12 16-4 26-14 26-30Z',
313
364
  ]
365
+ const jetSpine: Pt[] = [[0, 0], [-36, -4], [-74, -8], [-110, -6]]
366
+ const dragonJet = [tube(jetSpine, t => 12 + 34 * Math.sin(Math.PI * t * .62)), lock(-86, -18, 204, 42, 22, .5), lock(-90, 9, 162, 36, 18, -.5)]
367
+ const dragonJetCore = tube(jetSpine, t => 4 + 16 * Math.sin(Math.PI * t * .62), 0, .76)
368
+ const dragonEmbers = ([[-36, -14, 10], [-58, 8, 12], [-78, -22, 9], [-96, 4, 11], [-110, -26, 8]] as const).map(([x, y, r]) => burst(x, y, r, r * .62, 4))
314
369
  function PetDragon() {
315
370
  return <g transform="translate(233 640) translate(-800 -640)">
316
- {[{ at: 'translate(790 552)', d: dragonWing }, { at: 'translate(814 552) scale(-1 1)', d: dragonFarWing }].map(wing =>
317
- <g key={wing.at} transform={wing.at}><g className="dca-fx-flap-slow" style={{ transformOrigin: '0px 0px' }}>
318
- <path d={wing.d} fill="#2f7a4f" stroke="#fff" strokeWidth="12" strokeLinejoin="round" paintOrder="stroke fill" />
319
- </g></g>)}
320
- <path d="M812 486 840 446 826 490ZM796 482 806 438 786 482Z" fill="#e0ad84" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
321
- <Plane d={petDragonBody} fill="#4fae6a" contour={14} />
322
- <path d="M812 700l-26 6 18 18Z" fill="#2f7a4f" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
323
- <ellipse cx="786" cy="600" rx="16" ry="34" fill="#f6e3a1" />
324
- <path d="M788 644v14M812 646v14" stroke="#fff" strokeWidth="22" />
325
- <path d="M788 644v14M812 646v14" stroke="#2f7a4f" strokeWidth="10" />
326
- <circle cx="794" cy="502" r="7" fill="#202124" />
327
- <g transform="translate(728 518) rotate(-80)">
328
- <Glow blur={10} className="dca-fx-pulse"><ellipse cy="-30" rx="18" ry="32" fill="#ffb347" opacity=".75" /></Glow>
329
- <g className="dca-fx dca-fx-flame" style={{ transformOrigin: '0px 0px' }}>
330
- <path d="M0 0C-16-6-22-24-14-40c2 10 8 14 14 14-4-14 2-28 12-36-4 16 6 26 6 40S10 0 0 0Z" fill="#ffb347" stroke="#fff" strokeWidth="8" paintOrder="stroke fill" />
331
- <path d="M1-8c-8-4-10-14-6-20 2 4 6 6 8 6 0-8 2-14 6-18 0 10 4 16 4 22s-4 12-12 10Z" fill="#ffe08a" />
371
+ <g className="dca-fx-dragon-body" style={{ transformOrigin: '800px 660px' }}>
372
+ {[{ at: 'translate(790 552)', d: dragonWing }, { at: 'translate(814 552) scale(-1 1)', d: dragonFarWing }].map(wing =>
373
+ <g key={wing.at} transform={wing.at}><g className="dca-fx-flap-slow" style={{ transformOrigin: '0px 0px' }}>
374
+ <path d={wing.d} fill="#2f7a4f" stroke="#fff" strokeWidth="12" strokeLinejoin="round" paintOrder="stroke fill" />
375
+ </g></g>)}
376
+ <path d="M812 486 840 446 826 490ZM796 482 806 438 786 482Z" fill="#e0ad84" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
377
+ <Plane d={petDragonBody} fill="#4fae6a" contour={14} />
378
+ <path d="M812 700l-26 6 18 18Z" fill="#2f7a4f" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill" />
379
+ <ellipse cx="786" cy="600" rx="16" ry="34" fill="#f6e3a1" />
380
+ <path d="M788 644v14M812 646v14" stroke="#fff" strokeWidth="22" />
381
+ <path d="M788 644v14M812 646v14" stroke="#2f7a4f" strokeWidth="10" />
382
+ <circle cx="794" cy="502" r="7" fill="#202124" />
383
+ <g transform="translate(728 518) rotate(-80)">
384
+ <Halo color="#ffb347" shapes={[[0, -30, 26, 42]]} />
385
+ <g className="dca-fx dca-fx-flame" style={{ transformOrigin: '0px 0px' }}>
386
+ <path d="M0 0C-16-6-22-24-14-40c2 10 8 14 14 14-4-14 2-28 12-36-4 16 6 26 6 40S10 0 0 0Z" fill="#ffb347" stroke="#fff" strokeWidth="8" paintOrder="stroke fill" />
387
+ <path d="M1-8c-8-4-10-14-6-20 2 4 6 6 8 6 0-8 2-14 6-18 0 10 4 16 4 22s-4 12-12 10Z" fill="#ffe08a" />
388
+ </g>
389
+ </g>
390
+ <g transform="translate(726 516) rotate(26)">
391
+ <g className="dca-fx dca-fx-dragon-jet" style={{ transformOrigin: '0px 0px' }}>
392
+ <g className="dca-fx-flame" style={{ transformOrigin: '0px 0px' }}>
393
+ <Plane d={dragonJet} fill="#ffb347" contour={10} />
394
+ <path d={dragonJetCore} fill="#ffe08a" />
395
+ </g>
396
+ </g>
397
+ <g className="dca-fx dca-fx-dragon-embers" fill="#ffb347" stroke="#fff" strokeWidth="8" strokeLinejoin="round" paintOrder="stroke fill">
398
+ {dragonEmbers.map(d => <path key={d} d={d} />)}
399
+ </g>
332
400
  </g>
333
401
  </g>
334
402
  </g>
@@ -1,5 +1,23 @@
1
1
  import type { HeadId } from './items.js'
2
- import { Detail, Silhouette as S } from './DecorationShapes.js'
2
+ import { Detail, Silhouette as S, useClipId } from './DecorationShapes.js'
3
+
4
+ const crownBody = 'M363 282c-7-20 9-31 24-18l56 54 51-86c8-15 27-15 36 0l51 86 56-54c15-13 31-2 24 18l-24 117H387Z'
5
+ const sapphire = 'm512 305 26 30-26 30-26-30Z'
6
+ function Crown() {
7
+ const clip = useClipId()
8
+ return <>
9
+ <defs><clipPath id={clip}><path d={crownBody} /></clipPath></defs>
10
+ <S d={crownBody} fill="#efc65c" />
11
+ <path d="M387 365h250v34H387Z" fill="#c99139" />
12
+ <g clipPath={`url(#${clip})`}><path className="dca-fx dca-fx-sweep" d="M210 220h56l-80 190h-56Z" fill="#fff" opacity=".6" style={{ animationDelay: '1.5s' }} /></g>
13
+ <Detail>
14
+ <path d={sapphire} fill="#73b8cc" /><path d="m512 305 0 60-26-30Z" fill="#a3d8df" />
15
+ <path className="dca-fx dca-fx-facet-flash" d={sapphire} fill="#effcff" style={{ animationDelay: '1.95s' }} />
16
+ <circle cx="410" cy="342" r="8" fill="#fff1af" /><circle cx="614" cy="342" r="8" fill="#fff1af" />
17
+ </Detail>
18
+ <path className="dca-fx dca-fx-star-pop" d="M528 266Q535 311 566 318Q535 325 528 370Q521 325 490 318Q521 311 528 266Z" fill="#fffbe6" stroke="#fff" strokeWidth="10" strokeLinejoin="round" paintOrder="stroke fill" style={{ animationDelay: '2s' }} />
19
+ </>
20
+ }
3
21
 
4
22
  export function HatDecoration({ id }: { id: HeadId }) {
5
23
  switch (id) {
@@ -48,11 +66,7 @@ export function HatDecoration({ id }: { id: HeadId }) {
48
66
  <circle cx="513" cy="171" r="28" fill="#f5d07b" />
49
67
  <Detail><path d="m526 212 75 132" stroke="#f6c4ce" strokeWidth="11" strokeLinecap="round" /></Detail>
50
68
  </>
51
- case 'crown': return <>
52
- <S d="M363 282c-7-20 9-31 24-18l56 54 51-86c8-15 27-15 36 0l51 86 56-54c15-13 31-2 24 18l-24 117H387Z" fill="#efc65c" />
53
- <path d="M387 365h250v34H387Z" fill="#c99139" />
54
- <Detail><path d="m512 305 26 30-26 30-26-30Z" fill="#73b8cc" /><path d="m512 305 0 60-26-30Z" fill="#a3d8df" /><circle cx="410" cy="342" r="8" fill="#fff1af" /><circle cx="614" cy="342" r="8" fill="#fff1af" /></Detail>
55
- </>
69
+ case 'crown': return <Crown />
56
70
  case 'hard-hat': return <>
57
71
  <S d="M358 361c0-94 42-154 133-163v-11c0-15 42-15 42 0v11c91 9 133 69 133 163h22c23 0 23 39 0 39H336c-23 0-23-39 0-39Z" fill="#f5bd48" />
58
72
  <path d="M533 198c91 9 133 69 133 163h-48c0-86-24-135-85-163Z" fill="#d68d32" /><path d="M494 192h36v169h-36Z" fill="#ffdc79" />
package/src/MascotRig.tsx CHANGED
@@ -98,9 +98,9 @@ export function MascotRig({
98
98
  </linearGradient>}
99
99
  <RigMaterialClip id={materialClip} />
100
100
  <linearGradient className="dca-paint-mark" id={blueMark} x1="380" y1="696" x2="492" y2="557" gradientUnits="userSpaceOnUse">
101
- <stop offset="0" stopColor={mark0} />
102
- <stop offset=".55" stopColor={mark1} />
103
- <stop offset="1" stopColor={mark2} />
101
+ <stop offset="0" stopColor={mark0} style={{ '--dca-stop': mark0 } as CSSProperties} />
102
+ <stop offset=".55" stopColor={mark1} style={{ '--dca-stop': mark1 } as CSSProperties} />
103
+ <stop offset="1" stopColor={mark2} style={{ '--dca-stop': mark2 } as CSSProperties} />
104
104
  </linearGradient>
105
105
  <linearGradient id={yellow} x1="481" y1="174" x2="617" y2="713" gradientUnits="userSpaceOnUse">
106
106
  <stop offset="0" stopColor="#ffcf11" />