/* ============================================================
   Carely · Bewegung v3 (Spec 2026-11-04-bewegung-v3-design.md) – gebaut nach dem freigegebenen Entwurf v3
   ------------------------------------------------------------
   Regeln: nur transform und opacity (einzige Ausnahme: das Herz zeichnet sich über stroke-dashoffset –
   ein einziger Pfad, 56 px, kein Layout). Alltag 120–280 ms, Begrüßung zusammen ≤ 900 ms. Kein Blinken.
   Bei „weniger Bewegung“ keine Bewegung, höchstens Überblenden bis 100 ms, keine Begrüßung, Herz steht gefüllt.
   Die Klassen setzt bewegung.js im <head>: html.js, html.begruessung (nur ein Mal je Anmeldung, der Server entscheidet),
   html.gruss (bleibt, damit die Staffel nicht springt), html.anmeldet.
   Nur Tokens aus carely.css (dort auch --link), keine Farbwerte.
   Die Konsole (ops.css) lädt dieselbe Datei: Anmeldung, Seitenwechsel, Hover, Abmelden-Zeile.
   ============================================================ */
:root{--kurve-aus:cubic-bezier(.4,0,1,1);--stufe:35ms;--dauer-s:260ms}

@keyframes von-unten{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes einblenden{from{opacity:0}to{opacity:1}}
@keyframes zeichnen{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes pop{from{opacity:0;transform:scale(.4)}to{opacity:1;transform:none}}
@keyframes herz-zeichnen{to{stroke-dashoffset:0}}
@keyframes herz-fuellen{to{opacity:1}}
@keyframes atmen{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}
@keyframes ring-dreh{to{transform:rotate(360deg)}}
@keyframes nach-vorn{to{opacity:0;transform:scale(1.45)}}
@keyframes glanz{from{transform:translateX(-130%) skewX(-18deg)}to{transform:translateX(330%) skewX(-18deg)}}
@keyframes skel{to{transform:translateX(100%)}}
@keyframes vt-aus{to{opacity:0}}
@keyframes vt-ein{from{opacity:0}}
@keyframes rad{to{transform:rotate(360deg)}}
@keyframes hoch{from{transform:translateY(100%)}to{transform:none}}
@keyframes haken-ein{from{opacity:0;transform:scale(.5)}to{opacity:1;transform:none}}

/* ── 1. Brotkrumen: klar als Links (Linkfarbe, dauerhaft unterstrichen); am Handy „‹ Carely“ ── */
.krumen ol{gap:2px;font-size:14.5px}
.krumen li{display:flex;align-items:center}
.krumen li+li::before{content:"";width:6px;height:6px;margin:0 8px 0 6px;border-top:1.5px solid var(--rand-2);border-right:1.5px solid var(--rand-2);transform:rotate(45deg)}
.krumen a{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 10px;border-radius:8px;color:var(--link);font-weight:600;
  text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:4px;text-decoration-color:color-mix(in srgb,var(--link) 40%,transparent);
  transition:background var(--dauer-k),text-decoration-color var(--dauer-k)}
.krumen a:hover{background:var(--link-weich);text-decoration-color:currentColor}
.krumen a:active{background:var(--ueber-druck)}
.krumen a .ico{width:16px;height:16px}
.krumen [aria-current="page"]{display:inline-flex;align-items:center;height:32px;padding:0 10px;color:var(--text);font-weight:700;text-decoration:none;cursor:default}
.krumen .krume-gruppe{display:inline-flex;align-items:center;height:32px;padding:0 10px;color:var(--text-2);font-weight:500}
@media (max-width:900px){
  .krumen{display:block;min-width:0}
  .krumen li{display:none}
  .krumen li:has(a):has(+ [aria-current="page"]),.krumen li:first-child:has(+ .krume-gruppe){display:flex}
  .krumen li::before{display:none!important}
  .krumen .krume-gruppe{display:none}
  .krumen a{height:40px;padding:0 10px 0 4px}
  .krumen a .ico{display:none}
  .krumen a::before{content:"";width:8px;height:8px;margin:0 2px 0 6px;border-left:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg)}
  .krumen [aria-current="page"]{display:none}
  body:not(.seite-heute) .handy-marke{display:none!important}
  body.seite-heute .krumen{display:none}
}
@media (max-width:900px){body.app .krumen:not(:has(a)){display:none}}

/* ── 2. Menü: Hover, „bald“, Abmelden, Tooltips eingeklappt ── */
.nav{padding:10px 12px;gap:1px}
.nav a{min-height:var(--ziel)}
.nav-gruppe{padding:14px 12px 6px}
.nav a .ico{transition:transform var(--dauer-k) var(--kurve)}
@media (hover:hover){.nav a:hover .ico{transform:translateX(2px)}}
.nav a[aria-current="page"]:hover .ico{transform:none}
.nav a .extern{transition:transform var(--dauer-k) var(--kurve)}
@media (hover:hover){.nav a:hover .extern{transform:translate(2px,-2px)}}
.nav a.bald{color:var(--text-2)}
.nav a.bald:hover{color:var(--text)}
.leiste .nav{overflow-y:auto;flex:1;min-height:0}
.bald-marke{margin-left:auto;border:0;background:var(--fuell);color:var(--text-2);font:600 11.5px/1 var(--schrift);letter-spacing:0;text-transform:none;padding:3px 8px;border-radius:var(--radius-r)}
.blatt .bald-marke{border-color:var(--rand-stark);color:var(--text-2)}
.blatt .nav a.bald{color:var(--text-2)}
[data-leiste="schmal"] .leiste .bald-marke{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
[data-leiste="schmal"] .nav a.bald .ico{opacity:.7}
[data-leiste="schmal"] .nav a.bald::after{content:"";position:absolute;top:8px;right:10px;width:7px;height:7px;border-radius:50%;border:1.5px solid var(--leiste-gruppe)}
.leiste-fuss{display:grid;gap:2px;padding:10px 12px}
.leiste-fuss form{margin:0}
.leiste-knopf{transition:background var(--dauer-k)}
.leiste-knopf.abmelden .ico{transition:transform var(--dauer-k) var(--kurve)}
@media (hover:hover){.leiste-knopf.abmelden:hover .ico{transform:translateX(3px)}}
.leiste-knopf.abmelden:hover{background:var(--leiste-ueber)}
.leiste-knopf .ico{flex:none}
[data-leiste="schmal"] .leiste-knopf.abmelden .ico{transform:none}
.blatt-fuss{border-top:1px solid var(--rand);margin-top:8px;padding-top:8px}
.blatt-fuss form{margin:0}
.abmelden-blatt{display:flex;align-items:center;gap:12px;width:100%;min-height:48px;padding:0 12px;border:0;border-radius:var(--radius-k);background:transparent;color:var(--text-2);font:500 15px/1 var(--schrift);text-align:left}
.abmelden-blatt:hover,.abmelden-blatt:active{background:var(--ueber);color:var(--text)}
#tipp{position:fixed;z-index:300;pointer-events:none;padding:6px 10px;border-radius:8px;background:var(--text);color:var(--grund);font:600 13px/1.2 var(--schrift);white-space:nowrap;opacity:0;transform:translateX(-4px);transition:opacity 120ms,transform 120ms var(--kurve);box-shadow:var(--schatten-2)}
#tipp.an{opacity:1;transform:none}
/* Konsole: Fuß der Leiste wie in der App – gleiche Zeilen */
.o-leiste-fuss.o-nav{flex:none;overflow:visible;gap:2px;padding-top:var(--abstand-3)}
.o-leiste-fuss .o-nav-punkt{width:100%;border:0;background:transparent;font:500 1rem/1 var(--schrift);cursor:pointer;text-align:left}
.o-leiste-fuss form{margin:0}
.o-nav-punkt .ico{transition:transform var(--dauer-k) var(--kurve)}
@media (hover:hover){.o-nav-punkt:hover .ico{transform:translateX(2px)}}
.o-unten form{display:contents}
.o-unten button{position:relative;flex:1 0 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;min-height:56px;min-width:56px;padding:4px;border:0;border-radius:var(--radius-k);background:transparent;color:var(--text-3);font:600 .74rem/1.2 var(--schrift)}
.o-unten button:active{background:var(--ueber-druck)}

/* ── 3. Hover, Fokus, Druck (Hover nur bei Geräten mit Zeiger) ── */
:focus-visible{transition:outline-offset 120ms var(--kurve)}
.knopf{transition:transform var(--dauer-k) var(--kurve),box-shadow var(--dauer-k)}
@media (hover:hover){.knopf:not([disabled]):hover{box-shadow:var(--schatten-2)}}
.knopf:active{transform:scale(.97)}
.knopf.haupt-knopf{overflow:hidden}
.knopf.haupt-knopf::after{content:"";position:absolute;top:0;bottom:0;left:0;width:34%;pointer-events:none;opacity:0;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--marke-text) 40%,transparent),transparent)}
@media (hover:hover){.knopf.haupt-knopf:hover::after{opacity:1;animation:glanz 520ms var(--kurve)}}
.knopf .pfeil{transition:transform var(--dauer-k) var(--kurve)}
@media (hover:hover){.knopf:hover .pfeil{transform:translateX(3px)}}
.karte{transition:box-shadow var(--dauer) var(--kurve),border-color var(--dauer)}
@media (hover:hover){.karte:hover{box-shadow:var(--schatten-2)}}   /* Karten sind keine Links: sie heben sich nicht, nur der Schatten wird tiefer */
.aufgaben li{transition:background var(--dauer-k)}
@media (hover:hover){.aufgaben li:hover{background:var(--ueber)}}
.aufgabe-symbol{transition:transform var(--dauer) var(--kurve)}
@media (hover:hover){.aufgaben li:hover .aufgabe-symbol{transform:scale(1.07)}}
.aufgabe summary .ico.k{transition:transform var(--dauer-k) var(--kurve)}
.aufgabe[open] summary .ico.k{transform:rotate(180deg)}
.tabelle tbody tr{transition:background var(--dauer-k)}
.unten-nav a,.unten-nav button{transition:color var(--dauer-k)}
.unten-nav a:active,.unten-nav button:active{transform:scale(.94)}
/* Knopf speichert: Rad statt Symbol, Knopf bleibt an seinem Platz (kein Layoutsprung) */
.rad{display:inline-block;flex:none;width:1em;height:1em;border-radius:50%;border:2px solid currentColor;border-right-color:transparent;animation:rad .7s linear infinite}
.knopf[aria-busy="true"],form[aria-busy="true"] .knopf{pointer-events:none}
.knopf .rad{width:18px;height:18px}
.hinweis.gut .ico{animation:haken-ein 200ms var(--kurve) both}

/* ── 4. Anmeldung: Logo als Lade-Animation (App und Konsole) und Begrüßung ── */
.laden,.willkommen{position:fixed;inset:0;z-index:200;display:grid;place-items:center;background:var(--grund)}
.laden{opacity:0;visibility:hidden;transition:opacity 160ms var(--kurve),visibility 0s 160ms}
.laden.an{opacity:1;visibility:visible;transition:opacity 160ms var(--kurve)}
.laden-mitte{display:grid;justify-items:center;gap:44px}
.laden-kachel{position:relative;display:grid;place-items:center;width:96px;height:96px;border-radius:26px;background:var(--kachel);color:var(--kachel-herz);
  box-shadow:var(--schatten-3),0 0 0 1px var(--kachel-rand)}
.laden-kachel .herz{width:56px;height:56px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.herz-voll{fill:currentColor;stroke:none;opacity:0}
.herz-linie path{stroke-dasharray:1;stroke-dashoffset:1}
.laden-ring{position:absolute;inset:-22px;width:calc(100% + 44px);height:calc(100% + 44px);opacity:0;pointer-events:none}
.laden-ring circle{fill:none;stroke:var(--akzent-flaeche);stroke-width:2.5;stroke-linecap:round;stroke-dasharray:.3 .7}
.laden-text{font:600 15px/1 var(--schrift);color:var(--text-2);opacity:0}
.laden.an .herz-linie path{animation:herz-zeichnen 550ms var(--kurve) 60ms forwards}
.laden.an .herz-voll{animation:herz-fuellen 250ms ease-out 520ms forwards}
.laden.an .laden-kachel{animation:atmen 1500ms ease-in-out 800ms infinite}
.laden.an .laden-ring{animation:einblenden 200ms ease-out 300ms forwards,ring-dreh 1100ms linear 300ms infinite}
.laden.an .laden-text{animation:von-unten 300ms var(--kurve) 400ms forwards}
/* Begrüßung (Übergabe vom Laden): das Herz ist schon voll, Name blendet ein, Kachel fliegt nach vorn, Seite darunter erscheint.
   Fängt keine Klicks: die Seite darunter ist vom ersten Moment an bedienbar. */
.willkommen{display:none;pointer-events:none}
html.begruessung .willkommen{display:grid;pointer-events:none;animation:vt-aus 240ms var(--kurve) 600ms forwards}
html.begruessung .willkommen .herz-voll{opacity:1}
html.begruessung .willkommen .herz-linie path{stroke-dashoffset:0}
html.begruessung .willkommen .laden-kachel{animation:atmen 300ms var(--kurve) both,nach-vorn 300ms var(--kurve-aus) 520ms forwards}
html.begruessung .willkommen .laden-text{animation:von-unten 260ms var(--kurve) 80ms forwards}
.anmelde-formular .knopf[aria-busy="true"],form[aria-busy="true"] .knopf{pointer-events:none}
.knopf .rad{width:18px;height:18px}
.anmelde-karte{transition:opacity 160ms,transform 160ms var(--kurve)}
html.anmeldet .anmelde-karte,html.anmeldet .anmelde-fuss{opacity:0;transform:scale(.98)}

/* ── 5. Seitenwechsel: Menü und Kopf bleiben stehen, nur der Inhalt blendet um; dazu der Ladebalken ── */
@view-transition{navigation:auto}
.leiste{view-transition-name:leiste}
.kopfleiste{view-transition-name:kopf}
.haupt,.o-haupt{view-transition-name:haupt}
::view-transition-group(leiste),::view-transition-group(kopf){animation-duration:0s}
::view-transition-old(leiste),::view-transition-new(leiste),::view-transition-old(kopf),::view-transition-new(kopf){animation:none;mix-blend-mode:normal}
::view-transition-old(root){animation:none}
::view-transition-new(root){animation:none}
::view-transition-old(haupt){animation:vt-aus 100ms var(--kurve-aus) both}
::view-transition-new(haupt){animation:vt-ein 200ms var(--kurve) 40ms both}
#lade-balken{position:fixed;z-index:300;top:0;left:0;right:0;height:3px;pointer-events:none;transform-origin:0 50%;transform:scaleX(0);opacity:0;
  background:linear-gradient(90deg,var(--marke),var(--akzent-flaeche));box-shadow:0 0 8px color-mix(in srgb,var(--akzent-flaeche) 60%,transparent)}
#lade-balken.an{opacity:1;transform:scaleX(.82);transition:transform 6s cubic-bezier(.16,.84,.24,1),opacity 120ms linear}
#lade-balken.fertig{opacity:0;transform:scaleX(1);transition:transform 200ms ease-out,opacity 250ms linear 150ms}
/* Gestaffeltes Erscheinen: je Gruppe 35 ms Versatz, höchstens sieben Stufen (die siebte kommt nach 245 ms) */
html.js .stufe{animation:von-unten var(--dauer-s) var(--kurve) calc(var(--i,0) * var(--stufe) + var(--start,0ms)) both}
html.gruss{--start:300ms}
html.js body.app .verlauf-svg{transform-origin:left center;animation:zeichnen 450ms var(--kurve) calc(var(--start,0ms) + 120ms) both}
html.js body.app .verlauf-svg .ende-ring,html.js body.app .verlauf-svg .ende,html.js body.app .verlauf-svg .ende-kern{animation:pop 260ms var(--kurve) calc(var(--start,0ms) + 520ms) both;transform-box:fill-box;transform-origin:center}
html.js body.app .neu-balken > span{transform-origin:left center;animation:zeichnen 450ms var(--kurve) calc(var(--start,0ms) + 200ms) both}

/* ── 6. Platzhalter beim Laden (Skeleton): Schimmer als translateX, langsam, kein Blinken ── */
.skel-block{display:block;border-radius:8px;background:var(--flaeche-3);position:relative;overflow:hidden}
.skel-block::after,.haupt[aria-busy="true"] :is(.kz,.karte)::after{content:"";position:absolute;inset:0;transform:translateX(-100%);pointer-events:none;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--text) 9%,transparent),transparent);animation:skel 1.4s ease-in-out infinite}
.haupt[aria-busy="true"] :is(.kz,.karte){position:relative;overflow:hidden;opacity:.7}

/* ── Info-Seite „Kommt bald“ ── */
.bald-raster{display:grid;gap:20px;grid-template-columns:repeat(3,minmax(0,1fr));align-items:start}
.bald-raster .karte-inhalt{padding:18px 20px;display:grid;gap:14px}
.gross-satz{font:500 18px/1.45 var(--titel)}
.fehlt-liste{display:grid;gap:10px;padding-left:20px;list-style:disc}
.schritte-leiste{list-style:none;display:grid;gap:10px}
.schritte-leiste li{display:flex;align-items:center;gap:10px;color:var(--text-3);font-weight:600}
.schritte-leiste li.fertig{color:var(--gut)} .schritte-leiste li.jetzt{color:var(--text)}
.schritt-nr{display:grid;place-items:center;width:20px;height:20px;border-radius:50%;border:1.5px solid var(--rand-2);font-size:12px}
.schritte-leiste li.jetzt .schritt-nr{background:var(--marke);border-color:var(--marke);color:var(--marke-text)}
@media (max-width:1100px){.bald-raster{grid-template-columns:minmax(0,1fr)}}
.unten-nav a.bald .ico{opacity:.7}

/* ── Menüstreifen, Blatt „Mehr“ ── */
html.js .leiste .nav{position:relative}
html.js .leiste .nav a[aria-current="page"]::before{display:none}
.nav-streifen{position:absolute;left:0;top:0;width:4px;height:24px;border-radius:0 4px 4px 0;background:var(--akzent);pointer-events:none;will-change:transform;opacity:0}
.nav-streifen.da{opacity:1}
.nav-streifen.gleitet{transition:transform var(--dauer) var(--kurve)}
.blatt[open]{animation:hoch 240ms var(--kurve) both}
.blatt[open]::backdrop{animation:einblenden 200ms ease-out both}
.blatt{max-height:88vh;overflow-y:auto}
.blatt .nav a{min-height:44px}

/* ── Weniger Bewegung: nichts bewegt sich, höchstens 100 ms Überblenden, keine Begrüßung, Herz steht gefüllt ── */
@media (prefers-reduced-motion:reduce){
  .willkommen,html.begruessung .willkommen{display:none!important}
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  html.js .stufe{animation:none!important;opacity:1!important}
  .laden.an{transition:opacity 100ms linear!important}
  .laden .herz-voll{opacity:1}.laden .herz-linie path{stroke-dashoffset:0}.laden .laden-text{opacity:1}
  .laden .laden-ring{display:none}
  ::view-transition-old(haupt),::view-transition-new(haupt){animation:none!important}
  #lade-balken.an{transform:scaleX(1)}
  .blatt[open]{animation:einblenden 100ms linear both!important}
  .live-punkt{animation:none!important}
}

/* ══ Apple-Stil (E-39): Aktiv = blaue Kapsel (carely.css), darum kein gleitender Streifen mehr; Ziele mindestens 44 px ══ */
.nav-streifen,.nav-streifen.da{display:none}
.marke{min-height:var(--ziel)}
.krumen a{position:relative}
.krumen a::after{content:"";position:absolute;left:0;right:0;top:50%;height:var(--ziel);transform:translateY(-50%)}
@media (hover:hover){.knopf:not([disabled]):not(.haupt-knopf):not(.voll):hover{box-shadow:none}.knopf.haupt-knopf:not([disabled]):hover{box-shadow:var(--knopf-schein)}}
.karte{transition:box-shadow var(--dauer) var(--kurve)}
@media (hover:hover){.karte:hover{box-shadow:var(--s1)}}
