@dotcraft/avatar 0.6.3 → 0.6.5

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.
Files changed (83) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +46 -43
  3. package/dist/accessories.css +14 -14
  4. package/dist/avatar.css +62 -62
  5. package/dist/composer/ComposerMascot.d.ts +1 -1
  6. package/dist/composer/ComposerMascot.d.ts.map +1 -1
  7. package/dist/composer/ComposerMascot.js +33 -107
  8. package/dist/composer/ComposerMascot.js.map +1 -1
  9. package/dist/composer/MascotIdleStage.d.ts +11 -0
  10. package/dist/composer/MascotIdleStage.d.ts.map +1 -0
  11. package/dist/composer/MascotIdleStage.js +9 -0
  12. package/dist/composer/MascotIdleStage.js.map +1 -0
  13. package/dist/composer/constants.d.ts +12 -1
  14. package/dist/composer/constants.d.ts.map +1 -1
  15. package/dist/composer/constants.js +9 -4
  16. package/dist/composer/constants.js.map +1 -1
  17. package/dist/composer/styles/energy.css +99 -99
  18. package/dist/composer/styles/expressions.css +20 -20
  19. package/dist/composer/styles/feedback.css +188 -188
  20. package/dist/composer/styles/focus.css +72 -72
  21. package/dist/composer/styles/foundation.css +301 -287
  22. package/dist/composer/styles/idle.css +449 -438
  23. package/dist/composer/styles/overdrive.css +264 -264
  24. package/dist/composer/styles/props.css +21 -21
  25. package/dist/composer/types.d.ts +1 -0
  26. package/dist/composer/types.d.ts.map +1 -1
  27. package/dist/composer/useComposerAvatarBehavior.d.ts +1 -0
  28. package/dist/composer/useComposerAvatarBehavior.d.ts.map +1 -1
  29. package/dist/composer/useComposerAvatarBehavior.js +2 -2
  30. package/dist/composer/useComposerAvatarBehavior.js.map +1 -1
  31. package/dist/composer/useMascotActiveIdle.d.ts +33 -0
  32. package/dist/composer/useMascotActiveIdle.d.ts.map +1 -0
  33. package/dist/composer/useMascotActiveIdle.js +128 -0
  34. package/dist/composer/useMascotActiveIdle.js.map +1 -0
  35. package/dist/react.d.ts +5 -0
  36. package/dist/react.d.ts.map +1 -1
  37. package/dist/react.js +4 -0
  38. package/dist/react.js.map +1 -1
  39. package/dist/rig.css +265 -265
  40. package/dist/styles.css +13 -13
  41. package/package.json +56 -55
  42. package/src/AnimatedDecoration.tsx +43 -0
  43. package/src/AppearanceRig.tsx +15 -0
  44. package/src/Avatar.tsx +85 -0
  45. package/src/DecorationShapes.tsx +8 -0
  46. package/src/Decorations.tsx +31 -0
  47. package/src/Faces.tsx +37 -0
  48. package/src/HatDecorations.tsx +75 -0
  49. package/src/HeldDecorations.tsx +48 -0
  50. package/src/MascotRig.tsx +191 -0
  51. package/src/ObjectDecorations.tsx +55 -0
  52. package/src/accessories.css +14 -0
  53. package/src/appearanceModel.ts +65 -0
  54. package/src/avatar.css +62 -0
  55. package/src/characters.ts +5 -0
  56. package/src/composer/ComposerMascot.tsx +445 -0
  57. package/src/composer/ComposerMascotShadow.tsx +5 -0
  58. package/src/composer/MascotIdleStage.tsx +23 -0
  59. package/src/composer/constants.ts +89 -0
  60. package/src/composer/mascotHandoff.ts +19 -0
  61. package/src/composer/styles/energy.css +99 -0
  62. package/src/composer/styles/expressions.css +20 -0
  63. package/src/composer/styles/feedback.css +188 -0
  64. package/src/composer/styles/focus.css +72 -0
  65. package/src/composer/styles/foundation.css +301 -0
  66. package/src/composer/styles/idle.css +449 -0
  67. package/src/composer/styles/overdrive.css +264 -0
  68. package/src/composer/styles/props.css +21 -0
  69. package/src/composer/types.ts +32 -0
  70. package/src/composer/useComposerAvatarBehavior.ts +98 -0
  71. package/src/composer/useComposerMotion.ts +15 -0
  72. package/src/composer/useComposerProfile.ts +50 -0
  73. package/src/composer/useMascotActiveIdle.ts +170 -0
  74. package/src/decorationCatalog.ts +45 -0
  75. package/src/decorationMotion.ts +68 -0
  76. package/src/environment.ts +46 -0
  77. package/src/index.ts +5 -0
  78. package/src/palette.ts +52 -0
  79. package/src/react.ts +11 -0
  80. package/src/rig.css +265 -0
  81. package/src/styles.css +13 -0
  82. package/src/useEventReplay.ts +13 -0
  83. package/src/useGesture.ts +51 -0
@@ -1,99 +1,99 @@
1
- [data-mascot-effort] .dca-robot :is(.dca-paint-body, .dca-paint-mark) stop {
2
- transition: stop-color 360ms ease;
3
- }
4
-
5
- [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(1) {
6
- animation: composer-mascot-energy-medium-dark 6s ease-in-out infinite;
7
- }
8
-
9
- [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(2) {
10
- animation: composer-mascot-energy-medium-mid 6s ease-in-out infinite;
11
- }
12
-
13
- [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(3) {
14
- animation: composer-mascot-energy-medium-light 6s ease-in-out infinite;
15
- }
16
-
17
- [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(1) {
18
- animation: composer-mascot-energy-high-dark 3.8s ease-in-out infinite;
19
- }
20
-
21
- [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(2) {
22
- animation: composer-mascot-energy-high-mid 3.8s ease-in-out infinite;
23
- }
24
-
25
- [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(3) {
26
- animation: composer-mascot-energy-high-light 3.8s ease-in-out infinite;
27
- }
28
-
29
- [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(1) {
30
- animation: composer-mascot-energy-high-mark-dark 3.8s ease-in-out infinite;
31
- }
32
-
33
- [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(2),
34
- [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(3) {
35
- animation: composer-mascot-energy-high-mark-light 3.8s ease-in-out infinite;
36
- }
37
-
38
- [data-mascot-effort='high'] .dca-robot {
39
- filter: drop-shadow(0 0 5px color-mix(in srgb,
40
- oklch(from var(--mascot-energy-accent)
41
- clamp(0.28, calc(l - 0.0112), 0.96)
42
- clamp(0, calc(c * 1.116), 0.3)
43
- calc(h - 3.09)) 28%, transparent));
44
- }
45
-
46
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(1) {
47
- animation: composer-mascot-energy-extra-dark 2.8s ease-in-out infinite;
48
- }
49
-
50
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(2) {
51
- animation: composer-mascot-energy-extra-mid 2.8s ease-in-out infinite;
52
- }
53
-
54
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(3) {
55
- animation: composer-mascot-energy-extra-light 2.8s ease-in-out infinite;
56
- }
57
-
58
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(1) {
59
- animation: composer-mascot-energy-extra-mark-dark 2.8s ease-in-out infinite;
60
- }
61
-
62
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(2),
63
- [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(3) {
64
- animation: composer-mascot-energy-extra-mark-light 2.8s ease-in-out infinite;
65
- }
66
-
67
- [data-mascot-effort='extraHigh'] .dca-robot {
68
- filter: drop-shadow(0 0 7px color-mix(in srgb,
69
- oklch(from var(--mascot-energy-accent)
70
- clamp(0.28, calc(l - 0.0456), 0.96)
71
- clamp(0, calc(c * 1.231), 0.3)
72
- calc(h + 27.55)) 36%, transparent));
73
- }
74
-
75
- [data-mascot-context='max'] .dca-robot {
76
- animation: composer-mascot-max-overdrive-edge 3.8s ease-in-out infinite;
77
- will-change: filter;
78
- }
79
-
80
- [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(1) {
81
- animation: composer-mascot-max-coat-dark 3.8s ease-in-out infinite;
82
- }
83
-
84
- [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(2) {
85
- animation: composer-mascot-max-coat-mid 3.8s ease-in-out infinite;
86
- }
87
-
88
- [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(3) {
89
- animation: composer-mascot-max-coat-light 3.8s ease-in-out infinite;
90
- }
91
-
92
- [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(1) {
93
- animation: composer-mascot-max-coat-mark-dark 3.8s ease-in-out infinite;
94
- }
95
-
96
- [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(2),
97
- [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(3) {
98
- animation: composer-mascot-max-coat-mark-light 3.8s ease-in-out infinite;
99
- }
1
+ [data-mascot-effort] .dca-robot :is(.dca-paint-body, .dca-paint-mark) stop {
2
+ transition: stop-color 360ms ease;
3
+ }
4
+
5
+ [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(1) {
6
+ animation: composer-mascot-energy-medium-dark 6s ease-in-out infinite;
7
+ }
8
+
9
+ [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(2) {
10
+ animation: composer-mascot-energy-medium-mid 6s ease-in-out infinite;
11
+ }
12
+
13
+ [data-mascot-effort='medium'] .dca-robot .dca-paint-body stop:nth-child(3) {
14
+ animation: composer-mascot-energy-medium-light 6s ease-in-out infinite;
15
+ }
16
+
17
+ [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(1) {
18
+ animation: composer-mascot-energy-high-dark 3.8s ease-in-out infinite;
19
+ }
20
+
21
+ [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(2) {
22
+ animation: composer-mascot-energy-high-mid 3.8s ease-in-out infinite;
23
+ }
24
+
25
+ [data-mascot-effort='high'] .dca-robot .dca-paint-body stop:nth-child(3) {
26
+ animation: composer-mascot-energy-high-light 3.8s ease-in-out infinite;
27
+ }
28
+
29
+ [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(1) {
30
+ animation: composer-mascot-energy-high-mark-dark 3.8s ease-in-out infinite;
31
+ }
32
+
33
+ [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(2),
34
+ [data-mascot-effort='high'] .dca-robot .dca-paint-mark stop:nth-child(3) {
35
+ animation: composer-mascot-energy-high-mark-light 3.8s ease-in-out infinite;
36
+ }
37
+
38
+ [data-mascot-effort='high'] .dca-robot {
39
+ filter: drop-shadow(0 0 5px color-mix(in srgb,
40
+ oklch(from var(--mascot-energy-accent)
41
+ clamp(0.28, calc(l - 0.0112), 0.96)
42
+ clamp(0, calc(c * 1.116), 0.3)
43
+ calc(h - 3.09)) 28%, transparent));
44
+ }
45
+
46
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(1) {
47
+ animation: composer-mascot-energy-extra-dark 2.8s ease-in-out infinite;
48
+ }
49
+
50
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(2) {
51
+ animation: composer-mascot-energy-extra-mid 2.8s ease-in-out infinite;
52
+ }
53
+
54
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-body stop:nth-child(3) {
55
+ animation: composer-mascot-energy-extra-light 2.8s ease-in-out infinite;
56
+ }
57
+
58
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(1) {
59
+ animation: composer-mascot-energy-extra-mark-dark 2.8s ease-in-out infinite;
60
+ }
61
+
62
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(2),
63
+ [data-mascot-effort='extraHigh'] .dca-robot .dca-paint-mark stop:nth-child(3) {
64
+ animation: composer-mascot-energy-extra-mark-light 2.8s ease-in-out infinite;
65
+ }
66
+
67
+ [data-mascot-effort='extraHigh'] .dca-robot {
68
+ filter: drop-shadow(0 0 7px color-mix(in srgb,
69
+ oklch(from var(--mascot-energy-accent)
70
+ clamp(0.28, calc(l - 0.0456), 0.96)
71
+ clamp(0, calc(c * 1.231), 0.3)
72
+ calc(h + 27.55)) 36%, transparent));
73
+ }
74
+
75
+ [data-mascot-context='max'] .dca-robot {
76
+ animation: composer-mascot-max-overdrive-edge 3.8s ease-in-out infinite;
77
+ will-change: filter;
78
+ }
79
+
80
+ [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(1) {
81
+ animation: composer-mascot-max-coat-dark 3.8s ease-in-out infinite;
82
+ }
83
+
84
+ [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(2) {
85
+ animation: composer-mascot-max-coat-mid 3.8s ease-in-out infinite;
86
+ }
87
+
88
+ [data-mascot-context='max'] .dca-robot .dca-paint-body stop:nth-child(3) {
89
+ animation: composer-mascot-max-coat-light 3.8s ease-in-out infinite;
90
+ }
91
+
92
+ [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(1) {
93
+ animation: composer-mascot-max-coat-mark-dark 3.8s ease-in-out infinite;
94
+ }
95
+
96
+ [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(2),
97
+ [data-mascot-context='max'] .dca-robot .dca-paint-mark stop:nth-child(3) {
98
+ animation: composer-mascot-max-coat-mark-light 3.8s ease-in-out infinite;
99
+ }
@@ -1,20 +1,20 @@
1
- @keyframes composer-mascot-nod {
2
- 0%, 100% { transform: translateY(0); }
3
- 40% { transform: translateY(2.5px) scale(1.015, 0.985); }
4
- }
5
-
6
- .composer-mascot-nod {
7
- animation: composer-mascot-nod 140ms ease-out;
8
- transform-origin: bottom center;
9
- }
10
-
11
- @keyframes composer-mascot-think-sway {
12
- 0%, 100% { transform: rotate(-2.2deg); }
13
- 50% { transform: rotate(2.2deg); }
14
- }
15
-
16
- .composer-mascot-think {
17
- animation: composer-mascot-think-sway 2.6s ease-in-out infinite;
18
- transform-origin: bottom center;
19
- will-change: transform;
20
- }
1
+ @keyframes composer-mascot-nod {
2
+ 0%, 100% { transform: translateY(0); }
3
+ 40% { transform: translateY(2.5px) scale(1.015, 0.985); }
4
+ }
5
+
6
+ .composer-mascot-nod {
7
+ animation: composer-mascot-nod 140ms ease-out;
8
+ transform-origin: bottom center;
9
+ }
10
+
11
+ @keyframes composer-mascot-think-sway {
12
+ 0%, 100% { transform: rotate(-2.2deg); }
13
+ 50% { transform: rotate(2.2deg); }
14
+ }
15
+
16
+ .composer-mascot-think {
17
+ animation: composer-mascot-think-sway 2.6s ease-in-out infinite;
18
+ transform-origin: bottom center;
19
+ will-change: transform;
20
+ }
@@ -1,188 +1,188 @@
1
- @keyframes composer-mascot-cheer {
2
- 0% {
3
- transform: translateY(0) scale(1, 1);
4
- }
5
- 12% {
6
- transform: translateY(2px) scale(1.08, 0.9);
7
- }
8
- 30% {
9
- transform: translateY(-13px) scale(0.96, 1.06);
10
- }
11
- 46% {
12
- transform: translateY(0) scale(1.05, 0.94);
13
- }
14
- 60% {
15
- transform: translateY(-8px) scale(0.98, 1.03);
16
- }
17
- 74% {
18
- transform: translateY(0) scale(1.02, 0.98);
19
- }
20
- 100% {
21
- transform: translateY(0) scale(1, 1);
22
- }
23
- }
24
-
25
- .composer-mascot-cheer {
26
- animation: composer-mascot-cheer 1s ease-out;
27
- transform-origin: bottom center;
28
- }
29
-
30
- .composer-mascot-sparkles {
31
- position: absolute;
32
- inset: 0;
33
- pointer-events: none;
34
- }
35
-
36
- .composer-mascot-sparkles i {
37
- position: absolute;
38
- left: 50%;
39
- top: 6%;
40
- width: 7px;
41
- height: 7px;
42
- background: var(--success);
43
- clip-path: polygon(50% 0, 64% 36%, 100% 50%, 64% 64%, 50% 100%, 36% 64%, 0 50%, 36% 36%);
44
- animation: composer-mascot-sparkle 900ms ease-out forwards;
45
- }
46
-
47
- @keyframes composer-mascot-sparkle {
48
- 0% {
49
- opacity: 0;
50
- transform: translate(0, 0) scale(0.4) rotate(0);
51
- }
52
- 18% {
53
- opacity: 1;
54
- }
55
- 100% {
56
- opacity: 0;
57
- transform: translate(var(--dx), var(--dy)) scale(1) rotate(160deg);
58
- }
59
- }
60
-
61
- @keyframes composer-mascot-shake {
62
- 0%,
63
- 100% {
64
- transform: translateX(0) rotate(0);
65
- }
66
- 18% {
67
- transform: translateX(-5px) rotate(-2.4deg);
68
- }
69
- 38% {
70
- transform: translateX(5px) rotate(2.4deg);
71
- }
72
- 58% {
73
- transform: translateX(-4px) rotate(-1.8deg);
74
- }
75
- 78% {
76
- transform: translateX(3px) rotate(1.2deg);
77
- }
78
- }
79
-
80
- .composer-mascot-shake {
81
- animation: composer-mascot-shake 520ms ease-in-out;
82
- transform-origin: bottom center;
83
- }
84
-
85
- @keyframes composer-mascot-eager-hop {
86
- 0%,
87
- 100% {
88
- transform: translateY(0) scale(1, 1);
89
- }
90
- 50% {
91
- transform: translateY(-4px) scale(0.99, 1.02);
92
- }
93
- }
94
-
95
- .composer-mascot-eager {
96
- animation: composer-mascot-eager-hop 460ms ease-in-out infinite;
97
- transform-origin: bottom center;
98
- }
99
-
100
- @keyframes composer-mascot-sleep-breathe {
101
- 0%,
102
- 100% {
103
- transform: scale(1);
104
- }
105
- 50% {
106
- transform: scale(1.05, 1.06);
107
- }
108
- }
109
-
110
- .composer-mascot-sleep-breathe {
111
- animation: composer-mascot-sleep-breathe 5.6s ease-in-out infinite;
112
- transform-origin: bottom center;
113
- }
114
-
115
- .composer-mascot-zzz {
116
- position: absolute;
117
- inset: 0;
118
- pointer-events: none;
119
- }
120
-
121
- .composer-mascot-zzz span {
122
- position: absolute;
123
- right: -2px;
124
- top: 2px;
125
- font-family: Georgia, serif;
126
- font-size: 13px;
127
- font-weight: 700;
128
- color: var(--text-dimmed);
129
- opacity: 0;
130
- animation: composer-mascot-zzz 2.8s ease-out infinite;
131
- }
132
-
133
- .composer-mascot-zzz span:nth-child(2) {
134
- animation-delay: 0.9s;
135
- right: 2px;
136
- }
137
-
138
- .composer-mascot-zzz span:nth-child(3) {
139
- animation-delay: 1.8s;
140
- right: 6px;
141
- }
142
-
143
- @keyframes composer-mascot-zzz {
144
- 0% {
145
- opacity: 0;
146
- transform: translate(0, 0) scale(0.7);
147
- }
148
- 25% {
149
- opacity: 0.9;
150
- }
151
- 100% {
152
- opacity: 0;
153
- transform: translate(13px, -26px) scale(1.15);
154
- }
155
- }
156
-
157
- @keyframes composer-mascot-startle {
158
- 0% {
159
- transform: translateY(0) scale(1);
160
- }
161
- 30% {
162
- transform: translateY(-7px) scale(1.1, 0.96);
163
- }
164
- 60% {
165
- transform: translateY(0) scale(0.97, 1.03);
166
- }
167
- 100% {
168
- transform: translateY(0) scale(1);
169
- }
170
- }
171
-
172
- .composer-mascot-startle {
173
- animation: composer-mascot-startle 320ms ease-out;
174
- transform-origin: bottom center;
175
- }
176
-
177
- @keyframes composer-mascot-push-lift {
178
- 0% { transform: translateY(0) scale(1); }
179
- 38% { transform: translateY(-7px) scale(0.98, 1.035); }
180
- 72% { transform: translateY(1px) scale(1.025, 0.975); }
181
- 88% { transform: translateY(-1px) scale(0.995, 1.01); }
182
- 100% { transform: translateY(0) scale(1); }
183
- }
184
-
185
- .composer-mascot-push-lift {
186
- animation: composer-mascot-push-lift 360ms cubic-bezier(0.22, 0.72, 0.24, 1);
187
- transform-origin: bottom center;
188
- }
1
+ @keyframes composer-mascot-cheer {
2
+ 0% {
3
+ transform: translateY(0) scale(1, 1);
4
+ }
5
+ 12% {
6
+ transform: translateY(2px) scale(1.08, 0.9);
7
+ }
8
+ 30% {
9
+ transform: translateY(-13px) scale(0.96, 1.06);
10
+ }
11
+ 46% {
12
+ transform: translateY(0) scale(1.05, 0.94);
13
+ }
14
+ 60% {
15
+ transform: translateY(-8px) scale(0.98, 1.03);
16
+ }
17
+ 74% {
18
+ transform: translateY(0) scale(1.02, 0.98);
19
+ }
20
+ 100% {
21
+ transform: translateY(0) scale(1, 1);
22
+ }
23
+ }
24
+
25
+ .composer-mascot-cheer {
26
+ animation: composer-mascot-cheer 1s ease-out;
27
+ transform-origin: bottom center;
28
+ }
29
+
30
+ .composer-mascot-sparkles {
31
+ position: absolute;
32
+ inset: 0;
33
+ pointer-events: none;
34
+ }
35
+
36
+ .composer-mascot-sparkles i {
37
+ position: absolute;
38
+ left: 50%;
39
+ top: 6%;
40
+ width: 7px;
41
+ height: 7px;
42
+ background: var(--dca-theme-success);
43
+ clip-path: polygon(50% 0, 64% 36%, 100% 50%, 64% 64%, 50% 100%, 36% 64%, 0 50%, 36% 36%);
44
+ animation: composer-mascot-sparkle 900ms ease-out forwards;
45
+ }
46
+
47
+ @keyframes composer-mascot-sparkle {
48
+ 0% {
49
+ opacity: 0;
50
+ transform: translate(0, 0) scale(0.4) rotate(0);
51
+ }
52
+ 18% {
53
+ opacity: 1;
54
+ }
55
+ 100% {
56
+ opacity: 0;
57
+ transform: translate(var(--dx), var(--dy)) scale(1) rotate(160deg);
58
+ }
59
+ }
60
+
61
+ @keyframes composer-mascot-shake {
62
+ 0%,
63
+ 100% {
64
+ transform: translateX(0) rotate(0);
65
+ }
66
+ 18% {
67
+ transform: translateX(-5px) rotate(-2.4deg);
68
+ }
69
+ 38% {
70
+ transform: translateX(5px) rotate(2.4deg);
71
+ }
72
+ 58% {
73
+ transform: translateX(-4px) rotate(-1.8deg);
74
+ }
75
+ 78% {
76
+ transform: translateX(3px) rotate(1.2deg);
77
+ }
78
+ }
79
+
80
+ .composer-mascot-shake {
81
+ animation: composer-mascot-shake 520ms ease-in-out;
82
+ transform-origin: bottom center;
83
+ }
84
+
85
+ @keyframes composer-mascot-eager-hop {
86
+ 0%,
87
+ 100% {
88
+ transform: translateY(0) scale(1, 1);
89
+ }
90
+ 50% {
91
+ transform: translateY(-4px) scale(0.99, 1.02);
92
+ }
93
+ }
94
+
95
+ .composer-mascot-eager {
96
+ animation: composer-mascot-eager-hop 460ms ease-in-out infinite;
97
+ transform-origin: bottom center;
98
+ }
99
+
100
+ @keyframes composer-mascot-sleep-breathe {
101
+ 0%,
102
+ 100% {
103
+ transform: scale(1);
104
+ }
105
+ 50% {
106
+ transform: scale(1.05, 1.06);
107
+ }
108
+ }
109
+
110
+ .composer-mascot-sleep-breathe {
111
+ animation: composer-mascot-sleep-breathe 5.6s ease-in-out infinite;
112
+ transform-origin: bottom center;
113
+ }
114
+
115
+ .composer-mascot-zzz {
116
+ position: absolute;
117
+ inset: 0;
118
+ pointer-events: none;
119
+ }
120
+
121
+ .composer-mascot-zzz span {
122
+ position: absolute;
123
+ right: -2px;
124
+ top: 2px;
125
+ font-family: Georgia, serif;
126
+ font-size: 13px;
127
+ font-weight: 700;
128
+ color: var(--dca-theme-dimmed);
129
+ opacity: 0;
130
+ animation: composer-mascot-zzz 2.8s ease-out infinite;
131
+ }
132
+
133
+ .composer-mascot-zzz span:nth-child(2) {
134
+ animation-delay: 0.9s;
135
+ right: 2px;
136
+ }
137
+
138
+ .composer-mascot-zzz span:nth-child(3) {
139
+ animation-delay: 1.8s;
140
+ right: 6px;
141
+ }
142
+
143
+ @keyframes composer-mascot-zzz {
144
+ 0% {
145
+ opacity: 0;
146
+ transform: translate(0, 0) scale(0.7);
147
+ }
148
+ 25% {
149
+ opacity: 0.9;
150
+ }
151
+ 100% {
152
+ opacity: 0;
153
+ transform: translate(13px, -26px) scale(1.15);
154
+ }
155
+ }
156
+
157
+ @keyframes composer-mascot-startle {
158
+ 0% {
159
+ transform: translateY(0) scale(1);
160
+ }
161
+ 30% {
162
+ transform: translateY(-7px) scale(1.1, 0.96);
163
+ }
164
+ 60% {
165
+ transform: translateY(0) scale(0.97, 1.03);
166
+ }
167
+ 100% {
168
+ transform: translateY(0) scale(1);
169
+ }
170
+ }
171
+
172
+ .composer-mascot-startle {
173
+ animation: composer-mascot-startle 320ms ease-out;
174
+ transform-origin: bottom center;
175
+ }
176
+
177
+ @keyframes composer-mascot-push-lift {
178
+ 0% { transform: translateY(0) scale(1); }
179
+ 38% { transform: translateY(-7px) scale(0.98, 1.035); }
180
+ 72% { transform: translateY(1px) scale(1.025, 0.975); }
181
+ 88% { transform: translateY(-1px) scale(0.995, 1.01); }
182
+ 100% { transform: translateY(0) scale(1); }
183
+ }
184
+
185
+ .composer-mascot-push-lift {
186
+ animation: composer-mascot-push-lift 360ms cubic-bezier(0.22, 0.72, 0.24, 1);
187
+ transform-origin: bottom center;
188
+ }