/* =============================================================================
   avatar.css — the living avatar (avatar studio spec §5.2): how the art's groups
   move, the reactions' moves and pop-outs, the sidekick's size rule, and motion
   off. avatar/live.js sets the classes; the art (avatar/art/) names the groups:
   av-fig (the whole figure), av-head, av-eyes, av-pet, av-tear.
   No move lifts the figure more than 6 of its 100 units, so tall hats stay in
   the circle (scripts/css-contract.test.ts holds the line).
   ============================================================================= */
@layer components {
  .sc-avatar .av-fig, .sc-avatar .av-head, .sc-avatar .av-pet, .sc-avatar .av-eyes, .sc-avatar .av-tear { transform-box: fill-box; }
  .sc-avatar .av-fig { transform-origin: 50% 100%; }
  .sc-avatar .av-head { transform-origin: 50% 92%; }
  .sc-avatar .av-pet { transform-origin: 50% 100%; }
  .sc-avatar .av-eyes { transform-origin: 50% 50%; }
  .sc-avatar .av-tear { animation: av-tear 0.9s ease-in infinite; }
  .sc-avatar .av-tear + .av-tear { animation-delay: 0.45s; }

  /* The sidekick is a speck below 44 px: lists show the face alone. */
  .avatar .av-pet { display: none; }
  .avatar--44 .av-pet, .avatar--48 .av-pet, .avatar--72 .av-pet, .avw--pet .av-pet, .av-tile__art .av-pet { display: inline; }

  /* A live avatar: the round crop plus a pop-out layer that may spill outside it. */
  .avw { position: relative; display: inline-block; flex: none; width: var(--s, 44px); height: var(--s, 44px); }
  .avw > .avatar { width: 100%; height: 100%; }
  .av-fx { position: absolute; inset: -35%; z-index: 2; pointer-events: none; }
  .av-fx svg { display: block; width: 100%; height: 100%; overflow: visible; }
  .av-tile__art { display: block; width: 100%; height: 100%; overflow: hidden; border-radius: 50%; }
  .av-tile__art svg { display: block; width: 100%; height: 100%; }

  /* Idle: a blink wherever an avatar is live; the slow bob only where nobody is thinking about a move. */
  .avw.is-alive:not([data-move]) .av-eyes { animation: av-blink 5.2s infinite; }
  .avw--idle.is-alive:not([data-move]) .av-fig { animation: av-bob 3.6s ease-in-out infinite; }

  /* The moves (reactions.js names them). */
  .avw[data-move="hop"] .av-fig { animation: av-hop 0.9s var(--ease) 1; }
  .avw[data-move="bighop"] .av-fig { animation: av-bighop 1.25s var(--ease) 1; }
  .avw[data-move="shake"] .av-fig { animation: av-shake 0.7s linear 1; }
  .avw[data-move="shiver"] .av-fig { animation: av-shiver 0.9s linear 1; }
  .avw[data-move="wobble"] .av-fig { animation: av-wobble 1.1s var(--ease) 1; }
  .avw[data-move="spin"] .av-fig { animation: av-spin 1s var(--ease) 1; transform-origin: 50% 58%; }
  .avw[data-move="faint"] .av-fig { animation: av-faint 1.9s var(--ease) 1; }
  .avw[data-move="sink"] .av-fig { animation: av-sink 1.5s var(--ease) 1; }
  .avw[data-move="peek"] .av-fig { animation: av-peek 1.7s var(--ease) 1; }
  .avw[data-move="puff"] .av-fig { animation: av-puff 1s cubic-bezier(0.34, 1.56, 0.64, 1) 1; transform-origin: 50% 80%; }
  .avw[data-move="nod"] .av-head { animation: av-nod 1.1s var(--ease) 1; }
  .avw[data-move="lean"] .av-fig { animation: av-lean 1.5s var(--ease) 1; }
  .avw[data-move="dance"] .av-fig { animation: av-dance 1.1s var(--ease) 2; }
  .avw[data-move="melt"] .av-fig { animation: av-melt 1.9s var(--ease) 1; }
  .avw[data-pet="hop"] .av-pet { animation: av-pet-hop 0.8s var(--ease) 1 0.1s; }
  .avw[data-pet="hide"] .av-pet { animation: av-pet-hide 1.5s var(--ease) 1; }
  .avw[data-pet="spin"] .av-pet { animation: av-pet-spin 0.9s var(--ease) 1 0.1s; transform-origin: 50% 50%; }

  @keyframes av-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.6px); } }
  @keyframes av-blink { 0%, 93%, 100% { transform: scaleY(1); } 96% { transform: scaleY(0.12); } }
  @keyframes av-tear { 0% { transform: translateY(-2px); opacity: 0; } 25% { opacity: 1; } 100% { transform: translateY(7px); opacity: 0; } }
  @keyframes av-hop { 0% { transform: none; } 15% { transform: scale(1.06, 0.92); } 42% { transform: translateY(-6px) scale(0.97, 1.03); } 66% { transform: translateY(0) scale(1.08, 0.9); } 82% { transform: scale(0.98, 1.02); } 100% { transform: none; } }
  @keyframes av-bighop { 0% { transform: none; } 10% { transform: scale(1.06, 0.88); } 30% { transform: translateY(-6px) scale(0.94) rotate(-6deg); } 50% { transform: translateY(0) scale(1.06, 0.9); } 63% { transform: translateY(-4px) scale(0.96) rotate(6deg); } 80% { transform: translateY(0) scale(1.03, 0.95); } 100% { transform: none; } }
  @keyframes av-shake { 0%, 100% { transform: none; } 15% { transform: translateX(-5px) rotate(-5deg); } 30% { transform: translateX(5px) rotate(5deg); } 45% { transform: translateX(-4px) rotate(-4deg); } 60% { transform: translateX(4px) rotate(3deg); } 75% { transform: translateX(-2px); } }
  @keyframes av-shiver { 0%, 100% { transform: none; } 10%, 30%, 50%, 70%, 90% { transform: translateX(-1.6px); } 20%, 40%, 60%, 80% { transform: translateX(1.6px); } }
  @keyframes av-wobble { 0%, 100% { transform: none; } 20% { transform: rotate(-14deg); } 40% { transform: rotate(11deg); } 60% { transform: rotate(-7deg); } 80% { transform: rotate(4deg); } }
  @keyframes av-spin { 0% { transform: none; } 70% { transform: rotate(380deg); } 85% { transform: rotate(352deg); } 100% { transform: rotate(360deg); } }
  @keyframes av-faint { 0% { transform: none; } 18% { transform: rotate(8deg); } 42% { transform: rotate(-84deg) translateY(6px); } 50% { transform: rotate(-76deg) translateY(4px); } 57%, 80% { transform: rotate(-84deg) translateY(6px); } 100% { transform: none; } }
  @keyframes av-sink { 0% { transform: none; } 25%, 72% { transform: translateY(36px); } 100% { transform: none; } }
  @keyframes av-peek { 0% { transform: none; } 20% { transform: translateY(36px); } 42%, 72% { transform: translateY(15px); } 100% { transform: none; } }
  @keyframes av-puff { 0%, 100% { transform: none; } 30%, 70% { transform: scale(1.08); } 50% { transform: scale(1.11); } }
  @keyframes av-nod { 0%, 100% { transform: none; } 20% { transform: rotate(7deg); } 40% { transform: none; } 60% { transform: rotate(7deg); } 80% { transform: none; } }
  @keyframes av-lean { 0%, 100% { transform: none; } 22%, 76% { transform: rotate(-12deg) translateX(-3px); } }
  @keyframes av-dance { 0%, 100% { transform: none; } 25% { transform: translateY(-5px) rotate(-11deg); } 50% { transform: none; } 75% { transform: translateY(-5px) rotate(11deg); } }
  @keyframes av-melt { 0% { transform: none; } 35%, 75% { transform: scale(1.22, 0.62); } 100% { transform: none; } }
  @keyframes av-pet-hop { 0%, 100% { transform: none; } 35% { transform: translateY(-9px); } 55% { transform: none; } 72% { transform: translateY(-4px); } }
  @keyframes av-pet-hide { 0%, 100% { transform: none; } 25%, 75% { transform: translateY(24px); } }
  @keyframes av-pet-spin { 0% { transform: none; } 80%, 100% { transform: rotate(360deg); } }

  /* The pop-outs (avatar/fx.js draws them; each part may wait --d). */
  .fx-p { transform-box: fill-box; transform-origin: center; animation-fill-mode: both; animation-delay: var(--d, 0ms); }
  .fx-pop { animation-name: fx-pop; animation-duration: 1.3s; animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
  .fx-rise { animation-name: fx-rise; animation-duration: 1.6s; animation-timing-function: ease-out; }
  .fx-fall { animation-name: fx-fall; animation-duration: 1.4s; animation-timing-function: ease-in; }
  .fx-burst { animation-name: fx-burst; animation-duration: 1.7s; animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1); }
  .fx-swirl { animation-name: fx-swirl; animation-duration: 1s; animation-timing-function: ease-out; transform-box: view-box; transform-origin: 50px 50px; }
  @keyframes fx-pop { 0% { opacity: 0; transform: scale(0.2) rotate(-30deg); } 25% { opacity: 1; transform: scale(1.2); } 40% { transform: scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: scale(0.9); } }
  @keyframes fx-rise { 0% { opacity: 0; transform: translateY(10px) scale(0.6); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(-36px) scale(1.1); } }
  @keyframes fx-fall { 0% { opacity: 0; transform: translateY(-6px); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(22px); } }
  @keyframes fx-burst { 0% { opacity: 0; transform: translate(0, 0) rotate(0); } 8% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--r)); } }
  @keyframes fx-swirl { 0% { opacity: 0; transform: rotate(-90deg); } 30% { opacity: 1; } 100% { opacity: 0; transform: rotate(200deg); } }

  /* Motion off — the device setting (is-still) or the OS. `none`, not a short
     duration: base.css's clamp would end a pop-out at its last, invisible frame.
     The face still changes and the pop-out stands still where it is drawn. */
  .avw.is-still, .avw.is-still * { animation: none !important; }
  @media (prefers-reduced-motion: reduce) {
    .avw, .avw * { animation: none !important; }
  }
}
