/* Lernhelden – Bewegung und Touch (iPad).
   Steht nach allen Komponenten-Dateien und vor mobil.css.

   Regeln (siehe .github/CLAUDE.md „Bewegung“):
   - Nur transform und opacity animieren – das bleibt auch auf älteren iPads flüssig.
   - Dauern und Kurven nur über Tokens (css/tokens.css), damit Klassen-Charakter und „wenig Bewegung“ überall greifen.
   - html[data-bewegung="wenig"] setzt das Inline-Skript im <head> bzw. js/ui/bewegung.js, wenn das Gerät
     „Bewegung reduzieren“ meldet oder im Profilmenü „Weniger Animationen“ gewählt ist.
     Dann gibt es keine Wege und kein Federn mehr, nur kurze Überblendungen. Konfetti entfällt (JS).
   - Bedeutung nie nur über Bewegung: Texte und aria-labels setzt der JS-Code unabhängig davon. */

/* ---------- Wenig Bewegung ---------- */
:root[data-bewegung="wenig"]{
  --dauer-kurz:1ms; --dauer-mittel:120ms; --dauer-lang:160ms; --versatz:0ms;
  --kurve-feder:ease-out; --weg-klein:0px; --huepfen:1;
}
:root[data-bewegung="wenig"] .no-grade .grade-question{outline:3px solid var(--brand)}
:root[data-bewegung="wenig"] .no-grade .grade-question::after{animation:none}
/* Toasts erscheinen dann an Ort und Stelle statt hereinzugleiten */
:root[data-bewegung="wenig"] .badge-toast,:root[data-bewegung="wenig"] .info-toast{transform:translateX(-50%);opacity:0;transition:opacity var(--dauer-mittel)}
:root[data-bewegung="wenig"] .badge-toast.show,:root[data-bewegung="wenig"] .info-toast.show{opacity:1}
:root[data-bewegung="wenig"] .level-up-toast{transform:translate(-50%,-50%)}

/* ---------- Bausteine ---------- */
@keyframes bw-einblenden{from{opacity:0;transform:translateY(var(--weg-klein))}to{opacity:1;transform:none}}
@keyframes bw-aufploppen{0%{opacity:0;transform:scale(.6)}65%{opacity:1;transform:scale(var(--huepfen))}100%{opacity:1;transform:scale(1)}}
@keyframes bw-einrasten{0%,100%{transform:scale(1)}45%{transform:scale(var(--huepfen))}}
@keyframes bw-wackeln{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(calc(var(--weg-klein) * -1))}40%,80%{transform:translateX(var(--weg-klein))}}
@keyframes bw-huepfen{0%,100%{transform:translateY(0)}45%{transform:translateY(calc(var(--weg-klein) * -2.5))}}
@keyframes bw-haken{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}
@keyframes bw-balken{from{transform:scaleX(0)}}

.bw-einblenden{animation:bw-einblenden var(--dauer-mittel) var(--kurve-standard) both}
.bw-aufploppen{animation:bw-aufploppen var(--dauer-lang) var(--kurve-feder) both}
.bw-einrasten{animation:bw-einrasten var(--dauer-lang) var(--kurve-feder)}
.bw-wackeln{animation:bw-wackeln var(--dauer-lang) var(--kurve-standard)}
.bw-huepfen{display:inline-block;animation:bw-huepfen var(--dauer-lang) var(--kurve-feder)}

/* Haken, der sich zeichnet (js/ui/bewegung.js hakenSvg) */
.bw-haken{width:1em;height:1em;margin-left:.35em;vertical-align:-.12em;flex:0 0 auto;
  fill:none;stroke:currentColor;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:24;animation:bw-haken var(--dauer-lang) var(--kurve-standard) var(--dauer-kurz) both}

/* ---------- Rückmeldung im Training ---------- */
.feedback.good.pop{animation:bw-einrasten var(--dauer-lang) var(--kurve-feder)}
.feedback.bad.pop{animation:bw-einblenden var(--dauer-mittel) var(--kurve-standard)}
.hint-box,.why-box{animation:bw-einblenden var(--dauer-mittel) var(--kurve-standard) both}
.choice{transition:border-color var(--dauer-kurz),background-color var(--dauer-kurz),transform var(--dauer-kurz) var(--kurve-standard)}

/* Abschluss: Sterne nacheinander (--i setzt training/sitzung.js) */
.finish-stars span{display:inline-block;animation:bw-aufploppen var(--dauer-lang) var(--kurve-feder) both;
  animation-delay:calc(var(--dauer-kurz) + var(--i, 0) * var(--versatz))}
.finish-stars .stern-leer{opacity:.55}
.finish-zahl{margin:0;font-size:1.15rem;font-weight:800;color:var(--muted)}
.finish-zahl strong{color:var(--ink);font-size:1.5rem;font-variant-numeric:tabular-nums}

/* Fortschrittsbalken: scaleX statt width (flüssig auf dem iPad). --anteil = 0 … 1 */
.progress-fill{width:100%;transform:scaleX(var(--anteil,0));transform-origin:left center;border-radius:0;
  transition:transform var(--dauer-mittel) var(--kurve-standard),background-color var(--dauer-lang)}
.progress-fill.knapp{background:var(--bad)}
.stat-bar-fill,.roadmap-bar{width:100%;transform:scaleX(var(--anteil,0));transform-origin:left center;border-radius:0;
  transition:none;animation:bw-balken var(--dauer-lang) var(--kurve-standard) var(--dauer-kurz) both}

/* Toasts: Dauern aus Tokens, Symbol hüpft einmal */
.badge-toast,.info-toast{transition:transform var(--dauer-lang) var(--kurve-feder),opacity var(--dauer-mittel)}
.level-up-toast{transition:transform var(--dauer-lang) var(--kurve-feder),opacity var(--dauer-lang)}
.toast-symbol{display:inline-block}
.show .toast-symbol{animation:bw-huepfen var(--dauer-lang) var(--kurve-feder) var(--dauer-mittel) 2}

/* Tagesplan: frisch erledigt */
.daily-plan-item.frisch .daily-plan-icon{display:inline-block;animation:bw-aufploppen var(--dauer-lang) var(--kurve-feder) both}

/* Konfetti (js/ui/bewegung.js feiere): liegt über allem, fängt keine Eingaben ab */
.konfetti{position:fixed;left:0;top:0;width:0;height:0;z-index:900;pointer-events:none}
.konfetti i{position:absolute;left:-5px;top:-5px;width:10px;height:10px;border-radius:2px;will-change:transform,opacity}
.konfetti i:nth-child(3n){border-radius:50%}
.konfetti i:nth-child(4n){width:6px;height:14px}
.konfetti .k0{background:var(--brand)} .konfetti .k1{background:var(--brand-2)} .konfetti .k2{background:var(--good)}
.konfetti .k3{background:var(--akzent-gold)} .konfetti .k4{background:var(--hero-1)}

/* ---------- Übergänge (seit 8.2) ---------- */
@keyframes bw-hochgleiten{from{opacity:0;transform:translateY(calc(var(--weg-klein) * 5))}to{opacity:1;transform:none}}
@keyframes bw-aufgehen{from{opacity:0;transform:scale(.96) translateY(calc(var(--weg-klein) * -1))}to{opacity:1;transform:none}}
@keyframes bw-blende{from{opacity:0}to{opacity:1}}
/* Reiter: Die neue Ansicht blendet ein (startet von selbst, weil display wechselt) */
.view.active{animation:bw-einblenden var(--dauer-mittel) var(--kurve-standard)}
/* Training und Wissensbuch: Hintergrund blendet ein, Karte gleitet hoch. Ausblenden: js/ui/bewegung.js blendeAus */
.training:not(.hidden),.wissen:not([hidden]){animation:bw-blende var(--dauer-mittel) var(--kurve-standard)}
.training:not(.hidden) .training-card,.wissen:not([hidden]) .wissen-card{animation:bw-hochgleiten var(--dauer-lang) var(--kurve-standard)}
.bw-schliesst{pointer-events:none}
/* Aufklapp-Fenster und Dialog */
.popover:not([hidden]){animation:bw-aufgehen var(--dauer-kurz) var(--kurve-standard);transform-origin:top left}
.popover-right:not([hidden]){transform-origin:top right}
.skip-menu:not([hidden]){animation:bw-aufgehen var(--dauer-kurz) var(--kurve-standard);transform-origin:bottom left}
.app-dialog[open]{animation:bw-aufploppen var(--dauer-mittel) var(--kurve-standard)}
.app-dialog[open]::backdrop{animation:bw-blende var(--dauer-mittel) var(--kurve-standard)}

/* Diagramm „Letzte 7 Tage“: Säulen wachsen nacheinander von unten */
@keyframes bw-saeule{from{transform:scaleY(0)}}
.saeule{transform-box:fill-box;transform-origin:50% 100%;animation:bw-saeule var(--dauer-lang) var(--kurve-standard) both;
  animation-delay:calc(var(--dauer-kurz) + var(--i, 0) * var(--versatz) * .5)}

/* ---------- Touch und iPad ---------- */
/* Kein Doppeltipp-Zoom, keine 300-ms-Verzögerung auf Bedienelementen */
button,select,input,textarea,label,a,[role="button"],.choice,.module-card,.daily-plan-item{touch-action:manipulation}
/* Druckgefühl beim Tippen: iOS setzt :active nur mit einem touchstart-Listener (js/main.js) */
@media (hover:none){
  .btn:active:not(:disabled),.choice:active:not(:disabled),.chip-btn:active,.tab:active,.grade-pick:active,
  .daily-plan-item:active,.station-knopf:active,.wissen-kachel:active,.stufe-knopf:active,.werk-chip:active{transform:scale(.97)}
  .chip-btn,.tab,.grade-pick,.station-knopf,.wissen-kachel,.stufe-knopf,.werk-chip{transition:transform var(--dauer-kurz) var(--kurve-standard)}
}
/* Unschärfe hinter Overlays auch in Safari vor Version 18 */
.training{-webkit-backdrop-filter:blur(6px)}
.wissen{-webkit-backdrop-filter:blur(6px)}
.topbar{-webkit-backdrop-filter:blur(10px)}
.timer-alarm{-webkit-backdrop-filter:blur(8px)}
.app-dialog::backdrop{-webkit-backdrop-filter:blur(4px)}
/* Overlays scrollen nicht in die Seite darunter durch */
.training,.wissen{overscroll-behavior:contain}

/* Volle Höhe inklusive Browserleisten, Safe-Area auch im Querformat und auf großen Bildschirmen */
.app-shell{min-height:100dvh;padding-left:max(20px,env(safe-area-inset-left));padding-right:max(20px,env(safe-area-inset-right))}
.training{padding-left:max(18px,env(safe-area-inset-left));padding-right:max(18px,env(safe-area-inset-right))}
.training-actions{padding-bottom:calc(18px + env(safe-area-inset-bottom))}
.badge-toast,.info-toast{bottom:calc(28px + env(safe-area-inset-bottom))}

/* ---------- Diagnose-Tafel (?diagnose, js/diagnose/index.js) ---------- */
.diagnose{position:fixed;left:0;right:0;bottom:0;z-index:950;max-height:85dvh;overflow:auto;overscroll-behavior:contain;
  background:var(--panel);color:var(--ink);border-top:1px solid var(--line);box-shadow:var(--shadow);border-radius:var(--radius) var(--radius) 0 0;
  padding:16px max(16px,env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left));
  animation:bw-einblenden var(--dauer-mittel) var(--kurve-standard) both}
.diagnose-kopf{display:flex;justify-content:space-between;align-items:center;gap:12px}
.diagnose-kopf h2{margin:0}
.diagnose-merkmale{display:grid;grid-template-columns:minmax(120px,max-content) 1fr;gap:4px 14px;margin:12px 0;font-size:.85rem}
.diagnose-merkmale dt{font-weight:800;color:var(--muted)}
.diagnose-merkmale dd{margin:0;overflow-wrap:anywhere}
.diagnose-status{font-weight:800;margin:12px 0}
.diagnose-buehne{display:grid;gap:10px;justify-items:start}
.diagnose-buehne .choice{min-width:160px}
.diagnose-buehne .answer-input{max-width:260px}
/* Während der Rauch-Test die App bedient: nur die Statuszeile, ohne Eingaben abzufangen */
.diagnose.diagnose-klein{max-height:none;pointer-events:none;opacity:.92}
.diagnose.diagnose-klein > :not(.diagnose-status){display:none}
.diagnose-anschauungen{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
