/* avatar-kit.css — motion for the avatars from avatar-kit.js.
   States are classes on any ancestor of the <svg>:
     .is-walking   bouncy step, arms swing, a slight lean
     .is-talking   the mouth opens and closes
     .is-waving    the right arm waves
     .is-jumping, .is-dancing, .is-clapping   the other gestures
     .face-left    mirrored, to walk the other way
   Idle (breathing, blinking) runs all the time.

   The figure is drawn in a 768-unit space scaled into the 200×300 SVG, so
   moves on body parts are in those units, and each part carries its own pivot
   as an inline transform-origin. */

.ak { display: block; width: 100%; height: 100%; overflow: visible; }
.ak * { transform-box: view-box; }
/* A portrait is a crop; the figure must not spill out of it. */
.ak-portrait { overflow: hidden; }

.ak-root { transform-origin: 100px 288px; animation: ak-breathe 3.6s ease-in-out infinite; }
@keyframes ak-breathe {
    0%, 100% { transform: scale(1, 1); }
    50% { transform: scale(1.012, 0.988); }
}

.ak-tilt { transform-origin: 100px 288px; transition: transform 0.25s ease; }
.ak-head { animation: ak-head 3.6s ease-in-out infinite; }
@keyframes ak-head {
    0%, 100% { transform: rotate(0); }
    50% { transform: translateY(6px) rotate(-1.4deg); }
}

/* Blinking swaps in the drawing's own closed eyes for a moment. */
.ak-eyes-shut { opacity: 0; animation: ak-shut 5.2s steps(1) infinite; animation-delay: var(--ak-blink, 0s); }
.ak-eyes-open { animation: ak-open 5.2s steps(1) infinite; animation-delay: var(--ak-blink, 0s); }
@keyframes ak-shut { 0% { opacity: 0; } 94% { opacity: 1; } 97% { opacity: 0; } }
@keyframes ak-open { 0% { opacity: 1; } 94% { opacity: 0; } 97% { opacity: 1; } }

.ak-mouth-open { opacity: 0; }

/* Walking: two steps per cycle, each foot lifting in turn. */
.is-walking .ak-root { animation: ak-bounce 0.5s ease-in-out infinite; }
@keyframes ak-bounce {
    0%, 50%, 100% { transform: translateY(0); }
    25%, 75% { transform: translateY(-5px); }
}
.is-walking .ak-tilt { transform: rotate(4deg); }
.is-walking .ak-leg-l { animation: ak-lift 0.5s ease-in-out infinite; }
.is-walking .ak-leg-r { animation: ak-lift 0.5s ease-in-out infinite; animation-delay: -0.25s; }
@keyframes ak-lift {
    0%, 50%, 100% { transform: translateY(0); }
    /* Negative: the lifted foot swings forward, the way the figure leans. */
    25% { transform: translateY(-36px) rotate(-8deg); }
}
.is-walking .ak-arm-l { animation: ak-swing 0.5s ease-in-out infinite; }
.is-walking .ak-arm-r { animation: ak-swing 0.5s ease-in-out infinite; animation-delay: -0.25s; }
@keyframes ak-swing {
    0%, 100% { transform: rotate(14deg); }
    50% { transform: rotate(-14deg); }
}
.is-walking .ak-head { animation: none; }

/* Talking: the mouth flaps while a speech bubble is up. */
.is-talking .ak-mouth-open { animation: ak-talk 0.32s steps(1) infinite; }
.is-talking .ak-mouth-rest { animation: ak-talk-rest 0.32s steps(1) infinite; }
@keyframes ak-talk { 50% { opacity: 1; } }
@keyframes ak-talk-rest { 50% { opacity: 0; } }

/* Waving: the right arm goes up and swings. */
.is-waving .ak-arm-r { animation: ak-wave 0.9s ease-in-out infinite; }
@keyframes ak-wave {
    0%, 100% { transform: rotate(-150deg); }
    50% { transform: rotate(-118deg); }
}

.face-left .ak { transform: scaleX(-1); }

/* ── In a room (.ak-crowd on the figure's box) ─────────────────────────────
   Up to 50 figures at once. Anything animating inside an SVG makes the
   browser redraw that figure, outline filter and all, every frame: 50 of
   them halve the frame rate on a machine without a GPU. So in a room the
   breathing moves to the box (a transform the GPU does on the finished
   picture), the head keeps still, and blinking comes from AvatarKit.blink():
   one figure at a time, two redraws per blink, nothing in between. Walking
   and talking still move parts, but only while someone walks or talks. */
.ak-crowd { transform-origin: 50% 96%; animation: ak-crowd-breathe 3.6s ease-in-out infinite; will-change: transform; }
@keyframes ak-crowd-breathe {
    0%, 100% { transform: scale(1, 1); }
    50% { transform: scale(1.012, 0.988); }
}
.ak-crowd .ak-root, .ak-crowd .ak-head, .ak-crowd .ak-eyes-shut, .ak-crowd .ak-eyes-open { animation: none; }
.ak-crowd.ak-blink .ak-eyes-shut { opacity: 1; }
.ak-crowd.ak-blink .ak-eyes-open { opacity: 0; }
.is-walking .ak-crowd { animation: none; }
.is-walking .ak-crowd .ak-root { animation: ak-bounce 0.5s ease-in-out infinite; }

/* ── Gestures (a class on any ancestor, for a moment) ─────────────────────
   Written after the crowd rules on purpose: the same specificity, so these
   win while a gesture is on. */
.is-jumping .ak-crowd, .is-dancing .ak-crowd, .is-clapping .ak-crowd { animation: none; }

/* Jumping: two hops, knees giving a little on landing. */
.is-jumping .ak-root { animation: ak-jump 0.6s cubic-bezier(0.3, 0, 0.4, 1) 2; }
@keyframes ak-jump {
    0%, 100% { transform: translateY(0) scale(1, 1); }
    12% { transform: translateY(0) scale(1.04, 0.94); }
    50% { transform: translateY(-34px) scale(0.97, 1.04); }
    88% { transform: translateY(0) scale(1.05, 0.95); }
}
.is-jumping .ak-arm-l { animation: ak-jump-arm-l 0.6s ease-in-out 2; }
.is-jumping .ak-arm-r { animation: ak-jump-arm-r 0.6s ease-in-out 2; }
@keyframes ak-jump-arm-l { 50% { transform: rotate(60deg); } }
@keyframes ak-jump-arm-r { 50% { transform: rotate(-60deg); } }

/* Dancing: sway, bounce on the beat, arms up in turn. */
.is-dancing .ak-root { animation: ak-bounce 0.5s ease-in-out infinite; }
.is-dancing .ak-tilt { animation: ak-sway 1s ease-in-out infinite; }
@keyframes ak-sway {
    0%, 100% { transform: rotate(-6deg); }
    50% { transform: rotate(6deg); }
}
.is-dancing .ak-arm-l { animation: ak-dance-l 1s ease-in-out infinite; }
.is-dancing .ak-arm-r { animation: ak-dance-r 1s ease-in-out infinite; }
@keyframes ak-dance-l { 0%, 100% { transform: rotate(150deg); } 50% { transform: rotate(20deg); } }
@keyframes ak-dance-r { 0%, 100% { transform: rotate(-20deg); } 50% { transform: rotate(-150deg); } }
.is-dancing .ak-leg-l { animation: ak-lift 1s ease-in-out infinite; }
.is-dancing .ak-leg-r { animation: ak-lift 1s ease-in-out infinite; animation-delay: -0.5s; }

/* Clapping: the bent-arm pose (avatar-kit.js clapArms) replaces the hanging
   arms; the forearms swing in until the hands meet, a little bounce on each. */
.ak-clap { opacity: 0; }
.is-clapping .ak-clap { opacity: 1; }
.is-clapping .ak-arm { opacity: 0; }
.is-clapping .ak-clap-fore { animation: ak-clap 0.36s ease-in-out infinite; }
@keyframes ak-clap {
    0%, 100% { transform: rotate(-15deg); }
    45%, 55% { transform: rotate(0deg); }
}
.is-clapping .ak-root { animation: ak-bounce 0.36s ease-in-out infinite; }
.is-clapping .ak-mouth-open { opacity: 1; }
.is-clapping .ak-mouth-rest { opacity: 0; }

/* The pet: a wagging tail; hops along when the figure walks. In a crowded
   room the tail keeps still (anything moving inside an SVG redraws it). */
.ak-pet-tail { animation: ak-wag 0.9s ease-in-out infinite; }
@keyframes ak-wag { 0%, 100% { transform: rotate(-10deg); } 50% { transform: rotate(14deg); } }
.ak-crowd .ak-pet-tail { animation: none; }
.is-walking .ak-pet { animation: ak-pet-hop 0.25s ease-in-out infinite; }
.is-walking .ak-pet-tail { animation: ak-wag 0.3s ease-in-out infinite; }
@keyframes ak-pet-hop { 50% { transform: translateY(-4px); } }

@media (prefers-reduced-motion: reduce) {
    .ak-root, .ak-head, .ak-eyes-shut, .ak-eyes-open, .ak-crowd, .ak-pet, .ak-pet-tail { animation: none !important; }
}
