/* Mochi vivante (spec 008, docs/DESIGN.md « Mochi, la mascotte ») : les animations posées sur
   les groupes que rend mochi.js. Le dessin au repos est celui de l'image fixe.

   Jamais plus de deux mouvements à la fois :
   - la respiration est continue (sauf pendant un geste en deux parties, qui la remplace) ;
   - le second mouvement se partage dans un cycle de 6 s : le geste de l'état dans sa première
     moitié, la queue dans la seconde ;
   - le clignement et l'oreille, posés par commun.js (data-geste), suspendent ces deux-là le temps
     de se faire. */

.m-souffle, .m-perso, .m-tete, .m-salut, .m-yeux, .m-bulle, .m-balle, .m-etincelle, .m-page,
.m-queue, .m-oreille-g, .m-rubans, .m-x-pancarte, .m-x-point { transform-box: fill-box; }

/* Au repos, dans tous les états */
.m-souffle { transform-origin: 50% 100%; animation: m-souffle 3.6s ease-in-out infinite; }
@keyframes m-souffle { 50% { transform: scaleY(1.02); } }
.m-queue { transform-origin: 0% 100%; animation: m-queue 6s ease-in-out infinite; }
@keyframes m-queue { 0%, 52%, 96%, 100% { transform: none; } 64% { transform: rotate(-5deg); } 78% { transform: rotate(4deg); } 88% { transform: rotate(-2deg); } }
.m-yeux { transform-origin: 50% 50%; }
.mochi[data-geste~="cligne"] .m-yeux { animation: m-cligne .18s ease-in-out; }
@keyframes m-cligne { 50% { transform: scaleY(.1); } }
.m-oreille-g { transform-origin: 70% 100%; }
.mochi[data-geste~="oreille"] .m-oreille-g { animation: m-fremit .45s .25s ease-in-out; }
@keyframes m-fremit { 30% { transform: rotate(-7deg); } 65% { transform: rotate(3deg); } }
.mochi[data-geste] svg [class]:not(.m-souffle, .m-yeux, .m-oreille-g, .m-ravie .m-perso, .m-surprise .m-perso) {
  animation-play-state: paused;
}

/* Un geste en deux parties tient lieu de second mouvement : la respiration s'y tait. */
.m-ravie .m-souffle, .m-surprise .m-souffle, .m-victoire .m-souffle, .m-courage .m-souffle { animation: none; }

/* Bonjour : la patte du maneki-neko. */
.m-salut { transform-origin: 50% 100%; animation: m-salut 6s ease-in-out infinite; }
@keyframes m-salut { 0%, 45%, 100% { transform: none; } 9%, 27% { transform: rotate(-14deg); } 18% { transform: rotate(6deg); } 36% { transform: rotate(4deg); } }

/* Cachée : monte et redescend derrière le bord ; s'abaisse pendant une sélection. */
.m-cachee .m-perso { animation: m-guette 6s ease-in-out infinite; }
@keyframes m-guette { 0%, 45%, 100% { transform: none; } 12% { transform: translateY(-8px); } 24% { transform: none; } 34% { transform: translateY(14px); } }
.m-pose { transition: transform .25s ease-out; }
.selection-en-cours .m-pose { transform: translateY(26px); }

/* Ravie : bondit hors du bord, les étincelles scintillent, puis se recache (jeu.js). */
.m-ravie .m-perso { transform-origin: 50% 100%; animation: m-bondit 1.3s ease-in-out; }
@keyframes m-bondit { 30% { transform: translateY(-34px); } 45% { transform: translateY(-30px); } }
.m-ravie .m-etincelle { transform-origin: 50% 50%; animation: m-scintille .65s ease-in-out 2; }
.m-ravie .m-etincelle:nth-child(2) { animation-delay: .15s; }
.m-ravie .m-etincelle:nth-child(3) { animation-delay: .3s; }
@keyframes m-scintille { 50% { transform: scale(.4) rotate(45deg); opacity: .5; } }

/* Indice : la pancarte ヒント se balance. */
.m-x-pancarte { transform-origin: 50% 0%; animation: m-balance 6s ease-in-out infinite; }
@keyframes m-balance { 0%, 45%, 100% { transform: none; } 11% { transform: rotate(5deg); } 22% { transform: rotate(-4deg); } 33% { transform: rotate(2deg); } }

/* Surprise : sursaut (écrasement puis étirement), le « ! » surgit. */
.m-surprise .m-perso { transform-origin: 50% 100%; animation: m-sursaut .7s ease-out; }
@keyframes m-sursaut { 25% { transform: scale(1.08, .9); } 60% { transform: scale(.96, 1.07); } }
.m-x-point { transform-origin: 50% 100%; animation: m-surgit .45s .2s ease-out backwards; }
@keyframes m-surgit { from { transform: scale(0); opacity: 0; } 70% { transform: scale(1.25); } }

/* Victoire : sautille pattes levées, les confettis tombent. */
.m-victoire .m-perso { animation: m-sautille 6s ease-in-out infinite; }
@keyframes m-sautille { 0%, 16%, 32%, 45%, 100% { transform: none; } 8%, 24% { transform: translateY(-10px); } }
.m-confetti { --chute: 44px; animation: m-tombe 6s ease-in infinite; }
.m-confetti:nth-child(odd) { --chute: 30px; }
@keyframes m-tombe { 0%, 45%, 100% { transform: none; opacity: 1; } 36% { transform: translateY(var(--chute)); opacity: 0; } 37% { transform: translateY(-10px); opacity: 0; } }

/* Courage : hoche la tête, les rubans du bandeau flottent. */
.m-courage .m-tete { transform-origin: 50% 100%; animation: m-hoche 6s ease-in-out infinite; }
@keyframes m-hoche { 0%, 18%, 36%, 45%, 100% { transform: none; } 9%, 27% { transform: translateY(5px) rotate(-2deg); } }
.m-rubans { transform-origin: 0% 50%; animation: m-flotte 6s ease-in-out infinite; }
@keyframes m-flotte { 0%, 45%, 100% { transform: none; } 12%, 30% { transform: rotate(-9deg); } 21% { transform: rotate(5deg); } }

/* Studieuse : penche la tête au-dessus du livre, puis tourne une page. */
.m-studieuse .m-tete { transform-origin: 50% 100%; animation: m-penche 6s ease-in-out infinite; }
@keyframes m-penche { 0%, 22%, 100% { transform: none; } 6%, 16% { transform: rotate(-6deg); } }
.m-page { transform-origin: 0% 50%; animation: m-page 6s ease-in-out infinite; }
@keyframes m-page { 0%, 24% { transform: none; opacity: 0; } 26% { transform: none; opacity: 1; } 40% { transform: scaleX(-1); opacity: 1; } 42%, 100% { transform: scaleX(-1); opacity: 0; } }

/* Contente : penche la tête du côté du clin d'œil. */
.m-contente .m-tete { transform-origin: 50% 100%; animation: m-clin 6s ease-in-out infinite; }
@keyframes m-clin { 0%, 30%, 100% { transform: none; } 8%, 20% { transform: rotate(5deg); } }

/* Inquiète : la goutte glisse le long de la tête. */
.m-x-goutte { animation: m-glisse 6s ease-in infinite; }
@keyframes m-glisse { 0%, 45%, 100% { transform: none; opacity: 1; } 34% { transform: translateY(14px); opacity: 0; } 35% { transform: translateY(-4px); opacity: 0; } }

/* Endormie : respiration lente, les z montent, puis la bulle gonfle ; la queue dort. */
.m-endormie .m-souffle { animation: m-souffle-lent 5s ease-in-out infinite; }
@keyframes m-souffle-lent { 50% { transform: scaleY(1.035); } }
.m-endormie .m-queue { animation: none; }
.m-z { --o: .7; animation: m-monte 6s ease-out infinite; }
.m-z + .m-z { --o: .5; }
@keyframes m-monte { 0%, 45%, 100% { transform: none; opacity: var(--o); } 36% { transform: translate(6px, -16px); opacity: 0; } 37% { transform: translateY(6px); opacity: 0; } }
.m-bulle { transform-origin: 0% 50%; animation: m-bulle 6s ease-in-out infinite; }
@keyframes m-bulle { 0%, 50%, 96%, 100% { transform: none; } 73% { transform: scale(1.35); } }

/* Joueuse : la pelote roule un peu. */
.m-balle { transform-origin: 50% 50%; animation: m-roule 6s ease-in-out infinite; }
@keyframes m-roule { 0%, 45%, 100% { transform: none; } 15% { transform: translateX(5px) rotate(28deg); } 30% { transform: translateX(-3px) rotate(-12deg); } }

/* Mouvement réduit : Mochi figée dans l'état du moment ; elle apparaît en fondu. */
@media (prefers-reduced-motion: reduce) {
  .mochi svg * { animation: none !important; }
  .mochi svg { animation: m-fondu var(--court, .2s) ease-out; }
}
@keyframes m-fondu { from { opacity: 0; } }
