Spaces:
Sleeping
Sleeping
| .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); } | |
| } | |