clawd-desktop 1.0.0

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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/assets/LICENSE-clawd +22 -0
  4. package/assets/gif/clawd-building.gif +0 -0
  5. package/assets/gif/clawd-carrying.gif +0 -0
  6. package/assets/gif/clawd-conducting.gif +0 -0
  7. package/assets/gif/clawd-debugger.gif +0 -0
  8. package/assets/gif/clawd-error.gif +0 -0
  9. package/assets/gif/clawd-happy.gif +0 -0
  10. package/assets/gif/clawd-idle-reading.gif +0 -0
  11. package/assets/gif/clawd-idle.gif +0 -0
  12. package/assets/gif/clawd-juggling.gif +0 -0
  13. package/assets/gif/clawd-notification.gif +0 -0
  14. package/assets/gif/clawd-react-annoyed.gif +0 -0
  15. package/assets/gif/clawd-react-double-jump.gif +0 -0
  16. package/assets/gif/clawd-sleeping.gif +0 -0
  17. package/assets/gif/clawd-sweeping.gif +0 -0
  18. package/assets/gif/clawd-thinking.gif +0 -0
  19. package/assets/gif/clawd-typing.gif +0 -0
  20. package/assets/svg/clawd-about-hero.svg +202 -0
  21. package/assets/svg/clawd-collapse-sleep.svg +247 -0
  22. package/assets/svg/clawd-error.svg +94 -0
  23. package/assets/svg/clawd-happy.svg +161 -0
  24. package/assets/svg/clawd-idle-collapse.svg +101 -0
  25. package/assets/svg/clawd-idle-doze.svg +72 -0
  26. package/assets/svg/clawd-idle-follow.svg +64 -0
  27. package/assets/svg/clawd-idle-living.svg +196 -0
  28. package/assets/svg/clawd-idle-look.svg +115 -0
  29. package/assets/svg/clawd-idle-reading.svg +201 -0
  30. package/assets/svg/clawd-idle-yawn.svg +158 -0
  31. package/assets/svg/clawd-mini-alert.svg +129 -0
  32. package/assets/svg/clawd-mini-crabwalk.svg +76 -0
  33. package/assets/svg/clawd-mini-enter-sleep.svg +65 -0
  34. package/assets/svg/clawd-mini-enter.svg +115 -0
  35. package/assets/svg/clawd-mini-happy.svg +124 -0
  36. package/assets/svg/clawd-mini-idle.svg +83 -0
  37. package/assets/svg/clawd-mini-peek.svg +82 -0
  38. package/assets/svg/clawd-mini-sleep.svg +112 -0
  39. package/assets/svg/clawd-mini-typing.svg +153 -0
  40. package/assets/svg/clawd-notification.svg +149 -0
  41. package/assets/svg/clawd-react-annoyed.svg +167 -0
  42. package/assets/svg/clawd-react-double-jump.svg +229 -0
  43. package/assets/svg/clawd-react-double.svg +108 -0
  44. package/assets/svg/clawd-react-drag.svg +102 -0
  45. package/assets/svg/clawd-react-left.svg +102 -0
  46. package/assets/svg/clawd-react-right.svg +102 -0
  47. package/assets/svg/clawd-sleeping.svg +118 -0
  48. package/assets/svg/clawd-static-base.svg +21 -0
  49. package/assets/svg/clawd-wake.svg +277 -0
  50. package/assets/svg/clawd-working-building.svg +329 -0
  51. package/assets/svg/clawd-working-carrying.svg +178 -0
  52. package/assets/svg/clawd-working-conducting.svg +220 -0
  53. package/assets/svg/clawd-working-debugger.svg +245 -0
  54. package/assets/svg/clawd-working-juggling.svg +183 -0
  55. package/assets/svg/clawd-working-sweeping.svg +248 -0
  56. package/assets/svg/clawd-working-thinking.svg +196 -0
  57. package/assets/svg/clawd-working-typing.svg +273 -0
  58. package/assets/svg/clawd-working-ultrathink.svg +166 -0
  59. package/assets/svg/clawd-working-wizard.svg +98 -0
  60. package/assets/tray-icon.ico +0 -0
  61. package/bin/claude-pet.js +6 -0
  62. package/main.js +86 -0
  63. package/package.json +38 -0
  64. package/preload.js +6 -0
  65. package/renderer/avatar.js +55 -0
  66. package/renderer/index.html +14 -0
  67. package/renderer/motion.js +24 -0
  68. package/renderer/style.css +104 -0
@@ -0,0 +1,112 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500"
2
+ shape-rendering="crispEdges">
3
+ <defs>
4
+ <style>
5
+ /* Slower breathing for sleepy feel */
6
+ .breathe-anim {
7
+ transform-origin: 7.5px 13px;
8
+ animation: breathe 5s infinite ease-in-out;
9
+ }
10
+
11
+ /* Very slow, barely noticeable arm drift */
12
+ .arm-wobble {
13
+ transform-box: fill-box;
14
+ transform-origin: 100% 0%;
15
+ animation: arm-drift 50s infinite ease-in-out;
16
+ }
17
+
18
+ /* Zzz particles (same style as clawd-sleeping.svg) */
19
+ .z-particle { opacity: 0; }
20
+ .z1 { animation: float-1 6s infinite ease-in-out 0s; }
21
+ .z2 { animation: float-2 6s infinite ease-in-out 2s; }
22
+ .z3 { animation: float-3 6s infinite ease-in-out 4s; }
23
+
24
+ @keyframes breathe {
25
+ 0%, 100% { transform: scale(1, 1) translate(0, 0); }
26
+ 50% { transform: scale(1.015, 0.985) translate(0, 0.3px); }
27
+ }
28
+
29
+ @keyframes arm-drift {
30
+ 0%, 94%, 100% { transform: rotate(0deg); }
31
+ 96% { transform: rotate(3deg); }
32
+ 98% { transform: rotate(-1deg); }
33
+ }
34
+
35
+ /* Zzz floats left and up (away from screen edge) */
36
+ @keyframes float-1 {
37
+ 0% { transform: translate(-2px, 6px) scale(0.4); opacity: 0; }
38
+ 10% { opacity: 1; }
39
+ 30% { transform: translate(-5px, 3px) scale(0.6); }
40
+ 50% { transform: translate(-3px, 0px) scale(0.8); }
41
+ 70% { transform: translate(-6px, -3px) scale(1.0); }
42
+ 90% { opacity: 0.8; }
43
+ 100% { transform: translate(-4px, -6px) scale(1.1); opacity: 0; }
44
+ }
45
+
46
+ @keyframes float-2 {
47
+ 0% { transform: translate(-3px, 7px) scale(0.3); opacity: 0; }
48
+ 10% { opacity: 1; }
49
+ 30% { transform: translate(-6px, 4px) scale(0.5); }
50
+ 50% { transform: translate(-4px, 1px) scale(0.7); }
51
+ 70% { transform: translate(-7px, -2px) scale(0.9); }
52
+ 90% { opacity: 0.8; }
53
+ 100% { transform: translate(-5px, -5px) scale(1.0); opacity: 0; }
54
+ }
55
+
56
+ @keyframes float-3 {
57
+ 0% { transform: translate(-1px, 5px) scale(0.5); opacity: 0; }
58
+ 10% { opacity: 1; }
59
+ 30% { transform: translate(-4px, 2px) scale(0.7); }
60
+ 50% { transform: translate(-2px, -1px) scale(0.9); }
61
+ 70% { transform: translate(-5px, -4px) scale(1.1); }
62
+ 90% { opacity: 0.8; }
63
+ 100% { transform: translate(-3px, -7px) scale(1.2); opacity: 0; }
64
+ }
65
+ </style>
66
+
67
+ <g id="pixel-z">
68
+ <rect x="0" y="0" width="4" height="1"/>
69
+ <rect x="2" y="1" width="1" height="1"/>
70
+ <rect x="1" y="2" width="1" height="1"/>
71
+ <rect x="0" y="3" width="4" height="1"/>
72
+ </g>
73
+
74
+ <g id="pixel-z-small">
75
+ <rect x="0" y="0" width="3" height="1"/>
76
+ <rect x="1" y="1" width="1" height="1"/>
77
+ <rect x="0" y="2" width="3" height="1"/>
78
+ </g>
79
+ </defs>
80
+
81
+ <!-- Zzz particles -->
82
+ <use href="#pixel-z" class="z-particle z1" fill="#90A4AE"/>
83
+ <use href="#pixel-z-small" class="z-particle z2" fill="#B0BEC5"/>
84
+ <use href="#pixel-z" class="z-particle z3" fill="#CFD8DC"/>
85
+
86
+ <g transform="rotate(-12, 7.5, 15)">
87
+ <g fill="#DE886D">
88
+ <rect x="3" y="11" width="1" height="4"/>
89
+ <rect x="5" y="11" width="1" height="4"/>
90
+ <rect x="9" y="11" width="1" height="4"/>
91
+ <rect x="11" y="11" width="1" height="4"/>
92
+ </g>
93
+
94
+ <g id="body-js">
95
+ <g class="breathe-anim">
96
+ <rect x="2" y="6" width="11" height="7" fill="#DE886D"/>
97
+
98
+ <g class="arm-wobble">
99
+ <rect x="-1.5" y="9" width="4.5" height="2" fill="#DE886D"/>
100
+ </g>
101
+
102
+ <rect x="13" y="9" width="2" height="2" fill="#DE886D"/>
103
+
104
+ <!-- Eyes closed — wide dashes like sleeping pose -->
105
+ <g id="eyes-js" fill="#000000">
106
+ <rect x="3.5" y="8.8" width="2" height="0.4"/>
107
+ <rect x="9.5" y="8.8" width="2" height="0.4"/>
108
+ </g>
109
+ </g>
110
+ </g>
111
+ </g>
112
+ </svg>
@@ -0,0 +1,153 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ .breathe-anim {
5
+ transform-origin: 7.5px 13px;
6
+ animation: breathe 3.2s infinite ease-in-out;
7
+ }
8
+
9
+ .eyes-read {
10
+ animation: read-code 1.2s infinite;
11
+ }
12
+
13
+ #eyes-js {
14
+ transition: transform 0.2s ease-out;
15
+ }
16
+
17
+ .arm-l-type {
18
+ transform-origin: 3px 10px;
19
+ animation: type-l 0.15s infinite ease-in-out;
20
+ }
21
+ .arm-r-type {
22
+ transform-origin: 12px 10px;
23
+ animation: type-r 0.12s infinite ease-in-out;
24
+ }
25
+
26
+ /* Floating data packets */
27
+ .data-bit {
28
+ opacity: 0;
29
+ animation: float-data 1s infinite linear;
30
+ }
31
+ .d1 { animation-delay: 0.0s; transform-origin: -2px 10px; }
32
+ .d2 { animation-delay: 0.3s; transform-origin: 5px 12px; }
33
+ .d3 { animation-delay: 0.6s; transform-origin: 12px 11px; }
34
+ .d4 { animation-delay: 0.8s; transform-origin: 17px 9px; }
35
+ .d5 { animation-delay: 0.1s; transform-origin: 8px 10px; }
36
+ .d6 { animation-delay: 0.4s; transform-origin: 0px 11px; }
37
+ .d7 { animation-delay: 0.7s; transform-origin: 15px 12px; }
38
+
39
+ @keyframes breathe {
40
+ 0%, 100% { transform: scale(1, 1) translate(0, 0); }
41
+ 50% { transform: scale(1.02, 0.98) translate(0, 0.5px); }
42
+ }
43
+
44
+ @keyframes read-code {
45
+ 0%, 14% { transform: translate(-2px, 0); }
46
+ 15%, 29% { transform: translate(-1.5px, 0); }
47
+ 30%, 44% { transform: translate(-1px, 0); }
48
+ 45%, 59% { transform: translate(-0.5px, 0); }
49
+ 60%, 84% { transform: translate(0px, 0); }
50
+ 85%, 100% { transform: translate(-2px, 0); }
51
+ }
52
+
53
+ @keyframes type-l {
54
+ 0% { transform: rotate(-10deg); }
55
+ 25% { transform: rotate(15deg); }
56
+ 50% { transform: rotate(-5deg); }
57
+ 75% { transform: rotate(10deg); }
58
+ 100% { transform: rotate(-10deg); }
59
+ }
60
+
61
+ @keyframes type-r {
62
+ 0% { transform: rotate(10deg); }
63
+ 25% { transform: rotate(-15deg); }
64
+ 50% { transform: rotate(5deg); }
65
+ 75% { transform: rotate(-10deg); }
66
+ 100% { transform: rotate(10deg); }
67
+ }
68
+
69
+ .logo-glow {
70
+ animation: logo-pulse 1.5s infinite alternate ease-in-out;
71
+ }
72
+
73
+ @keyframes logo-pulse {
74
+ 0% { opacity: 0.4; }
75
+ 100% { opacity: 1; }
76
+ }
77
+
78
+ /* Packets float up and fade */
79
+ @keyframes float-data {
80
+ 0% { transform: translateY(0) scale(0.5); opacity: 0; }
81
+ 20% { opacity: 0.8; }
82
+ 100% { transform: translateY(-15px) scale(1.2); opacity: 0; }
83
+ }
84
+ </style>
85
+
86
+ <!-- A small square to represent data/code -->
87
+ <g id="pixel-packet">
88
+ <rect x="0" y="0" width="1.5" height="1.5" />
89
+ </g>
90
+ </defs>
91
+
92
+ <!-- No shadow (against screen edge, no ground plane) -->
93
+
94
+ <!-- Entire character leaning: rotate -12° around feet base (7.5, 15) -->
95
+ <!-- Negative = counterclockwise = head tilts left toward screen = peeking pose -->
96
+ <g transform="rotate(-12, 7.5, 15)">
97
+
98
+ <!-- Legs (inside rotation group so they tilt with the body) -->
99
+ <g fill="#DE886D">
100
+ <rect x="3" y="11" width="1" height="4"/>
101
+ <rect x="5" y="11" width="1" height="4"/>
102
+ <rect x="9" y="11" width="1" height="4"/>
103
+ <rect x="11" y="11" width="1" height="4"/>
104
+ </g>
105
+
106
+ <!-- Upper Body (JS body-shift preserved for compatibility) -->
107
+ <g id="body-js">
108
+ <g class="breathe-anim">
109
+ <!-- Torso -->
110
+ <rect x="2" y="6" width="11" height="7" fill="#DE886D"/>
111
+
112
+ <!-- Left Arm — typing -->
113
+ <g class="arm-l-type">
114
+ <rect x="0" y="9" width="3" height="2" fill="#DE886D"/>
115
+ </g>
116
+
117
+ <!-- Right Arm — typing -->
118
+ <g class="arm-r-type">
119
+ <rect x="12" y="9" width="3" height="2" fill="#DE886D"/>
120
+ </g>
121
+
122
+ <!-- Eyes: JS translate wrapper + CSS blink -->
123
+ <g id="eyes-js" fill="#000000">
124
+ <g class="eyes-read">
125
+ <rect x="4" y="8" width="1" height="2"/>
126
+ <rect x="10" y="8" width="1" height="2"/>
127
+ </g>
128
+ </g>
129
+ </g>
130
+ </g>
131
+
132
+ <!-- Pixel Laptop (inside rotation group so it leans with Clawd) -->
133
+ <g id="laptop" transform="translate(3, 11)">
134
+ <!-- Laptop Base -->
135
+ <rect x="-0.5" y="4" width="8" height="1" fill="#546E7A" rx="0.5"/>
136
+ <!-- Screen Back -->
137
+ <rect x="0" y="0" width="7" height="4.5" fill="#78909C" rx="0.5"/>
138
+ <!-- Glowing Logo -->
139
+ <circle cx="3.5" cy="2" r="1.2" fill="#40C4FF" opacity="0.2" class="logo-glow"/>
140
+ <rect x="3" y="1.5" width="1" height="1" fill="#FFFFFF" class="logo-glow"/>
141
+ </g>
142
+ </g>
143
+ <!-- Data Particles floating up from behind the laptop -->
144
+ <g class="data-particles" fill="#40C4FF">
145
+ <use href="#pixel-packet" class="data-bit d1" x="-2" y="12" />
146
+ <use href="#pixel-packet" class="data-bit d2" x="5" y="11" />
147
+ <use href="#pixel-packet" class="data-bit d3" x="12" y="13" />
148
+ <use href="#pixel-packet" class="data-bit d4" x="17" y="11" />
149
+ <use href="#pixel-packet" class="data-bit d5" x="8" y="10" />
150
+ <use href="#pixel-packet" class="data-bit d6" x="1" y="11" />
151
+ <use href="#pixel-packet" class="data-bit d7" x="15" y="12" />
152
+ </g>
153
+ </svg>
@@ -0,0 +1,149 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ /* 3.5s loop: startle + 4 decaying jumps */
5
+
6
+ .body-anim {
7
+ transform-origin: 7.5px 15px;
8
+ animation: body-jump 3.5s infinite ease-in-out;
9
+ }
10
+
11
+ .shadow-anim {
12
+ transform-origin: 7.5px 15.5px;
13
+ animation: shadow-pulse 3.5s infinite ease-in-out;
14
+ }
15
+
16
+ .eyes-look {
17
+ transform-origin: 7.5px 9px;
18
+ animation: eye-track 3.5s infinite ease-in-out;
19
+ }
20
+
21
+ .arm-l {
22
+ transform-origin: 1px 10px;
23
+ animation: arm-wave-l 3.5s infinite ease-in-out;
24
+ }
25
+ .arm-r {
26
+ transform-origin: 14px 10px;
27
+ animation: arm-wave-r 3.5s infinite ease-in-out;
28
+ }
29
+
30
+ .alert-pop {
31
+ transform-origin: 16px -1px;
32
+ animation: alert-flash 3.5s infinite ease-in-out;
33
+ opacity: 0;
34
+ }
35
+
36
+ /* --- Keyframes --- */
37
+
38
+ @keyframes body-jump {
39
+ 0% { transform: translate(0, 0) scale(1, 1); }
40
+ 3% { transform: translate(-1.5px, -1px) scale(1.03, 0.97); }
41
+ 10% { transform: translate(-1.5px, -1px) scale(1.03, 0.97); }
42
+ 15% { transform: translate(0, 1.5px) scale(1.05, 0.96); }
43
+ 20% { transform: translate(0, -10px) scale(0.96, 1.04); }
44
+ 25% { transform: translate(0, 1.5px) scale(1.05, 0.96); }
45
+ 30% { transform: translate(0, -8px) scale(0.97, 1.03); }
46
+ 35% { transform: translate(0, 1.2px) scale(1.04, 0.97); }
47
+ 40% { transform: translate(0, -5px) scale(0.98, 1.02); }
48
+ 45% { transform: translate(0, 1px) scale(1.03, 0.98); }
49
+ 50% { transform: translate(0, -3px) scale(0.99, 1.01); }
50
+ 55% { transform: translate(0, 0.5px) scale(1.01, 0.99); }
51
+ 62%, 100% { transform: translate(0, 0) scale(1, 1); }
52
+ }
53
+
54
+ @keyframes shadow-pulse {
55
+ 0% { transform: scale(1); opacity: 0.5; }
56
+ 3%, 10% { transform: translate(-1.5px, 0) scale(1); opacity: 0.5; }
57
+ 15% { transform: scale(1.1); opacity: 0.55; }
58
+ 20% { transform: scale(0.5); opacity: 0.12; }
59
+ 25% { transform: scale(1.12); opacity: 0.55; }
60
+ 30% { transform: scale(0.55); opacity: 0.15; }
61
+ 35% { transform: scale(1.1); opacity: 0.52; }
62
+ 40% { transform: scale(0.65); opacity: 0.2; }
63
+ 45% { transform: scale(1.06); opacity: 0.5; }
64
+ 50% { transform: scale(0.75); opacity: 0.3; }
65
+ 55% { transform: scale(1.03); opacity: 0.5; }
66
+ 62%, 100% { transform: scale(1); opacity: 0.5; }
67
+ }
68
+
69
+ @keyframes eye-track {
70
+ 0% { transform: translate(0, 0) scaleY(1); }
71
+ 3% { transform: translate(4px, 0) scaleY(0.3); }
72
+ 6% { transform: translate(4px, 0) scaleY(1); }
73
+ 10% { transform: translate(4px, 0) scaleY(1); }
74
+ 15%, 100% { transform: translate(0, 0) scaleY(1); }
75
+ }
76
+
77
+ @keyframes arm-wave-l {
78
+ 0% { transform: rotate(0deg); }
79
+ 3%, 10% { transform: rotate(25deg); }
80
+ 15% { transform: rotate(30deg); }
81
+ 20% { transform: rotate(155deg); }
82
+ 25% { transform: rotate(115deg); }
83
+ 30% { transform: rotate(140deg); }
84
+ 35% { transform: rotate(100deg); }
85
+ 40% { transform: rotate(115deg); }
86
+ 45% { transform: rotate(80deg); }
87
+ 50% { transform: rotate(80deg); }
88
+ 55% { transform: rotate(40deg); }
89
+ 62%, 100% { transform: rotate(0deg); }
90
+ }
91
+
92
+ @keyframes arm-wave-r {
93
+ 0% { transform: rotate(0deg); }
94
+ 3%, 10% { transform: rotate(-30deg); }
95
+ 15% { transform: rotate(-30deg); }
96
+ 20% { transform: rotate(-155deg); }
97
+ 25% { transform: rotate(-115deg); }
98
+ 30% { transform: rotate(-140deg); }
99
+ 35% { transform: rotate(-100deg); }
100
+ 40% { transform: rotate(-115deg); }
101
+ 45% { transform: rotate(-80deg); }
102
+ 50% { transform: rotate(-80deg); }
103
+ 55% { transform: rotate(-40deg); }
104
+ 62%, 100% { transform: rotate(0deg); }
105
+ }
106
+
107
+ @keyframes alert-flash {
108
+ 0% { opacity: 0; transform: scale(0.3); }
109
+ 3% { opacity: 1; transform: scale(1.3); }
110
+ 10% { opacity: 1; transform: scale(1); }
111
+ 50% { opacity: 1; transform: scale(1); }
112
+ 55% { opacity: 0.7; transform: scale(0.9); }
113
+ 62% { opacity: 0; transform: scale(0.6); }
114
+ 100% { opacity: 0; transform: scale(0.6); }
115
+ }
116
+ </style>
117
+ </defs>
118
+
119
+ <!-- Mirrored character -->
120
+ <g transform="translate(15, 0) scale(-1, 1)">
121
+ <rect class="shadow-anim" x="3" y="15" width="9" height="1" fill="#000000"/>
122
+
123
+ <g class="body-anim">
124
+ <g fill="#DE886D">
125
+ <rect x="3" y="13" width="1" height="2"/>
126
+ <rect x="5" y="13" width="1" height="2"/>
127
+ <rect x="9" y="13" width="1" height="2"/>
128
+ <rect x="11" y="13" width="1" height="2"/>
129
+ <rect x="2" y="6" width="11" height="7"/>
130
+ <g class="arm-l">
131
+ <rect x="0" y="9" width="2" height="2"/>
132
+ </g>
133
+ <g class="arm-r">
134
+ <rect x="13" y="9" width="2" height="2"/>
135
+ </g>
136
+ </g>
137
+ <g class="eyes-look" fill="#000000">
138
+ <rect x="4" y="8" width="1" height="2"/>
139
+ <rect x="10" y="8" width="1" height="2"/>
140
+ </g>
141
+ </g>
142
+ </g>
143
+
144
+ <!-- Exclamation mark (screen coords, not mirrored) -->
145
+ <g class="alert-pop" fill="#FF3D00">
146
+ <rect x="15" y="-6" width="2" height="5"/>
147
+ <rect x="15" y="0" width="2" height="2"/>
148
+ </g>
149
+ </svg>
@@ -0,0 +1,167 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ /* ===== 6s one-shot: annoyed, pause, resigned sigh, slow return =====
5
+ Phase 1 (0-6%, ~0.36s): Flinch
6
+ Phase 2 (6-18%, ~0.72s): Lean away + hand block + question mark
7
+ Phase 3 (18-35%, ~1.02s): Hold — stay annoyed, question mark fades
8
+ Phase 4 (35-55%, ~1.20s): Sigh — hand drops, body slumps, puff cloud
9
+ Phase 5 (55-70%, ~0.90s): Linger slumped — still tired
10
+ Phase 6 (70-90%, ~1.20s): Slow return
11
+ Phase 7 (90-100%, ~0.60s): Still
12
+ */
13
+
14
+ .body-react {
15
+ transform-origin: 7.5px 12px;
16
+ animation: body-react 6s 1 ease-in-out forwards;
17
+ }
18
+ .arm-l-react {
19
+ transform-origin: 2px 10px;
20
+ animation: arm-l-react 6s 1 ease-in-out forwards;
21
+ }
22
+ .eyes-react {
23
+ transform-origin: 7.5px 9px;
24
+ animation: eyes-react 6s 1 ease-in-out forwards;
25
+ }
26
+ .shadow-react {
27
+ transform-origin: 7.5px 15.5px;
28
+ animation: shadow-react 6s 1 ease-in-out forwards;
29
+ }
30
+ .qmark {
31
+ opacity: 0;
32
+ transform-origin: 8px -2px;
33
+ animation: qmark-pop 6s 1 ease-out forwards;
34
+ }
35
+ .sigh-cloud {
36
+ opacity: 0;
37
+ transform-origin: 16px 9px;
38
+ animation: sigh-puff 6s 1 ease-out forwards;
39
+ }
40
+
41
+ /* Body: flinch, lean, HOLD, sigh slump, LINGER, slow return */
42
+ @keyframes body-react {
43
+ 0% { transform: translate(0, 0) scale(1, 1); }
44
+ 4% { transform: translate(0, 1.5px) scale(1, 1); }
45
+ 6% { transform: translate(0, 1px) scale(1, 1); }
46
+ 14% { transform: translate(2px, 0) scale(1, 1); }
47
+ /* hold annoyed pose */
48
+ 35% { transform: translate(2px, 0) scale(1, 1); }
49
+ /* sigh: rise then slump */
50
+ 40% { transform: translate(1.5px, -0.5px) scale(1, 1.01); }
51
+ 46% { transform: translate(1px, 1px) scale(1.03, 0.97); }
52
+ 52% { transform: translate(0.5px, 0.5px) scale(1.01, 0.99); }
53
+ /* linger slumped */
54
+ 68% { transform: translate(0.3px, 0.3px) scale(1, 1); }
55
+ /* slow return */
56
+ 85% { transform: translate(0, 0) scale(1, 1); }
57
+ 100% { transform: translate(0, 0) scale(1, 1); }
58
+ }
59
+
60
+ /* Left arm: block, hold, resigned drop */
61
+ @keyframes arm-l-react {
62
+ 0% { transform: rotate(0deg); }
63
+ 6% { transform: rotate(0deg); }
64
+ 14% { transform: rotate(-50deg); }
65
+ /* hold block through pause */
66
+ 35% { transform: rotate(-45deg); }
67
+ /* resigned drop */
68
+ 43% { transform: rotate(-15deg); }
69
+ 48% { transform: rotate(0deg); }
70
+ 100% { transform: rotate(0deg); }
71
+ }
72
+
73
+ /* Eyes: squint, half-lid, HOLD, sigh-close, tired linger, recover */
74
+ @keyframes eyes-react {
75
+ 0% { transform: scaleY(1); }
76
+ 3% { transform: scaleY(0.2); }
77
+ 6% { transform: scaleY(0.6); }
78
+ 14% { transform: scaleY(0.5); }
79
+ /* hold half-lid through pause */
80
+ 35% { transform: scaleY(0.5); }
81
+ /* sigh: close then reopen tired */
82
+ 40% { transform: scaleY(0.1); }
83
+ 46% { transform: scaleY(0.6); }
84
+ /* linger tired */
85
+ 68% { transform: scaleY(0.6); }
86
+ /* blink, back to normal */
87
+ 74% { transform: scaleY(0.1); }
88
+ 78% { transform: scaleY(1); }
89
+ 100% { transform: scaleY(1); }
90
+ }
91
+
92
+ /* Question mark: pop during lean, fade during hold */
93
+ @keyframes qmark-pop {
94
+ 0%, 4% { opacity: 0; transform: translate(0, 4px) scale(0.5); }
95
+ 10% { opacity: 1; transform: translate(0, 0) scale(1.1); }
96
+ 14%, 26% { opacity: 1; transform: translate(0, 0) scale(1); }
97
+ 34% { opacity: 0; transform: translate(0, -3px) scale(1.1); }
98
+ 100% { opacity: 0; }
99
+ }
100
+
101
+ /* Sigh puff: breath cloud after hold */
102
+ @keyframes sigh-puff {
103
+ 0%, 37% { opacity: 0; transform: translate(0, 1px) scale(0.3); }
104
+ 43% { opacity: 0.6; transform: translate(0, 0) scale(0.8); }
105
+ 48% { opacity: 0.7; transform: translate(1px, 0) scale(1); }
106
+ 60% { opacity: 0; transform: translate(4px, -4px) scale(1.3); }
107
+ 100% { opacity: 0; }
108
+ }
109
+
110
+ /* Shadow */
111
+ @keyframes shadow-react {
112
+ 0% { transform: translate(0, 0) scaleX(1); opacity: 0.5; }
113
+ 4% { transform: translate(0, 0) scaleX(0.93); opacity: 0.45; }
114
+ 14% { transform: translate(1px, 0) scaleX(1); opacity: 0.5; }
115
+ 35% { transform: translate(1px, 0) scaleX(1); opacity: 0.5; }
116
+ 46% { transform: translate(0.5px, 0) scaleX(1.05); opacity: 0.55; }
117
+ 68% { transform: translate(0.3px, 0) scaleX(1.02); opacity: 0.52; }
118
+ 85% { transform: translate(0, 0) scaleX(1); opacity: 0.5; }
119
+ 100% { transform: translate(0, 0) scaleX(1); opacity: 0.5; }
120
+ }
121
+ </style>
122
+ </defs>
123
+
124
+ <!-- Ground Shadow -->
125
+ <rect class="shadow-react" x="3" y="15" width="9" height="1" fill="#000" opacity="0.5"/>
126
+
127
+ <!-- Static Legs -->
128
+ <g fill="#DE886D">
129
+ <rect x="3" y="11" width="1" height="4"/>
130
+ <rect x="5" y="11" width="1" height="4"/>
131
+ <rect x="9" y="11" width="1" height="4"/>
132
+ <rect x="11" y="11" width="1" height="4"/>
133
+ </g>
134
+
135
+ <!-- Animated Upper Body -->
136
+ <g class="body-react">
137
+ <!-- Torso -->
138
+ <g fill="#DE886D">
139
+ <rect x="2" y="6" width="11" height="7"/>
140
+ </g>
141
+ <!-- Arms -->
142
+ <g fill="#DE886D">
143
+ <g class="arm-l-react"><rect x="0" y="9" width="2" height="2"/></g>
144
+ <rect x="13" y="9" width="2" height="2"/>
145
+ </g>
146
+ <!-- Eyes -->
147
+ <g class="eyes-react" fill="#000">
148
+ <rect x="4" y="8" width="1" height="2"/>
149
+ <rect x="10" y="8" width="1" height="2"/>
150
+ </g>
151
+ <!-- Question mark -->
152
+ <g class="qmark" fill="#5C9CE6">
153
+ <rect x="7" y="-5" width="2" height="1"/>
154
+ <rect x="6" y="-4" width="1" height="1"/>
155
+ <rect x="9" y="-4" width="1" height="2"/>
156
+ <rect x="8" y="-2" width="1" height="1"/>
157
+ <rect x="7" y="-1" width="1" height="1"/>
158
+ <rect x="7" y="1" width="1" height="1"/>
159
+ </g>
160
+ <!-- Sigh puff cloud (right side of face) -->
161
+ <g class="sigh-cloud" fill="#FFF">
162
+ <rect x="14" y="9" width="2" height="1"/>
163
+ <rect x="15" y="8" width="2" height="1"/>
164
+ <rect x="16" y="7" width="2" height="1"/>
165
+ </g>
166
+ </g>
167
+ </svg>