File size: 3,932 Bytes
0ff9b81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
.orbit-wrapper {
  position: absolute;
  bottom: 30px;
  right: 30px;
  width: 120px;
  height: 120px;
  z-index: 2000;
  user-select: none;
}

/* Core orb */
.orbit {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, var(--orb-core, #fff), transparent 70%);
  box-shadow: 0 0 15px var(--orb-glow, #0ff), 0 0 30px var(--orb-glow, #0ff);
  transform: scale(var(--orb-scale, 1));
  opacity: var(--orb-opacity, 1);
  transition: all 0.3s ease, opacity 0.5s ease;
  cursor: grab;
  overflow: visible;
  animation: orbPulse 4s infinite ease-in-out;
  position: relative;
}

.orbit:hover {
  transform: scale(1.08); /* gentle grow */
  box-shadow: 0 0 25px var(--orb-glow, #0ff), 0 0 50px var(--orb-glow, #0ff);
  filter: brightness(1.1);
}

.orbit:active {
  cursor: grabbing;
}

/* Inner aura ripple */
.orbit::before {
  content: "";
  position: absolute;
  inset: -15%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--orb-glow, #0ff), transparent 70%);
  opacity: 0.5;
  animation: orbRipple 6s infinite linear;
}

/* Outer rotating energy */
.orbit::after {
  content: "";
  position: absolute;
  inset: -35%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, var(--orb-ray, cyan), transparent 50%, var(--orb-ray, cyan));
  animation: orbSpin 10s linear infinite;
  opacity: 0.3;
}

/* Resize handle */
.orbit-resize-handle {
  width: 14px;
  height: 14px;
  background: linear-gradient(135deg, #fff, #ddd);
  border: 2px solid #444;
  border-radius: 50%;
  position: absolute;
  bottom: -10px;
  right: -10px;
  cursor: nwse-resize;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
  transition: transform 0.2s ease;
}
.orbit-resize-handle:hover {
  transform: scale(1.2);
}

/* -------------------- */
/* State animations     */
/* -------------------- */

.orbit.listening {
  --orb-core: #00c6ff;
  --orb-glow: #00c6ff;
  --orb-ray: #0088ff;
  animation: listeningPulse 2s infinite ease-in-out;
}

.orbit.speaking {
  --orb-core: #ffdd55;
  --orb-glow: #ffbb00;
  --orb-ray: #ffaa00;
  animation: speakingRays 1.5s infinite alternate;
}

.orbit.thinking {
  --orb-core: #c77dff;
  --orb-glow: #a855f7;
  --orb-ray: #9333ea;
  animation: thinkingBreathe 3s infinite ease-in-out;
}

.orbit.error {
  --orb-core: #ff4d4d;
  --orb-glow: #ff1a1a;
  --orb-ray: #cc0000;
  animation: errorFlicker 0.5s infinite;
}

.orbit.idle {
  --orb-core: #fff;
  --orb-glow: #00f;
  --orb-ray: #f0f;
  background: conic-gradient(from 0deg, red, orange, yellow, lime, cyan, blue, violet, red);
  animation: rainbowFlow 6s linear infinite;
  background-size: 200% 200%;
}

/* -------------------- */
/* Keyframes            */
/* -------------------- */

@keyframes orbPulse {
  0%, 100% { transform: scale(var(--orb-scale, 1)); opacity: 0.9; }
  50% { transform: scale(calc(var(--orb-scale, 1) * 1.08)); opacity: 1; }
}

@keyframes orbRipple {
  0% { transform: scale(0.9); opacity: 0.3; }
  50% { transform: scale(1.1); opacity: 0.6; }
  100% { transform: scale(0.9); opacity: 0.3; }
}

@keyframes orbSpin {
  from { transform: rotate(0deg) scale(1); }
  to { transform: rotate(360deg) scale(1); }
}

@keyframes listeningPulse {
  0%, 100% { box-shadow: 0 0 12px #00c6ff, 0 0 25px #0088ff; }
  50% { box-shadow: 0 0 25px #00c6ff, 0 0 50px #0088ff; }
}

@keyframes speakingRays {
  0% { box-shadow: 0 0 15px #ffaa00, 0 0 30px #ffbb00; }
  100% { box-shadow: 0 0 30px #ffaa00, 0 0 60px #ffdd55; }
}

@keyframes thinkingBreathe {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(1.1); opacity: 1; }
}

@keyframes errorFlicker {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

@keyframes rainbowFlow {
  from { filter: hue-rotate(0deg); }
  to { filter: hue-rotate(360deg); }
}