/* Eco — animation + states. Pair with eco.ts (markup + controller).
 * States are classes on the <svg class="eco">: is-listening (Ouvindo: mic on, shows the red dot),
 * is-thinking (Pensando), is-happy (Anotou), is-speaking (Lembrando), is-sleeping (Descansando).
 * One-shots: is-entering, is-hopping. Live input: --lx/--ly (look direction, -1..1), is-blink, is-pressed.
 * Springs are the motion-broll constants [ω, ζ] sampled into linear(). */

.eco {
  --spring-morph: linear(0, 0.047, 0.1555, 0.2896, 0.4267, 0.5538, 0.6643, 0.7558, 0.8288, 0.8849, 0.9266, 0.9566, 0.9774, 0.9911, 0.9997, 1.0046, 1.007, 1.0077, 1.0075, 1.0067, 1.0057, 1.0046, 1.0036, 1.0027, 1);
  --spring-morph-dur: 539ms;
  --spring-fast: linear(0, 0.0458, 0.1515, 0.282, 0.4157, 0.54, 0.6485, 0.7392, 0.8121, 0.8689, 0.912, 0.9436, 0.9661, 0.9817, 0.992, 0.9985, 1.0023, 1.0042, 1.0049, 1.005, 1.0045, 1.0039, 1.0033, 1.0026, 1);
  --spring-fast-dur: 296ms;
  --spring-soft: linear(0, 0.0368, 0.1225, 0.2302, 0.3431, 0.4514, 0.5498, 0.636, 0.7094, 0.7706, 0.8208, 0.8614, 0.8937, 0.9192, 0.9392, 0.9546, 0.9664, 0.9753, 0.9821, 0.9871, 0.9908, 0.9936, 0.9956, 0.997, 1);
  --spring-soft-dur: 715ms;
  --ease-io: cubic-bezier(.45, 0, .55, 1);

  --lx: 0; --ly: 0;      /* pointer look, set by eco.js */
  --f: 1;                /* how much the pointer drives the look */
  --tx: 0; --ty: 0;      /* look the state asks for */

  display: block; width: 100%; height: auto; overflow: visible;
  -webkit-tap-highlight-color: transparent; user-select: none;
}

/* ---------- rig ---------- */
.eco .eco-rig, .eco .eco-hop, .eco .eco-float, .eco .eco-squash { transform-origin: 120px 206px; }
.eco .eco-ground { transform-origin: 120px 213px; animation: eco-ground 4.2s var(--ease-io) infinite; }
.eco .eco-float { animation: eco-float 4.2s var(--ease-io) infinite; }
.eco .eco-squash { transition: transform var(--spring-fast-dur) var(--spring-fast); }

@keyframes eco-float {
  0%, 100% { transform: translateY(0) rotate(0) scale(1, 1); }
  50% { transform: translateY(-5px) rotate(-1.2deg) scale(1.01, .99); }
}
@keyframes eco-ground { 50% { transform: scale(.9); opacity: .75; } }

/* ---------- look: eyes lead, shine counters, waves drift ---------- */
.eco .eco-face {
  transform: translate(calc((var(--lx) * var(--f) + var(--tx)) * 5px), calc((var(--ly) * var(--f) + var(--ty)) * 4px));
  transition: transform var(--spring-soft-dur) var(--spring-soft);
}
.eco .eco-shine {
  transform: translate(calc((var(--lx) * var(--f) + var(--tx)) * -3px), calc((var(--ly) * var(--f) + var(--ty)) * -2px));
  transition: transform var(--spring-soft-dur) var(--spring-soft);
}
.eco .eco-waves {
  transform: translateX(calc(var(--lx) * var(--f) * -2px));
  transition: transform var(--spring-soft-dur) var(--spring-soft), opacity .4s ease;
}

/* ---------- eyes ---------- */
.eco .eco-eyes { transition: opacity .12s ease; }
.eco .eco-eyes-open { transform-box: fill-box; transform-origin: center; transition: transform 70ms ease, opacity .12s ease; }
.eco .eco-eyes-happy, .eco .eco-eyes-closed { opacity: 0; }
.eco.is-blink .eco-eyes-open { transform: scaleY(.1); }

/* ---------- waves ---------- */
.eco .eco-wave { transform-box: fill-box; transform-origin: center; animation: eco-wave-idle 3.2s var(--ease-io) infinite; }
.eco .eco-wave-l2, .eco .eco-wave-r2 { animation-delay: .45s; }
@keyframes eco-wave-idle { 50% { opacity: .62; } }

.eco .eco-sweep { opacity: 0; }

/* ---------- listening: sound travels in ---------- */
.eco.is-listening .eco-squash { transform: scale(.98, 1.03); }
.eco.is-listening .eco-wave { animation: eco-wave-in 1.15s cubic-bezier(.3, 0, .3, 1) infinite; }
.eco.is-listening .eco-wave-l1, .eco.is-listening .eco-wave-r1 { animation-delay: .2s; }
.eco.is-listening .eco-wave-l2, .eco.is-listening .eco-wave-r2 { animation-delay: 0s; }
@keyframes eco-wave-in {
  0% { transform: translateX(calc(var(--side) * 14px)); opacity: 0; }
  35% { opacity: 1; }
  80% { transform: translateX(calc(var(--side) * -3px)); opacity: 1; }
  100% { transform: translateX(calc(var(--side) * -4px)); opacity: 0; }
}

/* The red dot means the microphone is on, so it only ever shows while listening. */
.eco .eco-rec { opacity: 0; transform-origin: 196px 198px; transition: opacity .15s ease; }
.eco.is-listening .eco-rec { opacity: 1; }
.eco.is-listening .eco-rec-dot { transform-box: fill-box; transform-origin: center; animation: eco-rec 1.4s var(--ease-io) infinite; }
@keyframes eco-rec { 50% { transform: scale(.78); } }

/* ---------- speaking: sound travels out, body talks ---------- */
.eco.is-speaking .eco-wave { animation: eco-wave-out 1s cubic-bezier(.2, .6, .4, 1) infinite; }
.eco.is-speaking .eco-wave-l2, .eco.is-speaking .eco-wave-r2 { animation-delay: .2s; }
.eco.is-speaking .eco-float { animation: eco-talk .34s var(--ease-io) infinite alternate; }
@keyframes eco-wave-out {
  0% { transform: translateX(calc(var(--side) * -8px)); opacity: 0; }
  25% { opacity: 1; }
  100% { transform: translateX(calc(var(--side) * 16px)); opacity: 0; }
}
@keyframes eco-talk { from { transform: scale(1, 1); } to { transform: translateY(1px) scale(1.022, .972); } }

/* ---------- thinking: eyes up, a sheen crosses the body ---------- */
.eco.is-thinking { --f: 0; --tx: .6; --ty: -.9; }
.eco.is-thinking .eco-float { animation-duration: 6s; }
.eco.is-thinking .eco-waves { opacity: .55; }
.eco.is-thinking .eco-wave { animation-duration: 1.3s; }
.eco.is-thinking .eco-sweep { opacity: 1; animation: eco-sweep 1.9s var(--ease-io) infinite; }
@keyframes eco-sweep { from { transform: translateX(-90px); } to { transform: translateX(230px); } }

/* ---------- happy: arched eyes + hop ---------- */
.eco.is-happy .eco-eyes-open { opacity: 0; }
.eco.is-happy .eco-eyes-happy { opacity: 1; }

.eco.is-hopping .eco-hop { animation: eco-hop .9s both; }
.eco.is-hopping .eco-ground { animation: eco-ground-hop .9s both; }
.eco.is-hopping .eco-wave { animation: eco-wave-pop .9s both; }
@keyframes eco-hop {
  0% { transform: none; animation-timing-function: ease-out; }
  16% { transform: scale(1.08, .88); animation-timing-function: cubic-bezier(.2, .7, .3, 1); }
  45% { transform: translateY(-24px) scale(.95, 1.07); animation-timing-function: ease-in; }
  74% { transform: translateY(0) scale(1.08, .9); animation-timing-function: ease-out; }
  88% { transform: scale(.98, 1.02); }
  100% { transform: none; }
}
@keyframes eco-ground-hop { 45% { transform: scale(.68); opacity: .45; } 74% { transform: scale(1.05); opacity: 1; } }
@keyframes eco-wave-pop {
  0%, 16% { transform: none; }
  50% { transform: translateX(calc(var(--side) * 7px)) scale(1.06); }
  100% { transform: none; }
}

/* ---------- sleeping ---------- */
.eco.is-sleeping { --f: 0; --ty: .4; }
.eco.is-sleeping .eco-eyes-open { opacity: 0; }
.eco.is-sleeping .eco-eyes-closed { opacity: 1; }
.eco.is-sleeping .eco-float { animation: eco-sleep 5s var(--ease-io) infinite; }
.eco.is-sleeping .eco-ground { animation: none; }
.eco.is-sleeping .eco-waves { opacity: .28; }
.eco.is-sleeping .eco-wave { animation: none; }
@keyframes eco-sleep {
  0%, 100% { transform: translateY(2px) scale(1, 1); }
  50% { transform: translateY(2px) scale(1.025, .965); }
}

/* ---------- entrance: pops up, lands, then the waves open ---------- */
.eco.is-entering .eco-rig { animation: eco-enter .95s both; }
.eco.is-entering .eco-ground { animation: eco-ground-in .95s both; }
.eco.is-entering .eco-wave { animation: eco-wave-enter var(--spring-morph-dur) var(--spring-morph) both; }
.eco.is-entering .eco-wave-l1, .eco.is-entering .eco-wave-r1 { animation-delay: .5s; }
.eco.is-entering .eco-wave-l2, .eco.is-entering .eco-wave-r2 { animation-delay: .6s; }
.eco.is-entering .eco-eyes-open { animation: eco-eyes-in .32s .42s both; }
@keyframes eco-enter {
  0% { transform: translateY(64px) scale(.45); opacity: 0; animation-timing-function: cubic-bezier(.2, .8, .3, 1); }
  30% { opacity: 1; }
  52% { transform: translateY(-14px) scale(.95, 1.07); animation-timing-function: ease-in; }
  72% { transform: translateY(0) scale(1.07, .92); animation-timing-function: ease-out; }
  86% { transform: scale(.98, 1.02); }
  100% { transform: none; opacity: 1; }
}
@keyframes eco-ground-in { 0% { transform: scale(0); opacity: 0; } 52% { transform: scale(.6); opacity: .5; } 72% { transform: scale(1.08); opacity: 1; } 100% { transform: none; } }
@keyframes eco-wave-enter { from { transform: translateX(calc(var(--side) * -18px)) scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes eco-eyes-in { from { transform: scaleY(.1); } to { transform: none; } }

/* press wins over any state pose */
.eco.is-pressed .eco-squash { transform: scale(1.07, .9); transition: transform 110ms ease-out; }

@media (prefers-reduced-motion: reduce) {
  .eco, .eco * { animation: none !important; transition: none !important; }
}
