:root {
  --mic: 0;

  --meter-mic: 0;
  --meter-peak: 0;
  --meter-velocity: 0;

  --look-x: 0;
  --look-y: 0;

  --state-hue: 176;
  --state-hue-2: 198;
  --state-hot: 18;
  --state-cool: 205;

  --orb-size: clamp(172px, 24vmin, 242px);
  --orb-scale: calc(1 + var(--mic) * 0.12);

  --green: rgba(48, 255, 174, 0.44);
  --cyan: rgba(74, 230, 255, 0.58);
  --purple: rgba(178, 76, 255, 0.46);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
  color: white;
  font-family:
    Inter,
    ui-sans-serif,
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Arial,
    sans-serif;
}

body {
  position: relative;
  isolation: isolate;
}

canvas {
  position: fixed;
  inset: 0;
  display: block;
  z-index: 1;
}

/* Subtle grain */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 7;
  pointer-events: none;
  opacity: 0.07;
  mix-blend-mode: screen;

  background-image:
    radial-gradient(circle at 20% 30%, rgba(255,255,255,0.5) 0 0.7px, transparent 0.8px),
    radial-gradient(circle at 80% 70%, rgba(255,255,255,0.34) 0 0.6px, transparent 0.7px);

  background-size: 42px 42px, 57px 57px;
  background-position: 0 0, 17px 23px;
}

/* ======================================================
   Assistant stage
====================================================== */

.assistant-stage {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 3;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.css-orb-wrap {
  position: absolute;
  left: 50%;
  top: 50%;

  width: var(--orb-size);
  height: var(--orb-size);

  transform:
    translate(-50%, -50%)
    translate(
      calc(var(--look-x) * 18px),
      calc(var(--look-y) * 14px)
    )
    scale(var(--orb-scale));

  transform-origin: center;
  pointer-events: none;

  transition: transform 90ms ease;
  animation: orbFloat 4.8s ease-in-out infinite;
}

/* Listening sound rings */
.css-orb-wrap::before,
.css-orb-wrap::after {
  content: "";
  position: absolute;
  inset: -14%;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  z-index: -1;

  border: 1px solid hsl(var(--state-hue-2) 100% 72% / 0);
  box-shadow:
    0 0 0 rgba(0,0,0,0),
    0 0 42px hsl(var(--state-hue-2) 100% 68% / 0);
}

body[data-state="listening"] .css-orb-wrap::before {
  opacity: calc(0.25 + var(--mic) * 0.55);
  border-color: hsl(var(--state-hue-2) 100% 72% / calc(0.22 + var(--mic) * 0.32));
  box-shadow:
    0 0 38px hsl(var(--state-hue-2) 100% 68% / calc(0.12 + var(--mic) * 0.22));
  animation: listeningRingOne 1.55s ease-out infinite;
}

body[data-state="listening"] .css-orb-wrap::after {
  opacity: calc(0.18 + var(--mic) * 0.42);
  border-color: hsl(var(--state-hue) 100% 72% / calc(0.16 + var(--mic) * 0.24));
  box-shadow:
    0 0 52px hsl(var(--state-hue) 100% 68% / calc(0.1 + var(--mic) * 0.2));
  animation: listeningRingTwo 1.55s ease-out infinite;
  animation-delay: 0.52s;
}

/* ======================================================
   Orb body
====================================================== */

.css-glass-orb {
  position: relative;
  width: 100%;
  height: 100%;

  border-radius: 50%;
  overflow: hidden;
  isolation: isolate;
  clip-path: circle(50% at 50% 50%);

  background:
    radial-gradient(
      circle at
      calc(32% + var(--look-x) * 7%)
      calc(22% + var(--look-y) * 7%),
      rgba(255,255,255,0.5) 0%,
      rgba(255,255,255,0.18) 13%,
      transparent 28%
    ),

    radial-gradient(
      circle at
      calc(50% + var(--look-x) * 5%)
      calc(58% + var(--look-y) * 5%),
      hsl(var(--state-hue) 100% 70% / 0.2),
      transparent 52%
    ),

    radial-gradient(
      circle at 50% 50%,
      rgba(255,255,255,0.12),
      hsl(var(--state-hue) 60% 22% / 0.32) 62%,
      rgba(0, 8, 8, 0.54) 100%
    );

  box-shadow:
    0 28px 88px rgba(0,0,0,0.58),
    0 0 54px hsl(var(--state-hue) 100% 62% / 0.16),
    inset 0 2px 2px rgba(255,255,255,0.68),
    inset 0 -2px 3px rgba(255,255,255,0.15),
    inset 18px 20px 38px rgba(255,255,255,0.13),
    inset -24px -30px 48px rgba(0,0,0,0.34),
    inset 0 0 54px hsl(var(--state-hue) 100% 65% / 0.11);

  animation: orbIdleBreath 4.8s ease-in-out infinite;
}

.css-glass-orb::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 5;

  background:
    radial-gradient(
      circle at
      calc(36% + var(--look-x) * 7%)
      calc(32% + var(--look-y) * 7%),
      rgba(255,255,255,0.2),
      transparent 26%
    ),
    radial-gradient(
      circle at 50% 62%,
      rgba(255,255,255,0.08),
      transparent 48%
    );

  mix-blend-mode: screen;
  opacity: 0.78;
}

.css-glass-orb::after {
  content: "";
  position: absolute;
  inset: 5%;
  border-radius: inherit;
  pointer-events: none;
  z-index: 8;

  border-top: 1px solid rgba(255,255,255,0.42);
  border-left: 1px solid rgba(255,255,255,0.14);
  border-right: 1px solid hsl(var(--state-hue) 100% 75% / 0.1);
  border-bottom: 1px solid rgba(255,255,255,0.06);

  box-shadow:
    inset 0 0 18px rgba(255,255,255,0.08),
    inset 0 -18px 32px rgba(0,0,0,0.16);

  opacity: 0.88;
}

/* ======================================================
   Lava-lamp field
====================================================== */

.orb-lava-field {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  clip-path: circle(50% at 50% 50%);
}

.lava-blob,
.lava-spark {
  position: absolute;
  display: block;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  will-change: transform, border-radius, opacity;
}

.lava-blob-a {
  left: 6%;
  top: 40%;
  width: 48%;
  height: 44%;

  background:
    radial-gradient(
      circle at 42% 38%,
      hsl(var(--state-cool) 100% 74% / 0.68),
      hsl(var(--state-cool) 100% 56% / 0.38) 42%,
      transparent 72%
    );

  opacity: 0.78;

  animation:
    lavaRiseA 8.4s ease-in-out infinite,
    lavaMorphA 5.8s ease-in-out infinite;
}

.lava-blob-b {
  left: 38%;
  top: 34%;
  width: 50%;
  height: 52%;

  background:
    radial-gradient(
      circle at 46% 44%,
      hsl(var(--state-hue) 100% 70% / 0.7),
      hsl(var(--state-hue) 100% 54% / 0.42) 44%,
      transparent 74%
    );

  opacity: 0.82;

  animation:
    lavaRiseB 9.2s ease-in-out infinite,
    lavaMorphB 6.6s ease-in-out infinite;
}

.lava-blob-c {
  left: 30%;
  top: 66%;
  width: 42%;
  height: 34%;

  background:
    radial-gradient(
      circle at 50% 48%,
      hsl(var(--state-hot) 100% 62% / 0.66),
      hsl(318 100% 62% / 0.36) 48%,
      transparent 74%
    );

  opacity: 0.72;

  animation:
    lavaRiseC 10.4s ease-in-out infinite,
    lavaMorphC 6.2s ease-in-out infinite;
}

.lava-blob-d {
  left: 20%;
  top: 18%;
  width: 30%;
  height: 28%;

  background:
    radial-gradient(
      circle at 46% 44%,
      hsl(280 100% 72% / 0.44),
      hsl(260 100% 62% / 0.28) 46%,
      transparent 74%
    );

  opacity: 0.58;

  animation:
    lavaFloatD 7.6s ease-in-out infinite,
    lavaMorphD 5.5s ease-in-out infinite;
}

.lava-blob-e {
  left: 28%;
  top: 22%;
  width: 45%;
  height: 42%;

  background:
    radial-gradient(
      circle at 42% 38%,
      rgba(255,255,255,0.26),
      rgba(255,255,255,0.07) 36%,
      transparent 70%
    );

  opacity: 0.52;

  animation:
    lavaMilkDrift 7.8s ease-in-out infinite,
    lavaMilkPulse 4.8s ease-in-out infinite;
}

.lava-spark {
  width: 3.5%;
  height: 3.5%;
  background: rgba(255, 255, 255, 0.42);
  box-shadow:
    0 0 8px rgba(255,255,255,0.28),
    0 0 18px hsl(var(--state-hue) 100% 70% / 0.24);
  opacity: 0.45;
}

.lava-spark-a {
  left: 32%;
  top: 68%;
  animation: lavaSparkA 5.6s ease-in-out infinite;
}

.lava-spark-b {
  left: 58%;
  top: 48%;
  width: 2.5%;
  height: 2.5%;
  animation: lavaSparkB 6.4s ease-in-out infinite;
}

.lava-spark-c {
  left: 72%;
  top: 72%;
  width: 2.8%;
  height: 2.8%;
  animation: lavaSparkC 7s ease-in-out infinite;
}

/* ======================================================
   Listening state
====================================================== */

body[data-state="listening"] .css-orb-wrap {
  --orb-scale: calc(1.05 + var(--mic) * 0.24);
}

body[data-state="listening"] .css-glass-orb {
  animation: orbIdleBreath 2.8s ease-in-out infinite;
}

body[data-state="listening"] .orb-lava-field {
  filter: saturate(calc(1.08 + var(--mic) * 0.4)) brightness(calc(1.02 + var(--mic) * 0.16));
}

body[data-state="listening"] .lava-blob {
  opacity: calc(0.68 + var(--mic) * 0.24);
}

body[data-state="listening"] .lava-blob-a {
  animation:
    listeningGatherA 2.7s ease-in-out infinite,
    lavaMorphA 4.8s ease-in-out infinite;
}

body[data-state="listening"] .lava-blob-b {
  animation:
    listeningGatherB 2.45s ease-in-out infinite,
    lavaMorphB 4.4s ease-in-out infinite;
}

body[data-state="listening"] .lava-blob-c {
  opacity: calc(0.42 + var(--mic) * 0.18);
  animation:
    listeningGatherC 3.1s ease-in-out infinite,
    lavaMorphC 5s ease-in-out infinite;
}

body[data-state="listening"] .lava-blob-d {
  opacity: calc(0.46 + var(--mic) * 0.18);
}

body[data-state="listening"] .lava-spark {
  opacity: calc(0.36 + var(--mic) * 0.36);
}

/* ======================================================
   Thinking state
====================================================== */

body[data-state="thinking"] .css-orb-wrap {
  --orb-scale: 1.1;
}

body[data-state="thinking"] .css-glass-orb {
  animation:
    orbIdleBreath 3.3s ease-in-out infinite,
    thinkingMorph 2.4s ease-in-out infinite;
}

body[data-state="thinking"] .orb-lava-field {
  filter: saturate(1.28) brightness(1.08);
}

body[data-state="thinking"] .lava-blob-a {
  opacity: 0.86;
  animation:
    thinkingBlobA 3.4s ease-in-out infinite,
    thinkingMorphA 2.8s ease-in-out infinite;
}

body[data-state="thinking"] .lava-blob-b {
  opacity: 0.9;
  animation:
    thinkingBlobB 3.1s ease-in-out infinite,
    thinkingMorphB 2.6s ease-in-out infinite;
}

body[data-state="thinking"] .lava-blob-c {
  opacity: 0.82;
  animation:
    thinkingBlobC 3.7s ease-in-out infinite,
    thinkingMorphC 2.9s ease-in-out infinite;
}

body[data-state="thinking"] .lava-blob-d {
  opacity: 0.72;
  animation:
    thinkingBlobD 2.9s ease-in-out infinite,
    thinkingMorphD 2.4s ease-in-out infinite;
}

body[data-state="thinking"] .lava-blob-e {
  opacity: 0.42;
  animation:
    thinkingMilkDrift 3.8s ease-in-out infinite,
    lavaMilkPulse 3.2s ease-in-out infinite;
}

body[data-state="thinking"] .lava-spark {
  opacity: 0.76;
  background: rgba(255,255,255,0.58);
  box-shadow:
    0 0 10px rgba(255,255,255,0.46),
    0 0 28px hsl(var(--state-hue-2) 100% 72% / 0.46);
}

body[data-state="thinking"] .lava-spark-a {
  animation: thinkingSparkA 2.6s ease-in-out infinite;
}

body[data-state="thinking"] .lava-spark-b {
  animation: thinkingSparkB 2.9s ease-in-out infinite;
}

body[data-state="thinking"] .lava-spark-c {
  animation: thinkingSparkC 3.2s ease-in-out infinite;
}

/* Other states */
body[data-state="result"] .lava-blob {
  opacity: 0.68;
}

body[data-state="alert"] .orb-lava-field {
  filter: hue-rotate(-80deg) saturate(1.25) brightness(1.08);
}

body[data-state="error"] .orb-lava-field {
  filter: hue-rotate(-145deg) saturate(1.35);
}

/* ======================================================
   Additional internal orb layers
====================================================== */

.orb-volume,
.orb-core-glow,
.orb-thinking-glow,
.orb-highlight,
.orb-rim {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
}

.orb-volume {
  z-index: 2;
}

.orb-volume-blue {
  left: 14%;
  top: 23%;
  width: 46%;
  height: 40%;

  background:
    radial-gradient(
      circle,
      hsl(var(--state-cool) 100% 64% / 0.22),
      transparent 68%
    );

  transform:
    translate(
      calc(var(--look-x) * 18px),
      calc(var(--look-y) * 13px)
    );

  opacity: 0.62;
}

.orb-volume-green {
  left: 38%;
  top: 38%;
  width: 48%;
  height: 48%;

  background:
    radial-gradient(
      circle,
      hsl(var(--state-hue) 100% 58% / 0.22),
      transparent 68%
    );

  transform:
    translate(
      calc(var(--look-x) * 21px),
      calc(var(--look-y) * 16px)
    );

  opacity: 0.62;
}

.orb-volume-warm {
  left: 46%;
  top: 55%;
  width: 34%;
  height: 30%;

  background:
    radial-gradient(
      circle,
      hsl(var(--state-hot) 100% 58% / 0.18),
      transparent 68%
    );

  transform:
    translate(
      calc(var(--look-x) * 16px),
      calc(var(--look-y) * 16px)
    );

  opacity: 0.52;
}

.orb-volume-milk {
  inset: 12%;
  z-index: 3;

  background:
    radial-gradient(
      circle at
      calc(35% + var(--look-x) * 6%)
      calc(35% + var(--look-y) * 6%),
      rgba(255,255,255,0.2),
      rgba(255,255,255,0.055) 24%,
      transparent 64%
    );

  opacity: 0.64;
}

.orb-core-glow {
  inset: 20%;
  z-index: 4;

  background:
    radial-gradient(circle at 35% 45%, hsl(var(--state-cool) 100% 72% / 0.18), transparent 42%),
    radial-gradient(circle at 70% 62%, hsl(var(--state-hue) 100% 70% / 0.16), transparent 44%),
    radial-gradient(circle at 48% 74%, hsl(var(--state-hot) 100% 64% / 0.12), transparent 48%);

  opacity: 0.72;
  animation: internalGlowDrift 5.2s ease-in-out infinite;
}

body[data-state="listening"] .orb-core-glow {
  opacity: calc(0.72 + var(--mic) * 0.24);
  animation: listeningCorePulse 1.8s ease-in-out infinite;
}

.orb-thinking-glow {
  inset: 14%;
  z-index: 4;
  opacity: 0;

  background:
    radial-gradient(circle at 42% 48%, hsl(186 100% 72% / 0.3), transparent 34%),
    radial-gradient(circle at 62% 58%, hsl(285 100% 72% / 0.28), transparent 38%),
    radial-gradient(circle at 48% 72%, hsl(160 100% 70% / 0.18), transparent 42%);
}

body[data-state="thinking"] .orb-thinking-glow {
  opacity: 1;
  animation: thinkingInnerGlow 2.2s ease-in-out infinite;
}

/* Highlights */
.orb-highlight {
  z-index: 6;
}

.orb-highlight-main {
  left: calc(19% + var(--look-x) * 7%);
  top: calc(17% + var(--look-y) * 7%);
  width: 30%;
  height: 18%;

  background:
    radial-gradient(ellipse, rgba(255,255,255,0.3), transparent 68%);

  opacity: 0.68;
}

.orb-highlight-small {
  right: calc(19% - var(--look-x) * 5%);
  top: calc(19% + var(--look-y) * 5%);
  width: 13%;
  height: 9%;

  background:
    radial-gradient(ellipse, rgba(255,255,255,0.16), transparent 72%);

  opacity: 0.58;
}

body[data-state="listening"] .orb-highlight-main {
  opacity: calc(0.72 + var(--mic) * 0.2);
}

body[data-state="thinking"] .orb-highlight-main {
  opacity: 0.54;
}

/* Rim */
.orb-rim {
  inset: 0;
  z-index: 7;

  background:
    radial-gradient(
      circle,
      transparent 57%,
      rgba(255,255,255,0.1) 63%,
      rgba(255,255,255,0.24) 68%,
      transparent 74%
    );

  opacity: 0.92;
}

body[data-state="listening"] .orb-rim {
  opacity: calc(0.9 + var(--mic) * 0.1);
  filter: drop-shadow(0 0 12px hsl(var(--state-hue-2) 100% 72% / calc(0.12 + var(--mic) * 0.22)));
}

body[data-state="thinking"] .orb-rim {
  opacity: 0.82;
}

/* Eyes */
.orb-eyes {
  position: absolute;
  left: 50%;
  top: 45%;
  width: 50%;
  height: 18%;

  transform:
    translate(-50%, -50%)
    translate(
      calc(var(--look-x) * 24px),
      calc(var(--look-y) * 16px)
    );

  pointer-events: none;
  transition: transform 70ms ease-out;
  z-index: 10;
}

.orb-eyes::before,
.orb-eyes::after {
  content: "";
  position: absolute;
  top: 0;

  width: 9%;
  height: 74%;

  border-radius: 999px;
  background: rgba(255,255,255,0.95);

  box-shadow:
    0 0 14px rgba(210,255,230,0.65),
    0 0 28px hsl(var(--state-hue) 100% 70% / 0.25);

  transform-origin: center;
  animation: cuteBlink 5.4s ease-in-out infinite;
}

.orb-eyes::before {
  left: 14%;
}

.orb-eyes::after {
  right: 14%;
  animation-delay: 0.03s;
}

body[data-state="listening"] .orb-eyes {
  top: 44%;
  width: 48%;

  transform:
    translate(-50%, -50%)
    translate(
      calc(var(--look-x) * 28px),
      calc(var(--look-y) * 18px)
    );
}

body[data-state="listening"] .orb-eyes::before,
body[data-state="listening"] .orb-eyes::after {
  height: 86%;
  width: 9.5%;
  background: rgba(245,255,255,0.98);
  box-shadow:
    0 0 18px rgba(210,255,245,0.92),
    0 0 38px hsl(var(--state-hue) 100% 70% / 0.45),
    0 0 60px hsl(var(--state-hue-2) 100% 70% / calc(0.1 + var(--mic) * 0.22));
  animation: listeningBlink 6.8s ease-in-out infinite;
}

body[data-state="thinking"] .orb-eyes {
  top: 46%;
  width: 46%;
}

body[data-state="thinking"] .orb-eyes::before,
body[data-state="thinking"] .orb-eyes::after {
  top: 15%;
  height: 48%;
  width: 9%;
  opacity: 0.92;
  background: rgba(245,255,255,0.88);
  box-shadow:
    0 0 12px rgba(210,255,245,0.56),
    0 0 30px hsl(var(--state-hue-2) 100% 72% / 0.36);
  animation: thinkingEyeSoftPulse 2.2s ease-in-out infinite;
}

body[data-state="error"] .orb-eyes::before,
body[data-state="error"] .orb-eyes::after {
  height: 36%;
  top: 20%;
  animation: none;
}

/* Floating shadow */
.orb-shadow {
  position: absolute;
  left: 50%;
  top: calc(50% + var(--orb-size) * 0.75);

  width: calc(var(--orb-size) * 1.18);
  height: calc(var(--orb-size) * 0.24);

  transform: translate(-50%, -50%);
  border-radius: 50%;

  background:
    radial-gradient(
      ellipse,
      hsl(var(--state-hue-2) 100% 72% / 0.42) 0%,
      hsl(270 100% 68% / 0.22) 36%,
      transparent 74%
    );

  opacity: 0.78;
  mix-blend-mode: screen;
  animation: shadowFloat 4.8s ease-in-out infinite;
}

body[data-state="listening"] .orb-shadow {
  opacity: calc(0.72 + var(--mic) * 0.22);
}

body[data-state="thinking"] .orb-shadow {
  background:
    radial-gradient(
      ellipse,
      hsl(var(--state-hue-2) 100% 72% / 0.38) 0%,
      hsl(280 100% 68% / 0.28) 38%,
      transparent 74%
    );
}

/* Other state behaviour */
body[data-state="result"] .css-orb-wrap {
  --orb-scale: 1.08;
}

body[data-state="result"] .orb-highlight-main {
  animation: resultHighlightPop 1.2s ease-out 1;
}

body[data-state="error"] .css-orb-wrap {
  animation: cssOrbError 420ms ease-in-out 2;
}

body[data-state="alert"] .css-orb-wrap {
  --orb-scale: 1.12;
}

body[data-state="alert"] .css-glass-orb {
  animation: orbIdleBreath 2.2s ease-in-out infinite;
}

/* ======================================================
   Glass UI
====================================================== */

.glass-shell {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
}

.glass-controls {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);

  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;

  width: min(900px, calc(100vw - 32px));
}

.glass-chip {
  position: relative;
  padding: 8px 13px;
  border-radius: 999px;

  border: 1px solid rgba(255,255,255,0.22);

  background:
    linear-gradient(
      145deg,
      rgba(255,255,255,0.2),
      rgba(255,255,255,0.055) 52%,
      rgba(255,255,255,0.12)
    );

  backdrop-filter: blur(22px) saturate(1.7) contrast(1.04);
  -webkit-backdrop-filter: blur(22px) saturate(1.7) contrast(1.04);

  box-shadow:
    0 12px 34px rgba(0,0,0,0.38),
    inset 0 1px 0 rgba(255,255,255,0.44),
    inset 0 -1px 0 rgba(255,255,255,0.08),
    inset 8px 8px 18px rgba(255,255,255,0.06),
    inset -10px -10px 22px rgba(0,0,0,0.2);

  color: rgba(255,255,255,0.68);
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.02em;
  white-space: nowrap;

  transition: 220ms ease;
  overflow: hidden;
}

.glass-chip::before {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: inherit;
  pointer-events: none;

  background:
    linear-gradient(
      145deg,
      rgba(255,255,255,0.36),
      transparent 34%,
      transparent 70%,
      rgba(255,255,255,0.08)
    );

  opacity: 0.5;
  mix-blend-mode: screen;
}

.glass-chip.active {
  color: rgba(255,255,255,0.96);
  border-color: rgba(255,255,255,0.34);

  background:
    linear-gradient(
      145deg,
      rgba(255,255,255,0.3),
      rgba(255,255,255,0.095) 52%,
      rgba(255,255,255,0.16)
    );

  box-shadow:
    0 0 26px hsl(var(--state-hue) 100% 65% / 0.2),
    0 12px 34px rgba(0,0,0,0.4),
    inset 0 1px 0 rgba(255,255,255,0.54),
    inset 0 -1px 0 rgba(255,255,255,0.1),
    inset 10px 10px 22px rgba(255,255,255,0.08),
    inset -12px -12px 26px rgba(0,0,0,0.22);
}

.glass-chip strong {
  color: rgba(255,255,255,0.94);
  font-weight: 750;
}

.glass-panel {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);

  width: min(760px, calc(100vw - 32px));
  padding: 15px 20px 17px;

  border-radius: 28px;
  border: 1px solid rgba(255,255,255,0.28);

  background:
    linear-gradient(
      135deg,
      rgba(255,255,255,0.24),
      rgba(255,255,255,0.075) 38%,
      rgba(255,255,255,0.13) 100%
    );

  backdrop-filter: blur(30px) saturate(1.75) contrast(1.06);
  -webkit-backdrop-filter: blur(30px) saturate(1.75) contrast(1.06);

  box-shadow:
    0 26px 80px rgba(0,0,0,0.58),
    0 0 38px hsl(var(--state-hue) 100% 65% / 0.08),
    inset 0 1px 1px rgba(255,255,255,0.62),
    inset 0 -1px 1px rgba(255,255,255,0.12),
    inset 10px 12px 28px rgba(255,255,255,0.08),
    inset -14px -18px 34px rgba(0,0,0,0.24);

  overflow: hidden;
}

.glass-panel::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;

  background:
    radial-gradient(circle at 16% 0%, rgba(255,255,255,0.5), transparent 24%),
    radial-gradient(circle at 90% 90%, hsl(var(--state-hue) 100% 65% / 0.18), transparent 28%),
    radial-gradient(circle at 8% 92%, hsl(var(--state-hue-2) 100% 65% / 0.16), transparent 24%),
    linear-gradient(
      115deg,
      rgba(255,255,255,0.35),
      transparent 24%,
      transparent 64%,
      rgba(255,255,255,0.12)
    );

  opacity: 0.86;
  mix-blend-mode: screen;
}

.glass-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;

  border: 1px solid rgba(255,255,255,0.16);

  box-shadow:
    inset 0 0 0 1px hsl(var(--state-hue-2) 100% 65% / 0.08),
    inset 0 0 28px rgba(255,255,255,0.04);
}

.glass-title {
  position: relative;
  margin: 0;

  font-size: 13px;
  line-height: 1.25;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 800;

  color: rgba(255,255,255,0.92);
  text-align: center;
  text-shadow: 0 0 18px hsl(var(--state-hue) 100% 75% / 0.3);
}

.glass-subtitle {
  position: relative;
  margin: 7px auto 0;

  max-width: 650px;
  min-height: 18px;

  font-size: 12px;
  line-height: 1.45;
  font-weight: 400;

  color: rgba(255,255,255,0.58);
  text-align: center;
}

/* ======================================================
   Voice-reactive meter
====================================================== */

.meter {
  position: relative;
  width: 188px;
  height: 7px;
  margin: 12px auto 0;

  border-radius: 999px;

  background:
    linear-gradient(
      90deg,
      rgba(255,255,255,0.055),
      rgba(255,255,255,0.15),
      rgba(255,255,255,0.055)
    );

  overflow: hidden;

  box-shadow:
    inset 0 0 0 1px rgba(255,255,255,0.07),
    inset 0 2px 8px rgba(0,0,0,0.42),
    0 0 18px hsl(var(--state-hue-2) 100% 70% / 0.08);

  transform:
    scaleY(calc(1 + var(--meter-velocity) * 7));

  transition:
    width 220ms ease,
    height 220ms ease,
    transform 80ms ease-out,
    box-shadow 120ms ease-out;
}

.meter::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;

  background:
    repeating-linear-gradient(
      90deg,
      rgba(255,255,255,0.12) 0 2px,
      transparent 2px 9px
    );

  opacity: 0.14;
  mix-blend-mode: screen;
}

.meter::after {
  content: "";
  position: absolute;
  left: calc(var(--meter-peak) * 100%);
  top: 50%;

  width: 10px;
  height: 190%;

  transform: translate(-50%, -50%);
  border-radius: 999px;

  background: rgba(255,255,255,0.78);

  box-shadow:
    0 0 12px rgba(255,255,255,0.45),
    0 0 24px hsl(var(--state-hue-2) 100% 72% / 0.36);

  opacity: calc(var(--meter-peak) * 0.72);
  pointer-events: none;
}

.meter-fill {
  position: absolute;
  left: 0;
  top: 0;

  width: 100%;
  height: 100%;

  border-radius: inherit;

  transform-origin: left center;

  transform:
    scaleX(var(--meter-mic))
    scaleY(calc(1 + var(--meter-velocity) * 5));

  background:
    linear-gradient(
      90deg,
      hsl(var(--state-hue) 100% 62% / 0.92),
      hsl(var(--state-hue-2) 100% 68% / 1),
      hsl(280 100% 72% / 0.9)
    );

  background-size: 180% 100%;

  box-shadow:
    0 0 calc(10px + var(--meter-mic) * 24px) hsl(var(--state-hue) 100% 68% / 0.42),
    0 0 calc(22px + var(--meter-mic) * 38px) hsl(var(--state-hue-2) 100% 70% / 0.24);

  filter:
    brightness(calc(0.95 + var(--meter-mic) * 0.45))
    saturate(calc(1 + var(--meter-mic) * 0.45));

  transition:
    transform 55ms ease-out,
    filter 80ms ease-out,
    box-shadow 80ms ease-out;
}

body[data-state="listening"] .meter {
  width: 236px;
  height: 9px;

  background:
    linear-gradient(
      90deg,
      rgba(255,255,255,0.07),
      rgba(255,255,255,0.17),
      rgba(255,255,255,0.07)
    );

  box-shadow:
    0 0 calc(18px + var(--meter-mic) * 26px) hsl(var(--state-hue-2) 100% 70% / 0.18),
    inset 0 0 0 1px rgba(255,255,255,0.1),
    inset 0 2px 8px rgba(0,0,0,0.38);
}

body[data-state="listening"] .meter::before {
  opacity: calc(0.18 + var(--meter-mic) * 0.28);
  animation: meterInputTexture 1.1s linear infinite;
}

body[data-state="listening"] .meter::after {
  opacity: calc(var(--meter-peak) * 0.85);
}

body[data-state="listening"] .meter-fill {
  min-width: 4%;

  background:
    linear-gradient(
      90deg,
      hsl(var(--state-hue) 100% 62% / 0.96),
      hsl(var(--state-hue-2) 100% 70% / 1),
      hsl(282 100% 74% / 0.92),
      hsl(var(--state-hue) 100% 66% / 0.96)
    );

  background-size: 220% 100%;

  animation: meterLiquidShimmer 1.1s ease-in-out infinite;
}

body[data-state="thinking"] .meter {
  width: 196px;
  height: 7px;

  box-shadow:
    0 0 18px hsl(270 100% 70% / 0.12),
    inset 0 0 0 1px rgba(255,255,255,0.08),
    inset 0 2px 8px rgba(0,0,0,0.4);
}

body[data-state="thinking"] .meter::before {
  opacity: 0.16;
  animation: meterInputTexture 1.8s linear infinite;
}

body[data-state="thinking"] .meter-fill {
  opacity: 0.78;

  background:
    linear-gradient(
      90deg,
      hsl(185 100% 68% / 0.78),
      hsl(265 100% 72% / 0.9),
      hsl(315 100% 70% / 0.74),
      hsl(185 100% 68% / 0.78)
    );

  background-size: 220% 100%;
  animation: meterThinkingFlow 1.8s ease-in-out infinite;
}

body[data-state="result"] .meter {
  width: 204px;
  height: 7px;
}

body[data-state="result"] .meter-fill {
  opacity: 0.82;
}

body[data-state="error"] .meter {
  width: 184px;
  height: 7px;
}

body[data-state="error"] .meter-fill {
  background:
    linear-gradient(
      90deg,
      hsl(8 100% 62% / 0.9),
      hsl(28 100% 64% / 0.82),
      hsl(320 100% 68% / 0.72)
    );

  animation: meterErrorJitter 320ms ease-in-out infinite;
}

body[data-state="alert"] .meter {
  width: 228px;
  height: 9px;
}

body[data-state="alert"] .meter-fill {
  background:
    linear-gradient(
      90deg,
      hsl(38 100% 62% / 0.98),
      hsl(52 100% 70% / 1),
      hsl(18 100% 62% / 0.9)
    );

  animation: meterAlertPulse 720ms ease-in-out infinite;
}

/* ======================================================
   Animations
====================================================== */

@keyframes orbFloat {
  0%, 100% {
    margin-top: 0;
  }

  50% {
    margin-top: -12px;
  }
}

@keyframes shadowFloat {
  0%, 100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.78;
  }

  50% {
    transform: translate(-50%, -50%) scale(1.16, 0.82);
    opacity: 0.5;
  }
}

@keyframes cuteBlink {
  0%, 86%, 91%, 100% {
    transform: scaleY(1);
  }

  88% {
    transform: scaleY(0.08);
  }
}

@keyframes listeningBlink {
  0%, 90%, 94%, 100% {
    transform: scaleY(1);
  }

  92% {
    transform: scaleY(0.12);
  }
}

@keyframes thinkingEyeSoftPulse {
  0%, 100% {
    transform: scaleY(0.92);
    opacity: 0.82;
  }

  50% {
    transform: scaleY(1.08);
    opacity: 1;
  }
}

@keyframes orbIdleBreath {
  0%, 100% {
    transform: scale(1) translateY(0);
  }

  50% {
    transform: scale(1.055) translateY(-5px);
  }
}

@keyframes listeningRingOne {
  0% {
    transform: scale(0.84);
    opacity: calc(0.36 + var(--mic) * 0.44);
  }

  100% {
    transform: scale(1.42);
    opacity: 0;
  }
}

@keyframes listeningRingTwo {
  0% {
    transform: scale(0.92);
    opacity: calc(0.24 + var(--mic) * 0.36);
  }

  100% {
    transform: scale(1.64);
    opacity: 0;
  }
}

@keyframes resultHighlightPop {
  0% {
    transform: scale(0.8);
    opacity: 0.2;
  }

  42% {
    transform: scale(1.18);
    opacity: 0.92;
  }

  100% {
    transform: scale(1);
    opacity: 0.78;
  }
}

@keyframes listeningMicroPulse {
  0%, 100% {
    box-shadow:
      0 28px 88px rgba(0,0,0,0.58),
      0 0 54px hsl(var(--state-hue) 100% 62% / 0.18),
      inset 0 2px 2px rgba(255,255,255,0.68),
      inset 0 -2px 3px rgba(255,255,255,0.15),
      inset 18px 20px 38px rgba(255,255,255,0.13),
      inset -24px -30px 48px rgba(0,0,0,0.34),
      inset 0 0 54px hsl(var(--state-hue) 100% 65% / 0.12);
  }

  50% {
    box-shadow:
      0 28px 88px rgba(0,0,0,0.58),
      0 0 74px hsl(var(--state-hue-2) 100% 66% / calc(0.24 + var(--mic) * 0.28)),
      inset 0 2px 2px rgba(255,255,255,0.72),
      inset 0 -2px 3px rgba(255,255,255,0.18),
      inset 18px 20px 38px rgba(255,255,255,0.16),
      inset -24px -30px 48px rgba(0,0,0,0.3),
      inset 0 0 68px hsl(var(--state-hue-2) 100% 68% / calc(0.18 + var(--mic) * 0.2));
  }
}

@keyframes thinkingMorph {
  0%, 100% {
    border-radius: 50% 48% 52% 50%;
  }

  33% {
    border-radius: 47% 53% 49% 51%;
  }

  66% {
    border-radius: 53% 47% 52% 48%;
  }
}

@keyframes internalGlowDrift {
  0%, 100% {
    transform: translate(-6%, 2%) scale(0.92) rotate(0deg);
    opacity: 0.62;
  }

  35% {
    transform: translate(7%, -5%) scale(1.08) rotate(12deg);
    opacity: 0.92;
  }

  70% {
    transform: translate(2%, 7%) scale(1.16) rotate(-10deg);
    opacity: 0.74;
  }
}

@keyframes listeningCorePulse {
  0%, 100% {
    transform: scale(0.96) translate(0, 0);
    opacity: calc(0.62 + var(--mic) * 0.18);
  }

  50% {
    transform:
      scale(calc(1.04 + var(--mic) * 0.08))
      translate(
        calc(var(--look-x) * 4px),
        calc(var(--look-y) * 3px)
      );
    opacity: calc(0.76 + var(--mic) * 0.2);
  }
}

@keyframes thinkingInnerGlow {
  0%, 100% {
    transform: scale(0.9) rotate(0deg);
    opacity: 0.38;
  }

  50% {
    transform: scale(1.2) rotate(10deg);
    opacity: 1;
  }
}

@keyframes alertPulse {
  0%, 100% {
    box-shadow:
      0 28px 88px rgba(0,0,0,0.58),
      0 0 58px hsl(42 100% 58% / 0.28),
      inset 0 2px 2px rgba(255,255,255,0.64),
      inset -24px -30px 48px rgba(0,0,0,0.38);
  }

  50% {
    box-shadow:
      0 28px 88px rgba(0,0,0,0.58),
      0 0 92px hsl(42 100% 58% / 0.55),
      inset 0 2px 2px rgba(255,255,255,0.7),
      inset -24px -30px 48px rgba(0,0,0,0.3);
  }
}

@keyframes cssOrbError {
  0%, 100% {
    transform:
      translate(-50%, -50%)
      translate(calc(var(--look-x) * 18px), calc(var(--look-y) * 14px))
      scale(var(--orb-scale));
  }

  25% {
    transform:
      translate(calc(-50% - 10px), -50%)
      translate(calc(var(--look-x) * 18px), calc(var(--look-y) * 14px))
      scale(0.98, 1.04);
  }

  55% {
    transform:
      translate(calc(-50% + 10px), -50%)
      translate(calc(var(--look-x) * 18px), calc(var(--look-y) * 14px))
      scale(1.04, 0.98);
  }

  80% {
    transform:
      translate(calc(-50% - 5px), -50%)
      translate(calc(var(--look-x) * 18px), calc(var(--look-y) * 14px))
      scale(1);
  }
}

/* Meter animations */

@keyframes meterInputTexture {
  0% {
    transform: translateX(-18px);
  }

  100% {
    transform: translateX(18px);
  }
}

@keyframes meterLiquidShimmer {
  0%, 100% {
    background-position: 0% 50%;
  }

  50% {
    background-position: 100% 50%;
  }
}

@keyframes meterThinkingFlow {
  0%, 100% {
    background-position: 0% 50%;
    filter: brightness(0.9) saturate(1.05);
  }

  50% {
    background-position: 100% 50%;
    filter: brightness(1.18) saturate(1.28);
  }
}

@keyframes meterErrorJitter {
  0%, 100% {
    transform:
      scaleX(var(--meter-mic))
      scaleY(calc(1 + var(--meter-velocity) * 5))
      translateX(0);
  }

  35% {
    transform:
      scaleX(var(--meter-mic))
      scaleY(calc(1 + var(--meter-velocity) * 5))
      translateX(-2px);
  }

  70% {
    transform:
      scaleX(var(--meter-mic))
      scaleY(calc(1 + var(--meter-velocity) * 5))
      translateX(2px);
  }
}

@keyframes meterAlertPulse {
  0%, 100% {
    filter: brightness(1) saturate(1.1);
  }

  50% {
    filter: brightness(1.35) saturate(1.35);
  }
}

/* Lava motion */

@keyframes lavaRiseA {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 9px - 4px),
        calc(var(--look-y) * 7px + 14px)
      )
      scale(1);
  }

  35% {
    transform:
      translate(
        calc(var(--look-x) * 9px + 10px),
        calc(var(--look-y) * 7px - 18px)
      )
      scale(1.08, 1.18);
  }

  70% {
    transform:
      translate(
        calc(var(--look-x) * 9px - 12px),
        calc(var(--look-y) * 7px - 4px)
      )
      scale(0.96, 1.08);
  }
}

@keyframes lavaMorphA {
  0%, 100% {
    border-radius: 58% 42% 52% 48% / 48% 54% 46% 52%;
  }

  50% {
    border-radius: 42% 58% 45% 55% / 56% 42% 58% 44%;
  }
}

@keyframes lavaRiseB {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 13px + 6px),
        calc(var(--look-y) * 9px + 8px)
      )
      scale(1.02);
  }

  42% {
    transform:
      translate(
        calc(var(--look-x) * 13px - 8px),
        calc(var(--look-y) * 9px - 20px)
      )
      scale(1.12, 1.22);
  }

  76% {
    transform:
      translate(
        calc(var(--look-x) * 13px + 12px),
        calc(var(--look-y) * 9px - 2px)
      )
      scale(0.98, 1.08);
  }
}

@keyframes lavaMorphB {
  0%, 100% {
    border-radius: 46% 54% 57% 43% / 54% 44% 56% 46%;
  }

  50% {
    border-radius: 60% 40% 42% 58% / 42% 58% 45% 55%;
  }
}

@keyframes lavaRiseC {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 7px),
        calc(var(--look-y) * 8px + 8px)
      )
      scale(1);
  }

  48% {
    transform:
      translate(
        calc(var(--look-x) * 7px + 4px),
        calc(var(--look-y) * 8px - 24px)
      )
      scale(0.9, 1.35);
  }

  82% {
    transform:
      translate(
        calc(var(--look-x) * 7px - 10px),
        calc(var(--look-y) * 8px - 8px)
      )
      scale(1.08, 0.95);
  }
}

@keyframes lavaMorphC {
  0%, 100% {
    border-radius: 54% 46% 48% 52% / 44% 56% 48% 52%;
  }

  50% {
    border-radius: 42% 58% 58% 42% / 58% 42% 55% 45%;
  }
}

@keyframes lavaFloatD {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 10px - 4px),
        calc(var(--look-y) * 7px)
      )
      scale(1);
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 10px + 12px),
        calc(var(--look-y) * 7px + 16px)
      )
      scale(1.12);
  }
}

@keyframes lavaMorphD {
  0%, 100% {
    border-radius: 50% 50% 45% 55% / 56% 44% 58% 42%;
  }

  50% {
    border-radius: 61% 39% 58% 42% / 43% 57% 40% 60%;
  }
}

@keyframes lavaMilkDrift {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 6px),
        calc(var(--look-y) * 5px)
      )
      scale(1);
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 6px + 8px),
        calc(var(--look-y) * 5px - 10px)
      )
      scale(1.06);
  }
}

@keyframes lavaMilkPulse {
  0%, 100% {
    opacity: 0.42;
  }

  50% {
    opacity: 0.64;
  }
}

@keyframes lavaSparkA {
  0%, 100% {
    transform: translate(0, 0) scale(0.9);
    opacity: 0.22;
  }

  50% {
    transform: translate(8px, -34px) scale(1.2);
    opacity: 0.72;
  }
}

@keyframes lavaSparkB {
  0%, 100% {
    transform: translate(0, 0) scale(0.8);
    opacity: 0.18;
  }

  45% {
    transform: translate(-12px, -24px) scale(1.1);
    opacity: 0.62;
  }
}

@keyframes lavaSparkC {
  0%, 100% {
    transform: translate(0, 0) scale(0.8);
    opacity: 0.2;
  }

  55% {
    transform: translate(-18px, -38px) scale(1.15);
    opacity: 0.68;
  }
}

/* Listening-specific lava motion */

@keyframes listeningGatherA {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 9px - 8px),
        calc(var(--look-y) * 7px + 8px)
      )
      scale(calc(0.96 + var(--mic) * 0.12));
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 11px + 2px),
        calc(var(--look-y) * 8px - 8px)
      )
      scale(calc(1.04 + var(--mic) * 0.18));
  }
}

@keyframes listeningGatherB {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 12px + 7px),
        calc(var(--look-y) * 9px + 5px)
      )
      scale(calc(1 + var(--mic) * 0.12));
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 13px - 4px),
        calc(var(--look-y) * 9px - 7px)
      )
      scale(calc(1.08 + var(--mic) * 0.16));
  }
}

@keyframes listeningGatherC {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 7px),
        calc(var(--look-y) * 8px + 6px)
      )
      scale(0.94);
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 7px + 2px),
        calc(var(--look-y) * 8px - 9px)
      )
      scale(calc(1.02 + var(--mic) * 0.14));
  }
}

/* Thinking-specific lava motion */

@keyframes thinkingBlobA {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 10px - 12px),
        calc(var(--look-y) * 8px + 14px)
      )
      scale(0.96, 1.04);
  }

  34% {
    transform:
      translate(
        calc(var(--look-x) * 10px + 12px),
        calc(var(--look-y) * 8px - 24px)
      )
      scale(1.2, 0.92);
  }

  68% {
    transform:
      translate(
        calc(var(--look-x) * 10px - 4px),
        calc(var(--look-y) * 8px - 8px)
      )
      scale(0.92, 1.22);
  }
}

@keyframes thinkingBlobB {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 13px + 12px),
        calc(var(--look-y) * 9px + 8px)
      )
      scale(1.06);
  }

  40% {
    transform:
      translate(
        calc(var(--look-x) * 13px - 14px),
        calc(var(--look-y) * 9px - 28px)
      )
      scale(0.94, 1.28);
  }

  78% {
    transform:
      translate(
        calc(var(--look-x) * 13px + 6px),
        calc(var(--look-y) * 9px - 4px)
      )
      scale(1.18, 0.96);
  }
}

@keyframes thinkingBlobC {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 8px - 2px),
        calc(var(--look-y) * 8px + 12px)
      )
      scale(1.02, 0.94);
  }

  44% {
    transform:
      translate(
        calc(var(--look-x) * 8px + 12px),
        calc(var(--look-y) * 8px - 32px)
      )
      scale(0.86, 1.42);
  }

  82% {
    transform:
      translate(
        calc(var(--look-x) * 8px - 10px),
        calc(var(--look-y) * 8px - 8px)
      )
      scale(1.18, 0.9);
  }
}

@keyframes thinkingBlobD {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 10px - 6px),
        calc(var(--look-y) * 7px - 2px)
      )
      scale(0.96);
  }

  48% {
    transform:
      translate(
        calc(var(--look-x) * 10px + 16px),
        calc(var(--look-y) * 7px + 22px)
      )
      scale(1.18);
  }
}

@keyframes thinkingMilkDrift {
  0%, 100% {
    transform:
      translate(
        calc(var(--look-x) * 5px - 5px),
        calc(var(--look-y) * 5px + 2px)
      )
      scale(0.98);
  }

  50% {
    transform:
      translate(
        calc(var(--look-x) * 5px + 10px),
        calc(var(--look-y) * 5px - 12px)
      )
      scale(1.08);
  }
}

@keyframes thinkingMorphA {
  0%, 100% {
    border-radius: 58% 42% 52% 48% / 48% 54% 46% 52%;
  }

  33% {
    border-radius: 38% 62% 48% 52% / 60% 40% 64% 36%;
  }

  66% {
    border-radius: 62% 38% 40% 60% / 42% 58% 38% 62%;
  }
}

@keyframes thinkingMorphB {
  0%, 100% {
    border-radius: 46% 54% 57% 43% / 54% 44% 56% 46%;
  }

  35% {
    border-radius: 64% 36% 44% 56% / 38% 62% 46% 54%;
  }

  72% {
    border-radius: 42% 58% 66% 34% / 58% 42% 62% 38%;
  }
}

@keyframes thinkingMorphC {
  0%, 100% {
    border-radius: 54% 46% 48% 52% / 44% 56% 48% 52%;
  }

  40% {
    border-radius: 34% 66% 58% 42% / 62% 38% 56% 44%;
  }

  78% {
    border-radius: 66% 34% 42% 58% / 40% 60% 38% 62%;
  }
}

@keyframes thinkingMorphD {
  0%, 100% {
    border-radius: 50% 50% 45% 55% / 56% 44% 58% 42%;
  }

  50% {
    border-radius: 68% 32% 62% 38% / 36% 64% 34% 66%;
  }
}

@keyframes thinkingSparkA {
  0%, 100% {
    transform: translate(0, 0) scale(0.82);
    opacity: 0.34;
  }

  45% {
    transform: translate(14px, -42px) scale(1.32);
    opacity: 0.94;
  }
}

@keyframes thinkingSparkB {
  0%, 100% {
    transform: translate(0, 0) scale(0.72);
    opacity: 0.28;
  }

  48% {
    transform: translate(-20px, -30px) scale(1.26);
    opacity: 0.84;
  }
}

@keyframes thinkingSparkC {
  0%, 100% {
    transform: translate(0, 0) scale(0.74);
    opacity: 0.32;
  }

  52% {
    transform: translate(-24px, -46px) scale(1.34);
    opacity: 0.9;
  }
}

@supports not ((backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px))) {
  .glass-panel,
  .glass-chip {
    background: rgba(20, 24, 28, 0.82);
  }
}

@media (max-width: 720px) {
  .glass-controls {
    top: 16px;
    gap: 6px;
  }

  .glass-chip {
    padding: 7px 10px;
    font-size: 10px;
  }

  .glass-panel {
    bottom: 18px;
    padding: 12px 14px 14px;
    border-radius: 21px;
  }

  .glass-title {
    font-size: 12px;
  }

  .glass-subtitle {
    font-size: 11px;
  }
}

/* ======================================================
   COMPLETE THINKING BOUNCE + THINKING TO RESULT HANDOFF
   Paste this at the END of style.css

   Includes:
   1. Thinking rubber-ball bounce
   2. Thinking shadow / eyes sync
   3. Thinking → Result resolve transition
   4. Result gentle entry to avoid hard jump
====================================================== */


/* ======================================================
   1. Thinking rubber-ball bounce
====================================================== */

/* Keep wrapper stable so shadow behaves like a ground reference */
body[data-state="thinking"] .css-orb-wrap {
  --orb-scale: 1.08;
  animation: none;
}

/*
  Main orb motion:
  The orb itself moves, not the wrapper.
  This keeps the shadow visually grounded.
*/
body[data-state="thinking"] .css-glass-orb {
  transform-origin: center bottom;

  animation:
    thinkingRubberBallOrb 2.4s linear infinite;
}

/* Preserve original colour / lava / glass details */
body[data-state="thinking"] .orb-lava-field {
  filter: saturate(1.22) brightness(1.06);
}

body[data-state="thinking"] .orb-thinking-glow {
  opacity: 1;
  animation: thinkingInnerGlow 2.2s ease-in-out infinite;
}

/*
  Shadow position:
  Slightly closer to the orb, so the bounce feels connected.
  If the shadow feels too low, change 0.545 to 0.52.
*/
body[data-state="thinking"] .orb-shadow {
  top: calc(50% + var(--orb-size) * 0.545);

  animation:
    thinkingRubberBallShadow 2.4s linear infinite;

  background:
    radial-gradient(
      ellipse,
      hsl(var(--state-hue-2) 100% 72% / 0.42) 0%,
      hsl(280 100% 68% / 0.25) 38%,
      transparent 74%
    );
}

/* Eyes inherit the character squash/stretch subtly */
body[data-state="thinking"] .orb-eyes {
  top: 45%;
  width: 46%;

  animation:
    thinkingRubberBallEyesMove 2.4s linear infinite;
}

body[data-state="thinking"] .orb-eyes::before,
body[data-state="thinking"] .orb-eyes::after {
  top: 15%;
  height: 50%;
  width: 9%;
  opacity: 0.92;

  background: rgba(245,255,255,0.9);

  box-shadow:
    0 0 12px rgba(210,255,245,0.56),
    0 0 30px hsl(var(--state-hue-2) 100% 72% / 0.36);

  animation:
    thinkingRubberBallEyeShape 2.4s linear infinite;
}

/* ======================================================
   Thinking orb keyframes

   Motion logic:
   - Down faster, up slower
   - Squash on contact
   - Stretch on recoil
   - Highest point returns to natural round shape
====================================================== */

@keyframes thinkingRubberBallOrb {
  0% {
    transform: translateY(-44px) scale(1, 1);
    border-radius: 50%;
  }

  8% {
    transform: translateY(-40px) scale(1, 1);
    border-radius: 50%;
  }

  /*
    Falling begins.
    Slight vertical stretch from speed.
  */
  18% {
    transform: translateY(-22px) scale(0.98, 1.04);
    border-radius: 51% 49% 50% 50% / 53% 53% 47% 47%;
  }

  /*
    Faster spacing before contact.
  */
  27% {
    transform: translateY(-5px) scale(1.02, 0.98);
    border-radius: 50% 50% 52% 48% / 48% 48% 52% 52%;
  }

  /*
    Contact squash.
    Main soft-ball moment.
  */
  32% {
    transform: translateY(8px) scale(1.25, 0.7);
    border-radius: 44% 56% 40% 60% / 33% 33% 67% 67%;
  }

  /*
    Recoil stretch.
    The orb pushes itself upward.
  */
  39% {
    transform: translateY(-8px) scale(0.86, 1.22);
    border-radius: 55% 45% 50% 50% / 63% 63% 37% 37%;
  }

  /*
    Going up.
    Slower and more evenly spaced.
  */
  50% {
    transform: translateY(-28px) scale(0.95, 1.08);
    border-radius: 52% 48% 50% 50% / 56% 56% 44% 44%;
  }

  62% {
    transform: translateY(-40px) scale(0.99, 1.02);
    border-radius: 50%;
  }

  /*
    Highest point / hang.
    Higher point, but still round.
  */
  70% {
    transform: translateY(-48px) scale(1, 1);
    border-radius: 50%;
  }

  /*
    Fall again, smaller bounce.
  */
  80% {
    transform: translateY(-24px) scale(0.99, 1.03);
    border-radius: 51% 49% 50% 50% / 52% 52% 48% 48%;
  }

  86% {
    transform: translateY(-4px) scale(1.02, 0.98);
    border-radius: 50% 50% 52% 48% / 48% 48% 52% 52%;
  }

  /*
    Second softer contact.
  */
  90% {
    transform: translateY(5px) scale(1.16, 0.8);
    border-radius: 46% 54% 43% 57% / 38% 38% 62% 62%;
  }

  /*
    Small rebound stretch.
  */
  95% {
    transform: translateY(-10px) scale(0.95, 1.08);
    border-radius: 52% 48% 50% 50% / 56% 56% 44% 44%;
  }

  100% {
    transform: translateY(-44px) scale(1, 1);
    border-radius: 50%;
  }
}

/* ======================================================
   Thinking shadow keyframes

   Shadow reads height:
   - High = smaller, softer, lower opacity
   - Contact = wider, denser
====================================================== */

@keyframes thinkingRubberBallShadow {
  0% {
    transform: translate(-50%, -50%) scale(0.56, 0.46);
    opacity: 0.24;
    filter: blur(2px);
  }

  8% {
    transform: translate(-50%, -50%) scale(0.58, 0.48);
    opacity: 0.26;
    filter: blur(1.9px);
  }

  18% {
    transform: translate(-50%, -50%) scale(0.78, 0.62);
    opacity: 0.44;
    filter: blur(1.2px);
  }

  27% {
    transform: translate(-50%, -50%) scale(1.08, 0.78);
    opacity: 0.68;
    filter: blur(0.4px);
  }

  /*
    Contact:
    Shadow is widest and most solid.
  */
  32% {
    transform: translate(-50%, -50%) scale(1.48, 0.9);
    opacity: 0.88;
    filter: blur(0px);
  }

  39% {
    transform: translate(-50%, -50%) scale(0.92, 0.7);
    opacity: 0.54;
    filter: blur(0.9px);
  }

  50% {
    transform: translate(-50%, -50%) scale(0.72, 0.56);
    opacity: 0.38;
    filter: blur(1.4px);
  }

  62% {
    transform: translate(-50%, -50%) scale(0.6, 0.48);
    opacity: 0.28;
    filter: blur(1.8px);
  }

  /*
    Highest point:
    Smaller and softer.
  */
  70% {
    transform: translate(-50%, -50%) scale(0.52, 0.42);
    opacity: 0.22;
    filter: blur(2.2px);
  }

  80% {
    transform: translate(-50%, -50%) scale(0.74, 0.58);
    opacity: 0.4;
    filter: blur(1.2px);
  }

  86% {
    transform: translate(-50%, -50%) scale(1.04, 0.76);
    opacity: 0.64;
    filter: blur(0.5px);
  }

  90% {
    transform: translate(-50%, -50%) scale(1.28, 0.85);
    opacity: 0.8;
    filter: blur(0px);
  }

  95% {
    transform: translate(-50%, -50%) scale(0.88, 0.68);
    opacity: 0.5;
    filter: blur(0.9px);
  }

  100% {
    transform: translate(-50%, -50%) scale(0.56, 0.46);
    opacity: 0.24;
    filter: blur(2px);
  }
}

/* ======================================================
   Thinking eye movement
====================================================== */

@keyframes thinkingRubberBallEyesMove {
  0%,
  8%,
  70%,
  100% {
    top: 44.3%;
  }

  27% {
    top: 45.5%;
  }

  32% {
    top: 48.2%;
  }

  39% {
    top: 42.8%;
  }

  50% {
    top: 43.8%;
  }

  90% {
    top: 47.2%;
  }

  95% {
    top: 43.5%;
  }
}

@keyframes thinkingRubberBallEyeShape {
  0%,
  8%,
  70%,
  100% {
    height: 50%;
    width: 9%;
    transform: scaleY(1);
  }

  /*
    Contact squash:
    Eyes flatten with the body.
  */
  32% {
    height: 32%;
    width: 11.8%;
    transform: scaleY(0.72);
  }

  /*
    Recoil stretch.
  */
  39% {
    height: 60%;
    width: 8.2%;
    transform: scaleY(1.14);
  }

  50% {
    height: 54%;
    width: 8.6%;
    transform: scaleY(1.06);
  }

  90% {
    height: 38%;
    width: 10.8%;
    transform: scaleY(0.82);
  }

  95% {
    height: 55%;
    width: 8.6%;
    transform: scaleY(1.07);
  }
}


/* ======================================================
   2. Thinking to Result transition
   Requires JS to add:
   body.classList.add("is-thinking-resolving")
====================================================== */

/*
  During resolving, keep wrapper stable.
*/
body.is-thinking-resolving[data-state="thinking"] .css-orb-wrap {
  --orb-scale: 1.08;
  animation: none;
}

/*
  Resolve ends at translateY(-10px),
  and result begins at the same translateY(-10px).
  This avoids the sudden float-up jump.
*/
body.is-thinking-resolving[data-state="thinking"] .css-glass-orb {
  transform-origin: center bottom;

  animation:
    thinkingToResultSmoothOrb 760ms cubic-bezier(0.2, 0.9, 0.22, 1) forwards;
}

/* Interior becomes calmer while resolving */
body.is-thinking-resolving[data-state="thinking"] .orb-lava-field {
  filter: saturate(1.16) brightness(1.08);
}

body.is-thinking-resolving[data-state="thinking"] .orb-thinking-glow {
  opacity: 1;

  animation:
    thinkingToResultSmoothGlow 760ms ease-out forwards;
}

/* Main highlight clarifies as the thought resolves */
body.is-thinking-resolving[data-state="thinking"] .orb-highlight-main {
  animation:
    thinkingToResultSmoothHighlight 760ms ease-out forwards;
}

/* Eyes follow the upward settle */
body.is-thinking-resolving[data-state="thinking"] .orb-eyes {
  animation:
    thinkingToResultSmoothEyesMove 760ms cubic-bezier(0.2, 0.9, 0.22, 1) forwards;
}

body.is-thinking-resolving[data-state="thinking"] .orb-eyes::before,
body.is-thinking-resolving[data-state="thinking"] .orb-eyes::after {
  animation:
    thinkingToResultSmoothEyeShape 760ms cubic-bezier(0.2, 0.9, 0.22, 1) forwards;
}

/* Shadow changes as the orb floats up into result */
body.is-thinking-resolving[data-state="thinking"] .orb-shadow {
  top: calc(50% + var(--orb-size) * 0.545);

  animation:
    thinkingToResultSmoothShadow 760ms cubic-bezier(0.2, 0.9, 0.22, 1) forwards;
}

/* Soft resolve bloom */
body.is-thinking-resolving[data-state="thinking"] .orb-shadow::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;

  width: 86%;
  height: 70%;

  transform: translate(-50%, -50%) scale(0.7, 0.55);
  border-radius: 50%;

  background:
    radial-gradient(
      ellipse,
      hsl(var(--state-hue-2) 100% 78% / 0.22) 0%,
      hsl(280 100% 72% / 0.1) 46%,
      transparent 78%
    );

  opacity: 0;
  mix-blend-mode: screen;
  pointer-events: none;

  animation:
    thinkingToResultSmoothBloom 760ms ease-out forwards;
}

/* ======================================================
   Thinking → Result keyframes
====================================================== */

@keyframes thinkingToResultSmoothOrb {
  /*
    Start from a soft finishing contact.
    This connects to the thinking bounce.
  */
  0% {
    transform: translateY(5px) scale(1.15, 0.82);
    border-radius: 46% 54% 43% 57% / 39% 39% 61% 61%;
  }

  /*
    Rebound upward.
  */
  22% {
    transform: translateY(-12px) scale(0.94, 1.1);
    border-radius: 53% 47% 50% 50% / 58% 58% 42% 42%;
  }

  /*
    Mid settle.
  */
  46% {
    transform: translateY(-6px) scale(1.03, 0.98);
    border-radius: 50% 50% 51% 49% / 48% 48% 52% 52%;
  }

  /*
    Float toward result position.
  */
  72% {
    transform: translateY(-12px) scale(0.995, 1.01);
    border-radius: 50%;
  }

  /*
    Final handoff position.
    IMPORTANT: resultGentleSettleIn starts from this same value.
  */
  100% {
    transform: translateY(-10px) scale(1, 1);
    border-radius: 50%;
  }
}

@keyframes thinkingToResultSmoothShadow {
  0% {
    transform: translate(-50%, -50%) scale(1.26, 0.84);
    opacity: 0.78;
    filter: blur(0px);
  }

  22% {
    transform: translate(-50%, -50%) scale(0.86, 0.68);
    opacity: 0.5;
    filter: blur(0.9px);
  }

  46% {
    transform: translate(-50%, -50%) scale(1.02, 0.76);
    opacity: 0.62;
    filter: blur(0.4px);
  }

  72% {
    transform: translate(-50%, -50%) scale(0.86, 0.66);
    opacity: 0.48;
    filter: blur(0.9px);
  }

  /*
    Final handoff shadow.
    IMPORTANT: resultShadowGentleSettle starts from this same visual scale.
  */
  100% {
    transform: translate(-50%, -50%) scale(0.82, 0.64);
    opacity: 0.44;
    filter: blur(1px);
  }
}

@keyframes thinkingToResultSmoothGlow {
  0% {
    opacity: 1;
    transform: scale(1.16) rotate(8deg);
  }

  45% {
    opacity: 0.82;
    transform: scale(1.04) rotate(3deg);
  }

  100% {
    opacity: 0.28;
    transform: scale(0.92) rotate(0deg);
  }
}

@keyframes thinkingToResultSmoothHighlight {
  0% {
    opacity: 0.5;
    transform: scale(0.92);
  }

  54% {
    opacity: 0.9;
    transform: scale(1.14);
  }

  100% {
    opacity: 0.74;
    transform: scale(1);
  }
}

@keyframes thinkingToResultSmoothEyesMove {
  0% {
    top: 47.2%;
  }

  22% {
    top: 43.5%;
  }

  46% {
    top: 44.4%;
  }

  72% {
    top: 44%;
  }

  100% {
    top: 44.5%;
  }
}

@keyframes thinkingToResultSmoothEyeShape {
  0% {
    height: 38%;
    width: 10.8%;
    transform: scaleY(0.82);
  }

  22% {
    height: 56%;
    width: 8.6%;
    transform: scaleY(1.08);
  }

  46% {
    height: 50%;
    width: 9%;
    transform: scaleY(1);
  }

  100% {
    height: 54%;
    width: 8.8%;
    transform: scaleY(1);
  }
}

@keyframes thinkingToResultSmoothBloom {
  0% {
    transform: translate(-50%, -50%) scale(0.7, 0.55);
    opacity: 0;
  }

  42% {
    transform: translate(-50%, -50%) scale(1.22, 0.7);
    opacity: 0.24;
  }

  100% {
    transform: translate(-50%, -50%) scale(1.65, 0.88);
    opacity: 0;
  }
}


/* ======================================================
   3. Result entry
   This makes Result continue from Thinking resolve,
   instead of snapping or suddenly floating.
====================================================== */

body[data-state="result"] .css-glass-orb {
  transform-origin: center bottom;

  animation:
    resultGentleSettleIn 920ms cubic-bezier(0.18, 0.9, 0.22, 1) 1,
    resultCalmBreath 4.8s ease-in-out 920ms infinite;
}

body[data-state="result"] .orb-shadow {
  animation:
    resultShadowGentleSettle 920ms cubic-bezier(0.18, 0.9, 0.22, 1) 1,
    resultShadowCalmBreath 4.8s ease-in-out 920ms infinite;
}

body[data-state="result"] .orb-thinking-glow {
  opacity: 0;
}

body[data-state="result"] .orb-lava-field {
  filter: saturate(1.06) brightness(1.03);
}

/*
  IMPORTANT:
  0% matches thinkingToResultSmoothOrb 100%.
*/
@keyframes resultGentleSettleIn {
  0% {
    transform: translateY(-10px) scale(1, 1);
    border-radius: 50%;
  }

  38% {
    transform: translateY(-4px) scale(1.025, 0.99);
    border-radius: 50%;
  }

  68% {
    transform: translateY(-7px) scale(0.995, 1.01);
    border-radius: 50%;
  }

  100% {
    transform: translateY(-6px) scale(1, 1);
    border-radius: 50%;
  }
}

@keyframes resultCalmBreath {
  0%, 100% {
    transform: translateY(-6px) scale(1, 1);
  }

  50% {
    transform: translateY(-10px) scale(1.025, 1.025);
  }
}

/*
  IMPORTANT:
  0% matches thinkingToResultSmoothShadow 100%.
*/
@keyframes resultShadowGentleSettle {
  0% {
    transform: translate(-50%, -50%) scale(0.82, 0.64);
    opacity: 0.44;
    filter: blur(1px);
  }

  38% {
    transform: translate(-50%, -50%) scale(1.03, 0.76);
    opacity: 0.62;
    filter: blur(0.4px);
  }

  68% {
    transform: translate(-50%, -50%) scale(0.94, 0.72);
    opacity: 0.56;
    filter: blur(0.7px);
  }

  100% {  
    transform: translate(-50%, -50%) scale(0.98, 0.74);
    opacity: 0.62;
    filter: blur(0.4px);
  }
}

@keyframes resultShadowCalmBreath {
  0%, 100% {
    transform: translate(-50%, -50%) scale(0.98, 0.74);
    opacity: 0.62;
    filter: blur(0.4px);
  }

  50% {
    transform: translate(-50%, -50%) scale(0.86, 0.66);
    opacity: 0.48;
    filter: blur(0.9px);
  }
}

/* ======================================================
   Glow pulse layer (replaces animated box-shadow)
   - listeningMicroPulse / alertPulse 的辉光改由这一层
     的 opacity 驱动，可被 GPU 合成，不再每帧 repaint
   - 球体本体的静态 box-shadow（玻璃质感）完全保留
====================================================== */

.orb-glow-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;

  pointer-events: none;
  z-index: -1;
  opacity: 0;

  /* 静态辉光：颜色跟随状态变量，listening=青，alert=琥珀 */
  box-shadow:
    0 0 60px 4px hsl(var(--state-hue) 100% 62% / 0.5),
    0 0 78px 8px hsl(var(--state-hue-2) 100% 66% / 0.4);

  will-change: opacity;
}

/* Listening：辉光随声音起伏 —— opacity 变亮 + scale 变大（均可 GPU 合成） */
body[data-state="listening"] .orb-glow-pulse {
  animation: glowPulse 900ms ease-in-out infinite;

  /* 声音越大，光晕越往外扩张；--mic 已在 JS 里平滑过，不会抖 */
  transform: scale(calc(1 + var(--mic) * 0.26));
  transition: transform 90ms ease-out;
}

/* Alert：更强、偏暖的辉光脉冲 */
body[data-state="alert"] .orb-glow-pulse {
  box-shadow:
    0 0 64px 4px hsl(42 100% 58% / 0.55),
    0 0 96px 10px hsl(42 100% 58% / 0.4);

  animation: glowPulse 720ms ease-in-out infinite;
}

@keyframes glowPulse {
  /* 静默时靠这条基线做轻呼吸；说话时 --mic 项主导，光晕明显冲亮 */
  0%, 100% {
    opacity: calc(0.24 + var(--mic) * 0.62);
  }

  50% {
    opacity: calc(0.44 + var(--mic) * 0.56);
  }
}

/* ======================================================
   Listening 环形电平表 —— 像底部进度条，但绕着小球一圈
   直接复用已存在的 --meter-mic (0..1)，JS 已做包络平滑
====================================================== */

.orb-audio-ring {
  position: absolute;
  inset: -14%;
  border-radius: 50%;

  pointer-events: none;
  z-index: -1;
  opacity: 0;

  /* 填充弧：从 12 点顺时针，亮色长度 = 当前音量；其余为暗色轨道 */
  background: conic-gradient(
    from -90deg,
    hsl(var(--state-hue)   100% 64% / 0.95) 0deg,
    hsl(var(--state-hue-2) 100% 72% / 0.98) calc(var(--meter-mic) * 360deg),
    hsl(0 0% 100% / 0.05)                    calc(var(--meter-mic) * 360deg)
  );

  /* 把扇形挖成一条细圆环带（去掉内圈和最外圈） */
  -webkit-mask: radial-gradient(
    circle,
    transparent 77%, #000 79%, #000 87%, transparent 89%
  );
  mask: radial-gradient(
    circle,
    transparent 77%, #000 79%, #000 87%, transparent 89%
  );

  filter: drop-shadow(0 0 6px hsl(var(--state-hue-2) 100% 70% / 0.5));
  will-change: opacity, transform;
}

/* 只在 listening 显示；整圈随音量轻微外扩，增强"胀一下"的手感 */
body[data-state="listening"] .orb-audio-ring {
  opacity: 1;
  transform: scale(calc(1 + var(--mic) * 0.06));
  transition: transform 90ms ease-out;
}

/* ======================================================
   表情微表演（只动眼睛）
   - result  开心：弯眼笑 + 右眼 wink
   - error   担心：⌣⌣ + 摇头 + 叹气下沉
   - listening 好奇：大小眼 + 点头 + 八卦瞟眼
   附加说明：本段会覆盖上方旧的 error 眼睛规则（height:36%/animation:none），
            属预期行为，旧规则可留可删。
====================================================== */

/* ---------- 开心 / RESULT：进入时微笑→豆豆眼保持（说话中） ---------- */
body[data-state="result"] .orb-eyes {
  top: 45%;
  width: 56%;
  animation: happyFace 1.6s ease-in-out 1 forwards;
}

body[data-state="result"] .orb-eyes::before,
body[data-state="result"] .orb-eyes::after {
  top: 28%; width: 28%; height: 36%;
  background: transparent;
  border: 6px solid transparent;
  border-top-color: rgba(245, 255, 255, 0.97);
  border-radius: 50%;
  box-shadow: none;
  filter: drop-shadow(0 0 11px hsl(var(--state-hue) 100% 74% / 0.65));
  transform-origin: center;
}
body[data-state="result"] .orb-eyes::before { left: 3%;  animation: happySmileL 1.6s ease-in-out 1 forwards; }
body[data-state="result"] .orb-eyes::after  { right: 3%; animation: happySmileR 1.6s ease-in-out 1 forwards; }

@keyframes happyFace {
  0%   { transform: translate(-50%, -50%); }
  16%  { transform: translate(-50%, -55%); }
  30%  { transform: translate(-50%, -51%); }
  46%  { transform: translate(-50%, -50%); }
  100% { transform: translate(-50%, -50%); }
}

/* 微笑 → 眨眼换豆豆眼 → 保持（不 wink） */
@keyframes happySmileL {
  0%   { top:28%; left:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(0.2); opacity:0.6; }
  14%  { top:28%; left:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(1); opacity:1; }
  42%  { top:28%; left:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(1); opacity:1; }
  47%  { top:28%; left:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(0.04); opacity:0.35; }
  48%  { top:15%; left:20%; width:9%; height:70%; border-width:0; border-top-color:transparent; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(0.04); opacity:0.6; }
  56%  { top:15%; left:20%; width:9%; height:70%; border-width:0; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(1); opacity:1; }
  100% { top:15%; left:20%; width:9%; height:70%; border-width:0; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(1); opacity:1; }
}
@keyframes happySmileR {
  0%   { top:28%; right:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(0.2); opacity:0.6; }
  14%  { top:28%; right:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(1); opacity:1; }
  42%  { top:28%; right:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(1); opacity:1; }
  47%  { top:28%; right:3%; width:28%; height:36%; border-width:6px; border-top-color:rgba(245,255,255,0.97); background:transparent; border-radius:50%; transform:scaleY(0.04); opacity:0.35; }
  48%  { top:15%; right:20%; width:9%; height:70%; border-width:0; border-top-color:transparent; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(0.04); opacity:0.6; }
  56%  { top:15%; right:20%; width:9%; height:70%; border-width:0; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(1); opacity:1; }
  100% { top:15%; right:20%; width:9%; height:70%; border-width:0; background:rgba(245,255,255,0.97); border-radius:999px; transform:scaleY(1); opacity:1; }
}

/* ---------- 回答说完那一刻：侧头 + 右眼 wink + ✨ ---------- */
/* 保持豆豆眼几何，防止回退到弧形 */
body.is-answering-done[data-state="result"] .orb-eyes::before,
body.is-answering-done[data-state="result"] .orb-eyes::after {
  top: 15%; width: 9%; height: 70%;
  border-width: 0; border-top-color: transparent;
  background: rgba(245, 255, 255, 0.97);
  border-radius: 999px;
}
body.is-answering-done[data-state="result"] .orb-eyes::before { left: 20%; }
body.is-answering-done[data-state="result"] .orb-eyes::after  { right: 20%; }

body.is-answering-done[data-state="result"] .orb-eyes {
  animation: winkDoneHead 0.9s ease-in-out 1 forwards;
}
body.is-answering-done[data-state="result"] .orb-eyes::after {
  animation: winkDoneR 0.9s ease-in-out 1 forwards;
}

@keyframes winkDoneHead {
  0%   { transform: translate(-50%, -50%) rotate(0deg); }
  40%  { transform: translate(-50%, -50%) rotate(8deg); }  /* 侧头 = wink 同步 */
  65%  { transform: translate(-50%, -50%) rotate(0deg); }  /* 回正 = 睁眼同步 */
  100% { transform: translate(-50%, -50%) rotate(0deg); }
}
@keyframes winkDoneR {
  0%   { transform: scaleY(1); }
  20%  { transform: scaleY(1); }
  40%  { transform: scaleY(0.06); }  /* 眨 */
  65%  { transform: scaleY(1); }     /* 睁回 */
  100% { transform: scaleY(1); }
}

/* ---------- wink 星星 ✨（跟随回答结束触发） ---------- */
.orb-wink-star {
  position: absolute;
  top: 45%; left: 50%;
  width: 16px; height: 16px;
  margin-left: 15%; margin-top: -34%;
  background: rgba(255, 255, 255, 0.98);
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
  filter: drop-shadow(0 0 6px hsl(var(--state-hue-2) 100% 74% / 0.9));
  opacity: 0;
  pointer-events: none;
  transform-origin: center;
  z-index: 11;
}

/* 拖尾：一颗更小更淡的星，慢半拍跟在主星后面 */
.orb-wink-star::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;

  width: 60%;
  height: 60%;

  transform: translate(-50%, -50%);

  background: rgba(255, 255, 255, 0.9);
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);

  filter: drop-shadow(0 0 4px hsl(var(--state-hue-2) 100% 74% / 0.8));

  opacity: 0;
  pointer-events: none;
}

body.is-answering-done[data-state="result"] .orb-wink-star {
  animation: winkStar 0.9s ease-out 1 forwards;
}
@keyframes winkStar {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.2) rotate(0deg); }
  45%  { opacity: 1; transform: translate(6px, -6px) scale(1.15) rotate(35deg); }
  100% { opacity: 0; transform: translate(20px, -26px) scale(0.55) rotate(80deg); }
}

/* 拖尾动画：比主星晚一点点出现，落在主星身后偏下的位置 */
body.is-answering-done[data-state="result"] .orb-wink-star::after {
  animation: winkStarTrail 0.9s ease-out 1 forwards;
}

@keyframes winkStarTrail {
  0%   { opacity: 0;   transform: translate(-50%, -50%) scale(0.2); }
  /* 主星在 45% 到达峰值，拖尾略晚、略靠后下方 */
  55%  { opacity: 0.7; transform: translate(-95%, 15%) scale(0.9); }
  100% { opacity: 0;   transform: translate(-165%, 60%) scale(0.35); }
}

/* ---------- 担心 / ERROR：⌣⌣ 向下弯的弧（无摇头、无叹气） ---------- */
body[data-state="error"] .orb-eyes {
  top: 47%;
  width: 56%;
  animation: none;
  transform: translate(-50%, -50%);
}

/* 反向弧：透明填充，只点亮"下边框"弯成 ⌣ */
body[data-state="error"] .orb-eyes::before,
body[data-state="error"] .orb-eyes::after {
  top: 20%;
  height: 36%;
  width: 28%;

  background: transparent;
  border: 6px solid transparent;
  border-bottom-color: rgba(235, 245, 255, 0.92);
  border-radius: 50%;

  box-shadow: none;
  filter: drop-shadow(0 0 10px hsl(var(--state-hue) 100% 70% / 0.5));

  transform-origin: center top;
}

body[data-state="error"] .orb-eyes::before {
  left: 3%;
  animation: worriedArc 1.1s ease-out 1 forwards;
}

body[data-state="error"] .orb-eyes::after {
  right: 3%;
  animation: worriedArc 1.1s ease-out 1 forwards;
}

/* 入场：从压平轻轻"垂"成 ⌣ 弧 */
@keyframes worriedArc {
  0%   { transform: scaleY(0.2); opacity: 0.5; }
  60%  { transform: scaleY(1.08); opacity: 1; }   /* 略过冲一下，更有"垮下来"的感觉 */
  100% { transform: scaleY(1); opacity: 1; }
}

/* ======================================================
   ALERT STATE
   进入动作：快速抬起 + 双脉冲 + 睁大眼睛 + 双层信号扩散
====================================================== */

/* Wrapper 保持稳定，避免与球体进入动画互相覆盖 */
body[data-state="alert"] .css-orb-wrap {
  --orb-scale: 1.1;
  animation: none;
}

/* 球体：突然抬起，连续两次短促脉冲，然后稳定 */
body[data-state="alert"] .css-glass-orb {
  transform-origin: center bottom;

  animation:
    alertAttentionEntry 1.25s cubic-bezier(0.2, 0.9, 0.22, 1) 1 forwards,
    alertAttentionHold 1.8s ease-in-out 1.25s infinite;
}

/* Alert 内部色彩更亮、更集中 */
body[data-state="alert"] .orb-lava-field {
  filter:
    hue-rotate(-80deg)
    saturate(1.42)
    brightness(1.14);
}

/* 内部 glow 跟随 Alert 做一次快速增强 */
body[data-state="alert"] .orb-core-glow {
  opacity: 0.96;

  animation:
    alertCoreFlash 1.25s ease-out 1 forwards,
    internalGlowDrift 4s ease-in-out 1.25s infinite;
}

/* 球体 rim 更清楚 */
body[data-state="alert"] .orb-rim {
  opacity: 1;

  filter:
    drop-shadow(
      0 0 16px
      hsl(42 100% 72% / 0.5)
    );
}

/* ======================================================
   Alert 眼睛
   进入时迅速睁大，短时间保持专注，不进行普通眨眼
====================================================== */

body[data-state="alert"] .orb-eyes {
  top: 42.5%;
  width: 47%;

  animation: alertEyesAttention 1.25s ease-out 1 forwards;
}

body[data-state="alert"] .orb-eyes::before,
body[data-state="alert"] .orb-eyes::after {
  top: 0;

  width: 10.5%;
  height: 92%;

  border: 0;
  border-radius: 999px;

  background: rgba(255, 255, 245, 0.98);

  box-shadow:
    0 0 18px rgba(255, 246, 190, 0.92),
    0 0 38px hsl(46 100% 70% / 0.62),
    0 0 62px hsl(28 100% 62% / 0.28);

  animation: alertEyeOpen 1.25s ease-out 1 forwards;
}

body[data-state="alert"] .orb-eyes::before {
  left: 17%;
}

body[data-state="alert"] .orb-eyes::after {
  right: 17%;
}

/* ======================================================
   Alert 外部双扩散环
   复用 css-orb-wrap 的 ::before 和 ::after
====================================================== */

body[data-state="alert"] .css-orb-wrap::before,
body[data-state="alert"] .css-orb-wrap::after {
  content: "";
  position: absolute;

  inset: -10%;
  border-radius: 50%;

  pointer-events: none;
  z-index: -2;

  opacity: 0;

  border: 2px solid hsl(44 100% 72% / 0.8);

  box-shadow:
    0 0 18px hsl(42 100% 64% / 0.5),
    inset 0 0 14px hsl(48 100% 72% / 0.16);
}

/* 第一圈：更强、更快 */
body[data-state="alert"] .css-orb-wrap::before {
  animation: alertSignalRingOne 1.25s ease-out 1 forwards;
}

/* 第二圈：稍慢、稍远、稍淡 */
body[data-state="alert"] .css-orb-wrap::after {
  border-color: hsl(28 100% 64% / 0.58);

  animation: alertSignalRingTwo 1.25s ease-out 1 forwards;
}

/* ======================================================
   Alert 独立辉光层
   需要 HTML 中已有 .orb-glow-pulse
====================================================== */

body[data-state="alert"] .orb-glow-pulse {
  opacity: 0;

  box-shadow:
    0 0 56px 5px hsl(48 100% 66% / 0.7),
    0 0 96px 14px hsl(32 100% 58% / 0.42);

  animation:
    alertGlowEntry 1.25s ease-out 1 forwards,
    alertGlowHold 1.8s ease-in-out 1.25s infinite;
}

/* ======================================================
   Alert meter
====================================================== */

body[data-state="alert"] .meter {
  width: 228px;
  height: 9px;

  animation: alertMeterEntry 1.25s ease-out 1 forwards;
}

body[data-state="alert"] .meter-fill {
  background:
    linear-gradient(
      90deg,
      hsl(28 100% 60% / 0.96),
      hsl(48 100% 72% / 1),
      hsl(18 100% 62% / 0.92),
      hsl(48 100% 72% / 1)
    );

  background-size: 220% 100%;

  animation: alertMeterFlow 850ms ease-in-out infinite;
}

/* ======================================================
   Alert keyframes
====================================================== */

/*
  球体进入：
  1. 快速抬起并拉长
  2. 第一次强脉冲
  3. 短暂收回
  4. 第二次较小脉冲
  5. 稳定
*/
@keyframes alertAttentionEntry {
  0% {
    transform: translateY(0) scale(1, 1);
    border-radius: 50%;
  }

  14% {
    transform: translateY(-13px) scale(0.94, 1.12);
    border-radius: 48% 52% 48% 52% / 54% 54% 46% 46%;
  }

  28% {
    transform: translateY(-8px) scale(1.18, 0.92);
    border-radius: 52% 48% 54% 46% / 46% 46% 54% 54%;
  }

  43% {
    transform: translateY(-10px) scale(0.98, 1.04);
    border-radius: 50%;
  }

  58% {
    transform: translateY(-8px) scale(1.12, 0.96);
    border-radius: 51% 49% 52% 48% / 47% 47% 53% 53%;
  }

  76% {
    transform: translateY(-9px) scale(1.03, 1.02);
    border-radius: 50%;
  }

  100% {
    transform: translateY(-8px) scale(1.06, 1.06);
    border-radius: 50%;
  }
}

/* Alert 进入后维持轻微但清楚的警觉呼吸 */
@keyframes alertAttentionHold {
  0%,
  100% {
    transform: translateY(-8px) scale(1.06);
  }

  50% {
    transform: translateY(-11px) scale(1.09);
  }
}

/* 眼睛容器轻微抬起，像突然注意到重要事情 */
@keyframes alertEyesAttention {
  0% {
    transform:
      translate(-50%, -50%)
      translate(
        calc(var(--look-x) * 24px),
        calc(var(--look-y) * 16px)
      )
      translateY(5px);
  }

  28% {
    transform:
      translate(-50%, -50%)
      translate(
        calc(var(--look-x) * 20px),
        calc(var(--look-y) * 12px)
      )
      translateY(-4px);
  }

  58% {
    transform:
      translate(-50%, -50%)
      translate(
        calc(var(--look-x) * 20px),
        calc(var(--look-y) * 12px)
      )
      translateY(-1px);
  }

  100% {
    transform:
      translate(-50%, -50%)
      translate(
        calc(var(--look-x) * 20px),
        calc(var(--look-y) * 12px)
      )
      translateY(-2px);
  }
}

/* 睁大眼睛，带一点点过冲 */
@keyframes alertEyeOpen {
  0% {
    transform: scaleY(0.5) scaleX(0.92);
    opacity: 0.58;
  }

  24% {
    transform: scaleY(1.16) scaleX(1.08);
    opacity: 1;
  }

  48% {
    transform: scaleY(0.96) scaleX(1);
    opacity: 0.94;
  }

  66% {
    transform: scaleY(1.08) scaleX(1.03);
    opacity: 1;
  }

  100% {
    transform: scaleY(1) scaleX(1);
    opacity: 1;
  }
}

/* 第一圈信号 */
@keyframes alertSignalRingOne {
  0% {
    transform: scale(0.78);
    opacity: 0;
  }

  12% {
    opacity: 0.95;
  }

  48% {
    opacity: 0.5;
  }

  100% {
    transform: scale(1.68);
    opacity: 0;
  }
}

/* 第二圈信号 */
@keyframes alertSignalRingTwo {
  0%,
  18% {
    transform: scale(0.88);
    opacity: 0;
  }

  30% {
    opacity: 0.72;
  }

  100% {
    transform: scale(2);
    opacity: 0;
  }
}

/* 球体周围辉光先快速亮起，再稳定 */
@keyframes alertGlowEntry {
  0% {
    opacity: 0;
    transform: scale(0.84);
  }

  22% {
    opacity: 1;
    transform: scale(1.2);
  }

  46% {
    opacity: 0.52;
    transform: scale(1.04);
  }

  62% {
    opacity: 0.9;
    transform: scale(1.14);
  }

  100% {
    opacity: 0.62;
    transform: scale(1.08);
  }
}

@keyframes alertGlowHold {
  0%,
  100% {
    opacity: 0.58;
    transform: scale(1.08);
  }

  50% {
    opacity: 0.8;
    transform: scale(1.13);
  }
}

/* 内部亮度快速增强 */
@keyframes alertCoreFlash {
  0% {
    transform: scale(0.78);
    opacity: 0.34;
  }

  28% {
    transform: scale(1.22);
    opacity: 1;
  }

  54% {
    transform: scale(0.96);
    opacity: 0.68;
  }

  74% {
    transform: scale(1.1);
    opacity: 0.92;
  }

  100% {
    transform: scale(1);
    opacity: 0.82;
  }
}

/* Meter 入场同步两次提示节奏 */
@keyframes alertMeterEntry {
  0% {
    transform: scaleX(0.82) scaleY(0.8);
    opacity: 0.45;
  }

  28% {
    transform: scaleX(1.12) scaleY(1.3);
    opacity: 1;
  }

  48% {
    transform: scaleX(0.96) scaleY(0.95);
    opacity: 0.76;
  }

  62% {
    transform: scaleX(1.06) scaleY(1.14);
    opacity: 1;
  }

  100% {
    transform: scaleX(1) scaleY(1);
    opacity: 1;
  }
}

@keyframes alertMeterFlow {
  0%,
  100% {
    background-position: 0% 50%;
    filter: brightness(1.04) saturate(1.15);
  }

  50% {
    background-position: 100% 50%;
    filter: brightness(1.38) saturate(1.42);
  }
}

/* ======================================================
   ALERT EXPRESSION
   两只眼睛向中央聚合，形成一个感叹号
====================================================== */

/* 感叹号整体区域 */
body[data-state="alert"] .orb-eyes {
  left: 50%;
  top: 43%;

  width: 24%;
  height: 30%;

  transform: translate(-50%, -50%);
  animation: alertExclamationMove 1.25s ease-out 1 forwards;
}

/*
  ::before = 感叹号竖线
  从普通眼睛的高度位置快速收拢、拉长
*/
body[data-state="alert"] .orb-eyes::before {
  left: 50%;
  top: 0;

  width: 18%;
  height: 68%;

  border: 0;
  border-radius: 999px;

  background: rgba(255, 255, 245, 0.98);

  box-shadow:
    0 0 16px rgba(255, 248, 200, 0.96),
    0 0 34px hsl(46 100% 70% / 0.7),
    0 0 58px hsl(28 100% 62% / 0.34);

  transform-origin: center bottom;

  animation: alertExclamationBar 1.25s ease-out 1 forwards;
}

/*
  ::after = 感叹号圆点
*/
body[data-state="alert"] .orb-eyes::after {
  left: 50%;
  right: auto;
  top: 82%;

  width: 20%;
  height: 20%;

  border: 0;
  border-radius: 50%;

  background: rgba(255, 255, 245, 0.98);

  box-shadow:
    0 0 14px rgba(255, 248, 200, 0.96),
    0 0 30px hsl(46 100% 70% / 0.68),
    0 0 50px hsl(28 100% 62% / 0.3);

  transform-origin: center;

  animation: alertExclamationDot 1.25s ease-out 1 forwards;
}

/* 感叹号整体轻微向上弹出 */
@keyframes alertExclamationMove {
  0% {
    transform:
      translate(-50%, -50%)
      translateY(10px)
      scale(0.82);
  }

  24% {
    transform:
      translate(-50%, -50%)
      translateY(-8px)
      scale(1.14);
  }

  44% {
    transform:
      translate(-50%, -50%)
      translateY(-2px)
      scale(0.98);
  }

  62% {
    transform:
      translate(-50%, -50%)
      translateY(-5px)
      scale(1.06);
  }

  100% {
    transform:
      translate(-50%, -50%)
      translateY(-4px)
      scale(1);
  }
}

/* 感叹号竖线：快速拉长，带两次注意力脉冲 */
@keyframes alertExclamationBar {
  0% {
    transform:
      translateX(-50%)
      scaleX(1.45)
      scaleY(0.18);

    opacity: 0;
  }

  18% {
    transform:
      translateX(-50%)
      scaleX(0.84)
      scaleY(1.2);

    opacity: 1;
  }

  34% {
    transform:
      translateX(-50%)
      scaleX(1.08)
      scaleY(0.94);

    opacity: 1;
  }

  52% {
    transform:
      translateX(-50%)
      scaleX(0.94)
      scaleY(1.1);

    opacity: 1;
  }

  70% {
    transform:
      translateX(-50%)
      scaleX(1.04)
      scaleY(0.98);

    opacity: 1;
  }

  100% {
    transform:
      translateX(-50%)
      scaleX(1)
      scaleY(1);

    opacity: 1;
  }
}

/* 圆点稍晚出现，形成“啪”的提示感 */
@keyframes alertExclamationDot {
  0%,
  16% {
    transform:
      translateX(-50%)
      scale(0);

    opacity: 0;
  }

  28% {
    transform:
      translateX(-50%)
      scale(1.5);

    opacity: 1;
  }

  44% {
    transform:
      translateX(-50%)
      scale(0.82);

    opacity: 0.86;
  }

  60% {
    transform:
      translateX(-50%)
      scale(1.16);

    opacity: 1;
  }

  100% {
    transform:
      translateX(-50%)
      scale(1);

    opacity: 1;
  }
}