/* The embedded Merlin voice orb (/voice#test). A living, layered orb driven entirely by
   two JS hooks: .morb[data-state=…] and the --level (0..1) audio var. All decorative
   layers are built from the existing .morb__stage / .morb__ring plus their pseudo-elements
   (no extra DOM), so merlin-orb.js is untouched. Brand tokens --violet/--magenta. */

.morb {
  --level: 0;
  --v: var(--violet, #7a2bf5);
  --m: var(--magenta, #c6379b);
  display: flex; flex-direction: column; align-items: center;
  gap: 1.4rem;
  padding: clamp(2rem, 5vw, 3.5rem) 1.5rem;
  border-radius: 28px;
  background: rgba(255, 255, 255, .55);
  border: 1px solid rgba(0, 0, 0, .06);
}

.morb__stage {
  position: relative;
  width: clamp(176px, 32vw, 244px);
  height: clamp(176px, 32vw, 244px);
  display: grid; place-items: center;
  isolation: isolate;
}

/* ── Outer halo: soft coloured glow that breathes and swells with the voice level ── */
.morb__stage::before {
  content: ""; position: absolute; inset: -24%; border-radius: 50%; z-index: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 50%,
              rgba(198, 55, 155, calc(.30 + var(--level) * .45)),
              rgba(122, 43, 245, .12) 46%, transparent 70%);
  filter: blur(16px);
  transform: scale(calc(.86 + var(--level) * .4));
  transition: transform .12s ease-out, background .3s ease;
  animation: morb-halo 5.5s ease-in-out infinite;
}
@keyframes morb-halo { 0%, 100% { opacity: .7; } 50% { opacity: 1; } }

/* ── The orb body: a glossy sphere (highlight + coloured depth + dark underside) ── */
.morb__ring {
  position: absolute; inset: 9%; border-radius: 50%; z-index: 1; overflow: hidden;
  background:
    radial-gradient(circle at 34% 27%, rgba(255,255,255,.92), rgba(255,255,255,0) 40%),
    radial-gradient(circle at 70% 74%, var(--m), rgba(198,55,155,0) 62%),
    radial-gradient(circle at 50% 52%, var(--v), #43188f 80%);
  box-shadow:
    inset 0 -14px 34px rgba(38, 8, 74, .5),
    inset 0 10px 24px rgba(255, 255, 255, .22),
    0 12px 34px rgba(122, 43, 245, calc(.22 + var(--level) * .3));
  transform: scale(calc(1 + var(--level) * .12));
  transition: transform .09s ease-out, box-shadow .12s ease-out;
  animation: morb-breathe 5.5s ease-in-out infinite;
}
/* breathe via brightness so it never fights the level-reactive transform */
@keyframes morb-breathe { 0%, 100% { filter: brightness(.97); } 50% { filter: brightness(1.06); } }

/* inner aurora — a slowly rotating luminous swirl inside the sphere */
.morb__ring::before {
  content: ""; position: absolute; inset: -30%; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 0deg,
              rgba(255,255,255,0), rgba(255,190,240,.6) 18%, rgba(122,43,245,0) 42%,
              rgba(255,120,210,.5) 66%, rgba(255,255,255,0) 88%);
  mix-blend-mode: screen;
  opacity: calc(.4 + var(--level) * .55);
  filter: blur(7px);
  animation: morb-swirl 9s linear infinite;
}
@keyframes morb-swirl { to { transform: rotate(360deg); } }

/* specular highlight — the glossy catch-light near the top-left */
.morb__ring::after {
  content: ""; position: absolute; left: 24%; top: 17%; width: 32%; height: 24%;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.9), rgba(255,255,255,0) 68%);
  filter: blur(2px); opacity: .82;
}

/* ── LISTENING: cooler, alert; concentric ripples signal "I'm receiving you" ── */
.morb[data-state="listening"] .morb__ring {
  background:
    radial-gradient(circle at 34% 27%, rgba(255,255,255,.95), rgba(255,255,255,0) 40%),
    radial-gradient(circle at 70% 74%, #4aa3ff, rgba(74,163,255,0) 62%),
    radial-gradient(circle at 50% 52%, var(--v), #3a2a9e 80%);
}
.morb[data-state="listening"] .morb__stage::after {
  content: ""; position: absolute; inset: 9%; border-radius: 50%; z-index: 0; pointer-events: none;
  border: 2px solid rgba(122, 43, 245, .5);
  animation: morb-ripple 1.8s ease-out infinite;
}
@keyframes morb-ripple {
  0%   { transform: scale(1);    opacity: .55; }
  100% { transform: scale(1.5);  opacity: 0; }
}

/* ── THINKING: no audio level — a faster, brighter aurora sweep carries the energy ── */
.morb[data-state="thinking"] .morb__ring::before {
  opacity: .9; filter: blur(5px);
  animation: morb-swirl 1.5s linear infinite;
}
.morb[data-state="thinking"] .morb__ring { animation: morb-think 1.6s ease-in-out infinite; }
@keyframes morb-think {
  0%, 100% { filter: brightness(1);    transform: scale(1); }
  50%      { filter: brightness(1.12); transform: scale(1.035); }
}

/* ── SPEAKING: warm, and the level var drives the pulse from the voice itself ── */
.morb[data-state="speaking"] .morb__ring::before { opacity: calc(.55 + var(--level) * .45); animation-duration: 5s; }

/* ── CONNECTING: gentle indeterminate shimmer ── */
.morb[data-state="connecting"] .morb__ring { animation: morb-think 2.2s ease-in-out infinite; }

/* ── Muted states: desaturate, go still ── */
.morb[data-state="busy"] .morb__ring,
.morb[data-state="error"] .morb__ring,
.morb[data-state="disconnected"] .morb__ring {
  background: radial-gradient(circle at 36% 30%, rgba(255,255,255,.5), rgba(255,255,255,0) 42%),
              radial-gradient(circle at 55% 60%, #9aa0ad, #6b7180 82%);
  box-shadow: inset 0 -10px 24px rgba(0,0,0,.28), 0 8px 22px rgba(0,0,0,.12);
  transform: none; animation: none;
}
.morb[data-state="busy"] .morb__ring::before,
.morb[data-state="error"] .morb__ring::before,
.morb[data-state="disconnected"] .morb__ring::before { opacity: 0; animation: none; }
.morb[data-state="busy"] .morb__stage::before,
.morb[data-state="error"] .morb__stage::before,
.morb[data-state="disconnected"] .morb__stage::before { background: none; }

/* ── The mic tap-target, floating over the orb ── */
.morb__mic {
  position: relative; z-index: 2;
  width: 66px; height: 66px; border-radius: 50%; border: none;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  color: var(--v);
  display: grid; place-items: center; cursor: pointer;
  box-shadow: 0 8px 22px rgba(40, 10, 80, .28), inset 0 0 0 1px rgba(255,255,255,.6);
  transition: transform .15s ease, background .2s ease, color .2s ease;
}
.morb__mic:hover { transform: scale(1.06); }
.morb__mic:active { transform: scale(.95); }
.morb__mic svg { width: 26px; height: 26px; }

.morb.is-on .morb__mic { color: var(--m); background: rgba(255,255,255,.94); }
.morb.is-on .morb__mic::after {
  content: ""; position: absolute; inset: -7px; border-radius: 50%;
  border: 2px solid var(--m); opacity: .45;
  animation: morb-ripple 1.6s ease-out infinite;
}

.morb__caption {
  min-height: 1.6em; max-width: 42ch; text-align: center;
  font-size: .98rem; color: var(--fg-mid, #4b4f5c);
  transition: color .3s ease;
}
.morb[data-state="error"] .morb__caption,
.morb[data-state="busy"] .morb__caption { color: #b23a5b; }

.morb__langs { display: flex; gap: .5rem; flex-wrap: wrap; justify-content: center; }
.morb__langs button {
  padding: .45rem 1rem; border-radius: 999px;
  border: 1px solid rgba(0, 0, 0, .12); background: transparent;
  font-size: .85rem; cursor: pointer; color: inherit; transition: all .15s ease;
}
.morb__langs button:hover { border-color: var(--v); color: var(--v); }
.morb__langs button[aria-pressed="true"] {
  background: linear-gradient(135deg, var(--v), var(--m));
  border-color: transparent; color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .morb__ring, .morb__ring::before, .morb__stage::before, .morb__stage::after,
  .morb.is-on .morb__mic::after { animation: none !important; transition: none; }
}
