/* The crew (#33): how an avatar moves. crew.js draws it; the mood is a class
   on the wrapper (`idle`, `work`, `queued`, `fail`) and the family is another
   (`f-bot` … `f-gadget`), so a state change is one class swap, never a redraw.

   Everyone blinks when idle and sleeps when queued (eyes shut, a floating z);
   `fail` shows crossed eyes. On top of that each family has its own way of
   being alive — see the family blocks. */

.av { display: inline-grid; place-items: center; flex: none; position: relative;
      width: 32px; height: 32px; vertical-align: middle; }
.av-xs { width: 22px; height: 22px; }
.av-sm { width: 32px; height: 32px; }
.av-md { width: 44px; height: 44px; }
.av-lg { width: 96px; height: 96px; }
.av > svg { width: 100%; height: 100%; display: block; overflow: visible; }

.av .eye, .av .ear, .av .body, .av .tip, .av .spark, .av .glow, .av .leaf, .av .x {
  transform-origin: center; transform-box: fill-box;
}

/* shared moods */
.av .zz { display: none; }
.av .x { display: none; }
.av.idle .eye { animation: crew-blink 4.2s infinite; }
.av.queued .eye { transform: scaleY(.12); }
.av.queued .zz { display: block; animation: crew-zz 2.4s linear infinite; }
.av.fail .eye { display: none; }
.av.fail .x { display: block; }

/* bots: bob, eyes scan, antenna glows */
.f-bot.work .body { animation: crew-bob 1.6s ease-in-out infinite; }
.f-bot.work .eye { animation: crew-scan 1.8s ease-in-out infinite; }
.f-bot.work .tip { animation: crew-glow 1s ease-in-out infinite alternate; }

/* critters: ears twitch, head tilts */
.f-critter.idle .ear { animation: crew-twitch 6s ease-in-out infinite; }
.f-critter.work .ear { animation: crew-twitch 1.2s ease-in-out infinite; }
.f-critter.work .body { animation: crew-tilt 2.2s ease-in-out infinite; }

/* blobs: breathe, wobble, slump */
.f-blob.idle .body { animation: crew-breathe 3.6s ease-in-out infinite; }
.f-blob.work .body { animation: crew-wobble 1.1s ease-in-out infinite; }
.f-blob.queued .body { transform: scaleY(.86) translateY(3px); }

/* spirits: float, hurry with a twinkle, fade */
.f-spirit.idle .body { animation: crew-float 4s ease-in-out infinite; }
.f-spirit.work .body { animation: crew-float 1.4s ease-in-out infinite; }
.f-spirit.work .spark { animation: crew-twinkle .9s ease-in-out infinite alternate; }
.f-spirit.queued .body { opacity: .55; }

/* gadgets: the screen or bulb flickers, the rocket shakes, dark when queued */
.f-gadget.work .glow { animation: crew-glow .7s steps(2) infinite alternate; }
.f-gadget.work .body { animation: crew-shake .5s linear infinite; }
.f-gadget.queued .glow { opacity: .15; }

@keyframes crew-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.1); } }
@keyframes crew-scan { 0%, 100% { transform: translateX(-1.2px); } 50% { transform: translateX(1.2px); } }
@keyframes crew-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } }
@keyframes crew-glow { from { opacity: .3; } to { opacity: 1; } }
@keyframes crew-zz { 0% { opacity: 0; transform: translate(0, 0); } 30% { opacity: 1; } 100% { opacity: 0; transform: translate(6px, -9px); } }
@keyframes crew-twitch { 0%, 80%, 100% { transform: rotate(0); } 85% { transform: rotate(-9deg); } 92% { transform: rotate(7deg); } }
@keyframes crew-tilt { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes crew-breathe { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.03, .97); } }
@keyframes crew-wobble { 0%, 100% { transform: scale(1, 1) skewX(0); } 25% { transform: scale(1.06, .94) skewX(3deg); } 75% { transform: scale(.95, 1.06) skewX(-3deg); } }
@keyframes crew-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
@keyframes crew-twinkle { from { opacity: .2; transform: scale(.7); } to { opacity: 1; transform: scale(1.15); } }
@keyframes crew-shake { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(.6px, -.4px); } 75% { transform: translate(-.6px, .4px); } }

/* Nobody is looking: crew.js sets this while the tab is hidden. */
html.crew-paused .av * { animation-play-state: paused; }

/* Anyone who asked their computer for less motion gets still avatars; the
   moods (shut eyes, crossed eyes, dimmed screen) still show. */
@media (prefers-reduced-motion: reduce) {
  .av * { animation: none !important; }
}
