/* MAIE Motion-Kit · motion.css · Stand 27.10.2026
   Charakter: "Bloom" (ruhig, weich, aus der Unschärfe scharf) als Grundton.
   "Glas" (Tiefe, Milchglas, wandernde Lichtflecken) für Jarvis-Dashboards.
   "Netz" (Punkte verbinden sich, roter Kern) für Organigramm und Denkweg.
   Regel 1: Nur das Rote bewegt sich, pulst, zählt. Schwarz und Grau stehen still.
   Ausnahme Puls: In Status-Karten (Organigramm, Architektur) pulst JEDER Knoten, an dem gerade ein Agent arbeitet.
   Dort ist der Puls Information, nicht Hervorhebung. In allen anderen Ansichten höchstens ein .mai-pulse.
   Regel 2: Eintritt 0,4–0,6 s · Zustandswechsel 0,2–0,3 s · Schleifen 1,5–6 s.
   Regel 3: Kurve cubic-bezier(.2,.8,.2,1) für Eintritt, ease für Zustände, linear nur für Fließpunkte.
   Regel 4: prefers-reduced-motion → alles steht, nichts fehlt. */

:root {
  --mai-ease-in: cubic-bezier(.2,.8,.2,1);
  --mai-ease-pop: cubic-bezier(.3,1.3,.4,1);
  --mai-t-enter: .5s;
  --mai-t-state: .25s;
}

/* ---------- Keyframes ---------- */
@keyframes mai-rise   { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }
@keyframes mai-pop    { 0% { opacity: 0; transform: scale(.7) } 60% { transform: scale(1.06) } 100% { opacity: 1; transform: none } }
@keyframes mai-bloom  { from { opacity: 0; filter: blur(18px); transform: translateY(8px) } to { opacity: 1; filter: blur(0); transform: none } }
@keyframes mai-pulse  { from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--maie-accent) 50%, transparent) } to { box-shadow: 0 0 0 14px transparent } }
@keyframes mai-flow   { 0% { left: 0; opacity: 0 } 10%, 90% { opacity: 1 } 100% { left: 100%; opacity: 0 } }
@keyframes mai-drop   { 0% { top: 0; opacity: 0 } 10%, 90% { opacity: 1 } 100% { top: 100%; opacity: 0 } }
@keyframes mai-bar    { from { transform: scaleX(0) } to { transform: scaleX(1) } }
@keyframes mai-edge   { from { stroke-dashoffset: 100 } to { stroke-dashoffset: 0 } }
@keyframes mai-dash   { to { stroke-dashoffset: -24 } }
@keyframes mai-ring   { from { stroke-dashoffset: 100 } to { stroke-dashoffset: var(--mai-ring-rest, 28) } }
@keyframes mai-spin   { to { transform: rotate(360deg) } }
@keyframes mai-count  { from { transform: translateY(0) } to { transform: translateY(-90%) } }
@keyframes mai-skel   { from { background-position: 200% 0 } to { background-position: -200% 0 } }
@keyframes mai-blink  { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@keyframes mai-typing { 0%, 60%, 100% { opacity: .25 } 30% { opacity: 1 } }
@keyframes mai-glow   { 0%, 100% { transform: translate(0,0) scale(1) } 50% { transform: translate(40px,-24px) scale(1.1) } }
@keyframes mai-float  { 0%, 100% { transform: var(--mai-float-base, none) translateY(0) } 50% { transform: var(--mai-float-base, none) translateY(-8px) } }
@keyframes mai-orb    { 0%, 100% { transform: scale(1) } 50% { transform: scale(1.06) } }
@keyframes mai-orbring{ from { transform: scale(1); opacity: .5 } to { transform: scale(2); opacity: 0 } }
@keyframes mai-talk   { 0%, 100% { transform: scaleY(.3) } 50% { transform: scaleY(1) } }
@keyframes mai-think  { 0%, 100% { opacity: .3; transform: scale(.8) } 50% { opacity: 1; transform: scale(1.1) } }
@keyframes mai-drawer { from { opacity: 0; transform: translateX(30px) } to { opacity: 1; transform: none } }
@keyframes mai-rowin  { 0% { opacity: 0; transform: translateX(-12px); background: var(--maie-accent-soft) } 60% { background: var(--maie-accent-soft) } 100% { opacity: 1; transform: none; background: var(--maie-white) } }
@keyframes mai-feed   { from { opacity: 0; transform: translateY(-10px); max-height: 0 } to { opacity: 1; transform: none; max-height: 60px } }

/* ---------- Bausteine (Klassennamen sind Vertrag; im Code so verwenden) ---------- */

/* mai-rise · Standard-Eintritt für Karten, Zeilen, Panels. Versatz per --i (Index). */
.mai-rise { animation: mai-rise var(--mai-t-enter) var(--mai-ease-in) both; animation-delay: calc(var(--i, 0) * 80ms) }

/* mai-pop · Eintritt für Icon-Kacheln und Knoten */
.mai-pop { animation: mai-pop .5s var(--mai-ease-pop) both; animation-delay: calc(var(--i, 0) * 120ms) }

/* mai-bloom · Hero-Headline, aus der Unschärfe scharf (Charakter Bloom) */
.mai-bloom { animation: mai-bloom .9s ease both }

/* mai-pulse · Live-Zustand. Nur auf Akzent-Punkten. Max. ein Puls pro Ansicht. */
.mai-pulse { animation: mai-pulse 1.8s ease-out infinite }

/* mai-flow · Prozessfluss: Linie mit wanderndem Punkt. Markup: .mai-flow-line > .mai-flow-dot */
.mai-flow-line { position: relative; flex: 1; height: 2px; background: var(--maie-line) }
.mai-flow-dot  { position: absolute; top: -4px; width: 10px; height: 10px; border-radius: 50%; background: var(--maie-accent); animation: mai-flow 1.6s linear infinite; animation-delay: calc(var(--i, 0) * 400ms) }
.mai-flow-line.vertical { width: 2px; height: auto; flex: 1; min-height: 36px }
.mai-flow-line.vertical .mai-flow-dot { left: -4px; top: 0; animation-name: mai-drop }

/* mai-bar · Balken füllt sich (Fortschritt, Kennzahl, Diagramm). transform-origin left bzw. bottom. */
.mai-bar { transform-origin: left; animation: mai-bar 1.2s var(--mai-ease-in) both; animation-delay: calc(var(--i, 0) * 100ms) }
.mai-bar.vertical { transform-origin: bottom }

/* mai-edge · SVG-Linie zeichnet sich (Organigramm, Architektur, Denkweg). pathLength="100" setzen. */
.mai-edge { stroke-dasharray: 100; animation: mai-edge 1.2s ease .3s both }
/* mai-dash · Datenfluss über eine aktive Linie (weiß gestrichelt, über der Linie) */
.mai-dash { stroke-dasharray: 4 20; stroke-linecap: round; animation: mai-dash 1s linear infinite }

/* mai-ring · Fortschrittsring. SVG circle pathLength="100", --mai-ring-rest = 100 - Prozent */
.mai-ring { stroke-dasharray: 100; animation: mai-ring 1.6s var(--mai-ease-in) both }

/* mai-counter · Ziffern rollen hoch. Markup: .mai-counter > .mai-counter-col > span×10 (letzte = Zielziffer) */
.mai-counter { display: inline-flex; font-variant-numeric: tabular-nums }
.mai-counter-col { display: inline-block; height: 1em; overflow: hidden }
.mai-counter-col > span { display: flex; flex-direction: column; animation: mai-count 1.6s var(--mai-ease-in) both; animation-delay: calc(var(--i, 0) * 150ms) }

/* mai-loader · Ring dreht, Akzent-Segment */
.mai-loader { animation: mai-spin 1.1s linear infinite }

/* mai-rows · Listen: Zeilen gleiten mit 70-ms-Versatz ein, neue Zeilen leuchten kurz Akzent-hell */
.mai-rows > * { animation: mai-rowin .8s ease both; animation-delay: calc(var(--i, 0) * 70ms) }

/* mai-feed · Live-Feed: neue Einträge klappen von oben auf */
.mai-feed > * { animation: mai-feed .5s ease both; animation-delay: calc(var(--i, 0) * 120ms) }

/* mai-skel · Platzhalter während des Ladens. Nie springender Inhalt. */
.mai-skel { background: linear-gradient(90deg, var(--maie-line-soft) 25%, color-mix(in srgb, var(--maie-white) 50%, var(--maie-mist)) 50%, var(--maie-line-soft) 75%); background-size: 200% 100%; animation: mai-skel 1.4s linear infinite }

/* mai-live · "● live"-Label blinkt langsam */
.mai-live { animation: mai-blink 2s infinite }

/* mai-typing · drei Punkte (Chat, "Jarvis denkt") */
.mai-typing > span { animation: mai-typing 1.2s infinite }
.mai-typing > span:nth-child(2) { animation-delay: .2s }
.mai-typing > span:nth-child(3) { animation-delay: .4s }

/* mai-glow · weicher Lichtfleck im Hintergrund (Charakter Glas/Bloom). aria-hidden, position absolute, blur. */
.mai-glow { position: absolute; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--maie-accent) 22%, transparent), transparent); filter: blur(28px); animation: mai-glow 12s ease-in-out infinite; pointer-events: none }

/* mai-orgchart · Knoten per mai-pop Ebene für Ebene (--i = Ebene), Linien per mai-edge, Agent-Knoten mit mai-pulse-Punkt */

/* mai-avatar · Jarvis. Zustände als data-state: idle | thinking | speaking */
.mai-avatar { position: relative; border-radius: 50%; background: radial-gradient(circle at 35% 30%, var(--maie-white), var(--maie-line) 40%, var(--maie-white) 70%); box-shadow: var(--maie-glow-accent); animation: mai-orb 3s ease-in-out infinite; display: flex; align-items: center; justify-content: center }
.mai-avatar::before, .mai-avatar::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--maie-accent); opacity: 0 }
.mai-avatar[data-state="thinking"]::before { animation: mai-orbring 2s ease-out infinite }
.mai-avatar[data-state="thinking"]::after  { animation: mai-orbring 2s ease-out 1s infinite }
.mai-avatar .mai-talk > span { width: 5px; border-radius: 3px; background: var(--maie-accent); animation: mai-talk .9s ease-in-out infinite }
.mai-avatar .mai-talk > span:nth-child(2) { animation-delay: -.3s } .mai-avatar .mai-talk > span:nth-child(3) { animation-delay: -.15s }
.mai-avatar .mai-talk > span:nth-child(4) { animation-delay: -.45s } .mai-avatar .mai-talk > span:nth-child(5) { animation-delay: -.6s }
.mai-avatar .mai-dots > span { width: 10px; height: 10px; border-radius: 50%; background: var(--maie-accent); animation: mai-think 1.2s ease-in-out infinite }
.mai-avatar .mai-dots > span:nth-child(2) { animation-delay: .2s } .mai-avatar .mai-dots > span:nth-child(3) { animation-delay: .4s }

/* mai-float · leichtes Schweben für 3D-Flächen (Organigramm) und schwebende Hinweise.
   Grund-Transform (z. B. rotateX) in --mai-float-base setzen, damit die Neigung erhalten bleibt. 7 s. */
.mai-float { animation: mai-float 7s ease-in-out infinite }

/* mai-drawer · Denkweg-Schublade schiebt von rechts */
.mai-drawer { animation: mai-drawer .35s var(--mai-ease-in) both }

/* ---------- Reduzierte Bewegung ---------- */
@media (prefers-reduced-motion: reduce) {
  [class^="mai-"], [class*=" mai-"], .mai-rows > *, .mai-feed > *, .mai-typing > span, .mai-avatar::before, .mai-avatar::after,
  .mai-avatar .mai-talk > span, .mai-avatar .mai-dots > span, .mai-counter-col > span {
    animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; stroke-dashoffset: 0 !important;
  }
}
