/* characters.css – Animationen des Character-Systems (siehe js/characters.js).
   Zustand steht in data-anim am <svg class="cv">:  auto | idle | dance | wave | jump | celebrate | reaction
   auto = idle, solange keine Musik laeuft (body.playing), sonst dance. Tempo: --beat (Sekunden pro Schlag, am Vorfahren setzbar), Versatz: --o (negativ). */

.av { position: absolute; width: 6.4em; height: 9.17em; transform-origin: 50% 100%; transform: scale(var(--s, 1)); transition: left .6s ease, bottom .6s ease, transform .6s ease, opacity .4s ease; animation: arrive .5s ease-out; }
@keyframes arrive { from { opacity: 0; transform: scale(calc(var(--s, 1) * .5)) translateY(-1.5em); } }
.av.leaving { opacity: 0; pointer-events: none; }
#crowd .av, #dj.av { cursor: pointer; }
.av .cv { display: block; width: 100%; height: 100%; overflow: visible; --t: var(--beat, .55s); }
.cv * { transform-box: fill-box; }
.cv .p-body { transform-origin: 50% 100%; }
.cv .p-head { transform-origin: 50% 92%; }
.cv .p-arml, .cv .p-armr { transform-origin: 50% 6%; }
.cv .p-legl, .cv .p-legr { transform-origin: 50% 10%; }
.cv .p-eyes { transform-origin: 50% 50%; }
.cv .p-tail { transform-origin: 12% 88%; }
.cv .shadow { transform-origin: 50% 50%; }
.cv .fx-excl { transform-origin: 50% 100%; }

/* Gesichtsausdruecke (Standard: offene Augen + Laecheln) */
.cv .eyes-happy, .cv .mouth-open, .cv .mouth-o, .cv .fx-conf, .cv .fx-excl { display: none; }
:is(.cv[data-anim=wave], .cv[data-anim=celebrate], .cv[data-anim=jump]) .eyes-open { display: none; }
:is(.cv[data-anim=wave], .cv[data-anim=celebrate], .cv[data-anim=jump]) .eyes-happy { display: inline; }
:is(.cv[data-anim=celebrate], .cv[data-anim=jump], .cv[data-anim=dance], body.playing .cv[data-anim=auto]) .mouth-smile { display: none; }
:is(.cv[data-anim=celebrate], .cv[data-anim=jump], .cv[data-anim=dance], body.playing .cv[data-anim=auto]) .mouth-open { display: inline; }
.cv[data-anim=reaction] .mouth-smile { display: none; }
.cv[data-anim=reaction] .mouth-o, .cv[data-anim=reaction] .fx-excl { display: inline; }
.cv[data-anim=celebrate] .fx-conf { display: inline; }

/* ---------- Idle (leichtes Atmen, Blinzeln, Schwanz) ---------- */
:is(.cv[data-anim=idle], body:not(.playing) .cv[data-anim=auto]) .p-body { animation: i-body 2.8s ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=idle], body:not(.playing) .cv[data-anim=auto]) .p-head { animation: i-head 2.8s ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=idle], body:not(.playing) .cv[data-anim=auto]) .p-arml { animation: i-arml 2.8s ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=idle], body:not(.playing) .cv[data-anim=auto]) .p-armr { animation: i-armr 2.8s ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=idle], body:not(.playing) .cv[data-anim=auto]) .p-eyes { animation: blink 4.6s linear var(--o, 0s) infinite; }
.cv .p-tail { animation: wag 2.4s ease-in-out var(--o, 0s) infinite alternate; }
@keyframes i-body { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.012, 1.03); } }
@keyframes i-head { 0%, 100% { transform: translateY(0) rotate(0); } 50% { transform: translateY(1px) rotate(-1.4deg); } }
@keyframes i-arml { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(3deg); } }
@keyframes i-armr { 0%, 100% { transform: rotate(0); } 50% { transform: rotate(-3deg); } }
@keyframes blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.08); } }
@keyframes wag { from { transform: rotate(-8deg); } to { transform: rotate(10deg); } }

/* ---------- Dance (im Takt --t, Schwung von Koerper, Kopf, Armen, Beinen) ---------- */
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-body { animation: d-body calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-head { animation: d-head calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-arml { animation: d-arml calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-armr { animation: d-armr calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-legl { animation: d-legl calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-legr { animation: d-legr calc(var(--t) * 2) ease-in-out var(--o, 0s) infinite; }
:is(.cv[data-anim=dance], body.playing .cv[data-anim=auto]) .p-tail { animation: wag calc(var(--t)) ease-in-out var(--o, 0s) infinite alternate; }
@keyframes d-body { 0%, 100% { transform: translateY(0) rotate(-3deg) scale(1.03, .97); } 25% { transform: translateY(-5px) rotate(0) scale(.98, 1.03); }
                    50% { transform: translateY(0) rotate(3deg) scale(1.03, .97); } 75% { transform: translateY(-5px) rotate(0) scale(.98, 1.03); } }
@keyframes d-head { 0%, 100% { transform: rotate(5deg); } 50% { transform: rotate(-5deg); } }
@keyframes d-arml { 0%, 100% { transform: rotate(140deg); } 50% { transform: rotate(15deg); } }
@keyframes d-armr { 0%, 100% { transform: rotate(-15deg); } 50% { transform: rotate(-140deg); } }
@keyframes d-legl { 0%, 100% { transform: translateY(-3px); } 50% { transform: translateY(0); } }
@keyframes d-legr { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

/* ---------- Wave ---------- */
.cv[data-anim=wave] .p-armr { animation: w-armr 1.9s ease-in-out both; }
.cv[data-anim=wave] .p-head { animation: w-head 1.9s ease-in-out both; }
.cv[data-anim=wave] .p-body { animation: i-body 1.9s ease-in-out both; }
@keyframes w-armr { 0% { transform: rotate(0); } 14% { transform: rotate(-145deg); } 28% { transform: rotate(-120deg); } 42% { transform: rotate(-155deg); }
                    56% { transform: rotate(-120deg); } 70% { transform: rotate(-155deg); } 84% { transform: rotate(-145deg); } 100% { transform: rotate(0); } }
@keyframes w-head { 0%, 100% { transform: rotate(0); } 20%, 80% { transform: rotate(5deg); } }

/* ---------- Jump ---------- */
.cv[data-anim=jump] .p-body { animation: j-body .85s cubic-bezier(.3, .1, .4, 1) both; }
.cv[data-anim=jump] .p-arml { animation: j-arml .85s ease-in-out both; }
.cv[data-anim=jump] .p-armr { animation: j-armr .85s ease-in-out both; }
.cv[data-anim=jump] .shadow { animation: j-shadow .85s ease-in-out both; }
@keyframes j-body { 0% { transform: translateY(0) scale(1.08, .9); } 15% { transform: translateY(0) scale(1.09, .87); } 40% { transform: translateY(-34px) scale(.94, 1.1); }
                    62% { transform: translateY(-34px) scale(.98, 1.04); } 88% { transform: translateY(0) scale(1.1, .86); } 100% { transform: translateY(0) scale(1); } }
@keyframes j-arml { 0%, 15% { transform: rotate(-10deg); } 40%, 62% { transform: rotate(140deg); } 100% { transform: rotate(0); } }
@keyframes j-armr { 0%, 15% { transform: rotate(10deg); } 40%, 62% { transform: rotate(-140deg); } 100% { transform: rotate(0); } }
@keyframes j-shadow { 0%, 100% { transform: scale(1); opacity: 1; } 40%, 62% { transform: scale(.6); opacity: .4; } }

/* ---------- Celebrate (zwei Spruenge, Arme hoch, Konfetti) ---------- */
.cv[data-anim=celebrate] .p-body { animation: c-body 2.3s ease-in-out both; }
.cv[data-anim=celebrate] .p-arml { animation: c-arml 2.3s ease-in-out both; }
.cv[data-anim=celebrate] .p-armr { animation: c-armr 2.3s ease-in-out both; }
.cv[data-anim=celebrate] .p-head { animation: c-head 2.3s ease-in-out both; }
.cv[data-anim=celebrate] .fx-conf > * { animation: conf 1.5s ease-out both; }
.cv .fx-conf > :nth-child(1) { --dx: -22px; animation-delay: 0s !important; }   .cv .fx-conf > :nth-child(2) { --dx: 12px; animation-delay: .12s !important; }
.cv .fx-conf > :nth-child(3) { --dx: -8px; animation-delay: .25s !important; }  .cv .fx-conf > :nth-child(4) { --dx: 26px; animation-delay: .05s !important; }
.cv .fx-conf > :nth-child(5) { --dx: -30px; animation-delay: .3s !important; }  .cv .fx-conf > :nth-child(6) { --dx: 6px; animation-delay: .18s !important; }
.cv .fx-conf > :nth-child(7) { --dx: 30px; animation-delay: .4s !important; }   .cv .fx-conf > :nth-child(8) { --dx: -14px; animation-delay: .08s !important; }
@keyframes c-body { 0%, 100% { transform: translateY(0) scale(1); } 8% { transform: translateY(0) scale(1.08, .9); } 24% { transform: translateY(-28px) scale(.95, 1.08); }
                    40% { transform: translateY(0) scale(1.08, .9); } 56% { transform: translateY(-28px) scale(.95, 1.08); } 72% { transform: translateY(0) scale(1.06, .92); } 84% { transform: translateY(0) scale(1); } }
@keyframes c-arml { 0% { transform: rotate(0); } 12% { transform: rotate(140deg); } 30% { transform: rotate(160deg); } 50% { transform: rotate(135deg); } 70% { transform: rotate(160deg); } 90% { transform: rotate(140deg); } 100% { transform: rotate(0); } }
@keyframes c-armr { 0% { transform: rotate(0); } 12% { transform: rotate(-140deg); } 30% { transform: rotate(-160deg); } 50% { transform: rotate(-135deg); } 70% { transform: rotate(-160deg); } 90% { transform: rotate(-140deg); } 100% { transform: rotate(0); } }
@keyframes c-head { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } 75% { transform: rotate(-5deg); } }
@keyframes conf { 0% { opacity: 0; transform: translate(0, 24px) rotate(0); } 15% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--dx, 0), -34px) rotate(300deg); } }

/* ---------- Reaction (ueberrascht: Huepfer, grosse Augen, Ausrufezeichen) ---------- */
.cv[data-anim=reaction] .p-body { animation: r-body 1.25s ease-out both; }
.cv[data-anim=reaction] .p-head { animation: r-head 1.25s ease-out both; }
.cv[data-anim=reaction] .p-eyes { animation: r-eyes 1.25s ease-out both; }
.cv[data-anim=reaction] .p-arml { animation: r-arml 1.25s ease-out both; }
.cv[data-anim=reaction] .p-armr { animation: r-armr 1.25s ease-out both; }
.cv[data-anim=reaction] .fx-excl { animation: r-excl 1.25s ease-out both; }
@keyframes r-body { 0% { transform: none; } 12% { transform: translateY(-9px) scale(.97, 1.05); } 28% { transform: translateY(0) scale(1.05, .95); } 45%, 100% { transform: none; } }
@keyframes r-head { 0% { transform: none; } 15% { transform: scale(1.08) rotate(-3deg); } 30% { transform: scale(1.06) rotate(3deg); } 45% { transform: scale(1.05) rotate(-2deg); } 62%, 100% { transform: none; } }
@keyframes r-eyes { 0% { transform: none; } 10%, 78% { transform: scale(1.22); } 100% { transform: none; } }
@keyframes r-arml { 0%, 100% { transform: rotate(0); } 15%, 70% { transform: rotate(38deg); } }
@keyframes r-armr { 0%, 100% { transform: rotate(0); } 15%, 70% { transform: rotate(-38deg); } }
@keyframes r-excl { 0% { transform: scale(0); opacity: 1; } 15% { transform: scale(1.35); } 30%, 82% { transform: scale(1); opacity: 1; } 100% { transform: scale(.8); opacity: 0; } }

/* ---------- Epic: funkelnde Sterne ---------- */
.cv .p-sparkle { transform-origin: center; animation: tw 2.2s ease-in-out infinite; }
@keyframes tw { 0%, 100% { opacity: .15; transform: scale(.5); } 50% { opacity: 1; transform: scale(1); } }

/* ---------- Detailstufen (Teilnehmerzahl): mid = ohne Blinzeln/Schwanz/Funkeln, low = nur Koerper ---------- */
[data-lod=mid] .cv .p-eyes, [data-lod=mid] .cv .p-tail, [data-lod=mid] .cv .p-sparkle, [data-lod=mid] .cv .p-fx { animation: none !important; }
[data-lod=low] .cv *:not(.p-body) { animation: none !important; }
[data-lod=low] .cv .p-sparkle, [data-lod=low] .cv .fx-conf { display: none; }
[data-lod=low] .cv .shadow { display: none; }

/* Respektiert die Systemeinstellung "Bewegung reduzieren"; <html data-motion="full"> hebt das auf (Test/spaetere App-Einstellung). */
@media (prefers-reduced-motion: reduce) { html:not([data-motion=full]) .cv * { animation: none !important; } }

/* ---------- Kosmetik-Effekte (items.js, Slot "effect"): steigende Symbole; bei vielen Figuren aus (LOD) ---------- */
.cv .eff-rise { animation: eff-rise 3.2s ease-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes eff-rise { 0% { opacity: 0; transform: translateY(10px); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(-38px); } }
[data-lod=mid] .cv .p-eff, [data-lod=low] .cv .p-eff { display: none; }
