Princeaka's picture
Upload 44 files
0ff9b81 verified
.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); }
}