/* The Metrics Lab lab-tech agent.
   A single SVG whose parts animate independently, driven by a `data-state`
   attribute on the root. Every transform-origin is set explicitly because
   SVG defaults to the viewBox origin, not the element's own box. */

.agent-stage {
  position: relative;
  display: grid;
  place-items: center;
  padding: 0.5rem 0 0;
  isolation: isolate;
}

.ml-agent {
  width: 100%;
  max-width: 260px;
  height: auto;
  overflow: visible;
}

/* ---- Ambient idle: the whole figure breathes and sways ---- */
.agent-bob {
  transform-origin: 120px 250px;
  animation: agent-sway 6s ease-in-out infinite;
}

@keyframes agent-sway {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  25%      { transform: translateY(-2.5px) rotate(-0.7deg); }
  75%      { transform: translateY(-1.5px) rotate(0.7deg); }
}

.agent-torso {
  transform-origin: 120px 200px;
  animation: agent-breathe 4s ease-in-out infinite;
}

@keyframes agent-breathe {
  0%, 100% { transform: scale(1, 1); }
  50%      { transform: scale(1.015, 1.025); }
}

/* ---- Head: a slower counter-sway reads as a living neck ---- */
.agent-head {
  transform-origin: 120px 130px;
  animation: agent-head-tilt 7s ease-in-out infinite;
}

@keyframes agent-head-tilt {
  0%, 100% { transform: rotate(0deg); }
  30%      { transform: rotate(1.6deg); }
  65%      { transform: rotate(-1.4deg); }
}

/* ---- Blink: driven by JS so the interval can be irregular ---- */
.agent-eye {
  transform-origin: center;
  transform-box: fill-box;
  transition: transform 90ms ease;
}

.ml-agent.is-blinking .agent-eye {
  transform: scaleY(0.08);
}

.agent-mouth {
  transform-origin: 120px 166px;
}

/* A quiet smile shift makes the face feel reactive without pretending to
   lip-sync audio the bot cannot hear locally in this browser. */
.ml-agent[data-state="listening"] .agent-mouth {
  animation: mouth-listen 2.8s ease-in-out infinite;
}

@keyframes mouth-listen {
  0%, 100% { transform: scaleX(1); }
  50% { transform: scaleX(0.82) translateY(-1px); }
}

/* The goggle scan is active only while joining/thinking. */
.visor-scan {
  transform-origin: 120px 128px;
}

.ml-agent[data-state="joining"] .visor-scan,
.ml-agent[data-state="thinking"] .visor-scan {
  animation: visor-scan 1.65s ease-in-out infinite;
}

@keyframes visor-scan {
  0%   { opacity: 0; transform: translateY(0); }
  15%  { opacity: .9; }
  85%  { opacity: .65; }
  100% { opacity: 0; transform: translateY(29px); }
}

/* ---- Flask bubbles ---- */
.bubble {
  transform-box: fill-box;
  transform-origin: center;
  animation: bubble-rise var(--dur, 2.6s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
  opacity: 0;
}

@keyframes bubble-rise {
  0%       { opacity: 0; transform: translateY(0) scale(0.5); }
  18%      { opacity: 0.9; }
  75%      { opacity: 0.7; }
  100%     { opacity: 0; transform: translateY(-16px) scale(1.15); }
}

.agent-flask {
  transform-origin: 187px 218px;
  animation: flask-steady 4.8s ease-in-out infinite;
}

@keyframes flask-steady {
  0%, 100% { transform: rotate(0); }
  35% { transform: rotate(1.8deg); }
  70% { transform: rotate(-1.2deg); }
}

.ml-agent[data-state="joining"] .agent-flask,
.ml-agent[data-state="thinking"] .agent-flask {
  animation: flask-analyze 1.3s ease-in-out infinite;
}

@keyframes flask-analyze {
  0%, 100% { transform: rotate(-3deg) translateY(0); }
  50% { transform: rotate(3deg) translateY(-2px); }
}

/* ---- Status halo behind the figure ---- */
.agent-halo {
  transform-origin: 120px 150px;
  opacity: 0;
  transition: opacity 0.4s ease, stroke 0.4s ease;
}

/* ---- Listening rings: concentric, audio-suggestive ---- */
.listen-ring {
  transform-origin: 120px 150px;
  opacity: 0;
  stroke: var(--ml-mint);
}

/* =========================================================
   STATES
   ========================================================= */

/* IDLE - calm, waiting */
.ml-agent[data-state="idle"] .agent-halo {
  opacity: 0.35;
  stroke: var(--ml-blue);
}

/* JOINING - leaning in, amber urgency, faster bubbles */
.ml-agent[data-state="joining"] .agent-halo {
  opacity: 0.8;
  stroke: var(--ml-amber);
  animation: halo-throb 1.1s ease-in-out infinite;
}

.ml-agent[data-state="joining"] .agent-bob {
  animation-duration: 2.4s;
}

.ml-agent[data-state="joining"] .bubble {
  animation-duration: 1.1s;
}

@keyframes halo-throb {
  0%, 100% { transform: scale(1);    opacity: 0.75; }
  50%      { transform: scale(1.05); opacity: 0.3; }
}

/* LISTENING - live in the room, mint rings radiate */
.ml-agent[data-state="listening"] .agent-halo {
  opacity: 0.5;
  stroke: var(--ml-mint);
}

.ml-agent[data-state="listening"] .listen-ring {
  animation: ring-out 2.4s ease-out infinite;
}

.ml-agent[data-state="listening"] .listen-ring:nth-of-type(2) { animation-delay: 0.8s; }
.ml-agent[data-state="listening"] .listen-ring:nth-of-type(3) { animation-delay: 1.6s; }

@keyframes ring-out {
  0%   { opacity: 0.55; transform: scale(0.82); }
  100% { opacity: 0;    transform: scale(1.35); }
}

/* THINKING - summarizing; the flask does the work */
.ml-agent[data-state="thinking"] .agent-halo {
  opacity: 0.6;
  stroke: var(--ml-blue);
  animation: halo-throb 2s ease-in-out infinite;
}

.ml-agent[data-state="thinking"] .bubble {
  animation-duration: 0.8s;
}

.ml-agent[data-state="thinking"] .agent-head {
  animation-duration: 3s;
}

.ml-agent[data-state="thinking"] {
  filter: drop-shadow(0 0 10px rgb(55 144 228 / .22));
}

/* OFFLINE - asleep, drained of colour */
.ml-agent[data-state="offline"] {
  filter: grayscale(0.85) brightness(0.75);
}

.ml-agent[data-state="offline"] .agent-eye {
  transform: scaleY(0.08);
}

.ml-agent[data-state="offline"] .agent-bob,
.ml-agent[data-state="offline"] .agent-torso,
.ml-agent[data-state="offline"] .agent-head {
  animation-duration: 9s;
}

.ml-agent[data-state="offline"] .bubble {
  animation: none;
  opacity: 0;
}

/* ---- Data particles orbit outside the SVG ---- */
.data-orbit {
  position: absolute;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid rgb(55 144 228 / .38);
  background: rgb(10 15 31 / .88);
  color: var(--ml-mint);
  box-shadow: 0 0 18px rgb(55 144 228 / .16);
  font-family: var(--ml-font-display);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .06em;
  animation: data-float 4.4s ease-in-out infinite;
}

.orbit-one { left: 8%; top: 24%; }
.orbit-two { right: 7%; top: 18%; animation-delay: -1.4s; color: var(--ml-amber); }
.orbit-three { right: 5%; bottom: 20%; animation-delay: -2.8s; }

@keyframes data-float {
  0%, 100% { transform: translateY(0) rotate(0); }
  50% { transform: translateY(-8px) rotate(4deg); }
}

.agent-stage:has(.ml-agent[data-state="offline"]) .data-orbit {
  opacity: .25;
  animation-play-state: paused;
}

/* ---- Caption under the figure ---- */
.agent-caption {
  text-align: center;
  margin-top: 0.35rem;
}

.agent-caption .line1 {
  font-family: var(--ml-font-display);
  font-weight: 700;
  font-size: 17px;
}

.agent-caption .line2 {
  color: var(--ml-text-dim);
  font-size: 13px;
  min-height: 1.2em;
}

@media (prefers-reduced-motion: reduce) {
  .data-orbit,
  .agent-flask,
  .visor-scan {
    animation: none !important;
  }
}
