{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "flip-zustandswechsel",
 "name": "Animierter Filter- und Ansichtswechsel (FLIP / View Transitions)",
 "name_en": "FLIP filter gallery / grid-list layout toggle / Grid/list view switch / Same-document / element-scoped view transitions",
 "kurz": "Filter und Raster-Liste-Umschalter, bei denen jede Projektkachel sichtbar an ihren neuen Platz gleitet: wahlweise mit GSAP Flip oder nativ mit View Transitions.",
 "kategorie": "Galerien & Slider",
 "kategorie_slug": "galerien-slider",
 "kategorie_nr": 12,
 "bau_chat": "C6",
 "prioritaet": "B",
 "trendstatus": "etabliert",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "ruhig",
  "präzise",
  "luxuriös",
  "verspielt"
 ],
 "stimmung_roh": [
  "präzise",
  "sachlich",
  "elegant",
  "technisch",
  "verspielt",
  "ruhig",
  "funktional"
 ],
 "technik": [
  "gsap",
  "flip",
  "scrolltrigger",
  "view-transitions",
  "css",
  "css-grid",
  "vanilla-js"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Beim Filtern oder beim Wechsel zwischen Raster und Liste springen die Kacheln nicht, sondern gleiten von ihrer alten an ihre neue Position und Größe. Ablauf mit GSAP Flip: Zustand aller Kacheln erfassen (Flip.getState), Filter oder Layoutklasse anwenden, dann animiert Flip.from jede verbleibende Kachel an ihren neuen Platz. Ausgefilterte Kacheln schrumpfen auf scale 0,8 und blenden aus, neue blenden umgekehrt ein. Ein kleiner Versatz (20 bis 50 ms) und eine gemeinsame Kurve halten die Bewegung zusammen. Nativ geht dasselbe mit View Transitions: Jede Kachel bekommt einen Namen, der Browser animiert die Positionen selbst.",
  "warum_es_wirkt": "Ursache und Wirkung bleiben sichtbar: Man sieht, welche Elemente bleiben und wohin sie gehen. Das gibt Orientierung und zeigt, dass es dieselben Projekte sind, nur anders sortiert. Veränderung wird nachvollziehbar statt sprunghaft und wirkt hochwertig. Mit element-scoped View Transitions bleibt der Rest der Seite bedienbar, und mehrere Übergänge können parallel laufen.",
  "wann_einsetzen": "Übersichten mit Kategorien und mindestens acht Einträgen: Portfolios, Projekt- und Archivseiten, Shops mit Bild- und Listenmodus, Team- oder Veranstaltungsseiten.",
  "wann_nicht": "Bei Hunderten Elementen gleichzeitig: Das kostet Leistung, bei View Transitions je ein Schnappschuss pro Name. Nicht, wenn der Filter die Seite serverseitig neu lädt. Nicht bei sehr wenigen Elementen oder wenn eine Ansicht klar genügt. Nicht für Zustandswechsel per Hover.",
  "varianten": [
   "Kategorie-Filter: verbleibende Kacheln gleiten nach, ausgefilterte skalieren heraus",
   "Raster ↔ Liste: dieselben Elemente in anderer Anordnung, gewählte Ansicht wird gemerkt",
   "Dichte-Regler (2/4/8 Spalten) oder groß ↔ klein",
   "Raster → Split-Screen → Vollbild oder Raster → Slideshow",
   "Scroll-gekoppelt: Layoutwechsel gepinnt und mit ScrollTrigger gescrubbt, Kinderbilder skalieren von 2 auf 1",
   "Ein Element wandert per Flip über mehrere Scroll-Wegpunkte",
   "Nativ: document.startViewTransition() oder element.startViewTransition() (ab Chrome 147) mit view-transition-name bzw. match-element und view-transition-class"
  ],
  "umsetzung": "GSAP Flip: const state = Flip.getState(items); dann Filter anwenden (display: none) oder Layoutklasse wechseln; Flip.from(state, { duration: 0.6–0.8, ease: 'power3.inOut', absolute: true, stagger: 0.03, onEnter: els => gsap.fromTo(els, { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1 }), onLeave: els => gsap.to(els, { opacity: 0, scale: 0.8 }) }). Bei absolute: true die Containerhöhe von alt nach neu mitführen, sonst springt der Inhalt darunter. Ändert sich die Größe stark (Raster ↔ Liste), Bilder als verschachtelte Ziele mitnehmen (nested: true) und den neu umbrechenden Text kurz ausblenden. In React: useLayoutEffect bzw. batch, Ziele neu übergeben.\n\nNativ mit View Transitions: if (grid.startViewTransition) grid.startViewTransition(update); else if (document.startViewTransition) document.startViewTransition(update); else update(). CSS: .card { view-transition-name: match-element; view-transition-class: card } (oder eindeutige Namen je Element); ::view-transition-group(.card) { animation-duration: .6s; animation-timing-function: cubic-bezier(.76,0,.24,1) }; ::view-transition-old(.card):only-child und ::view-transition-new(.card):only-child bekommen eigene Scale-Animationen für Aus- und Eintritt. Versatz über animation-delay je Name. Die Pseudo-Ebene blockiert Hover, deshalb ::view-transition { pointer-events: none } (Hinweis von Cyd Stumpel). Der Scope-Root bekommt bei element-scoped Übergängen automatisch contain: layout.\n\nUmschalter als Buttons mit aria-pressed oder als Radiogruppe; die gewählte Ansicht in localStorage merken (mit try/catch).",
  "mobil": "Gleiches Verhalten mit kürzerer Dauer (etwa 450 ms). Filter als waagerecht wischbare Chips. Oft genügt eine Liste oder ein zweispaltiges Raster; der Umschalter bleibt.",
  "reduzierte_bewegung": "Kein Gleiten der Positionen: sofort umschalten oder höchstens 150 ms einblenden.",
  "barrierefreiheit": "Filter als Buttons mit aria-pressed, Ansicht-Umschalter mit aria-pressed oder als Radiogruppe. Ergebnisanzahl in einer aria-live-Region melden. Der Fokus bleibt auf dem gedrückten Button. Ausgefilterte Elemente nach der Animation mit display: none wirklich aus dem Accessibility-Baum nehmen. Die Reihenfolge der Elemente ist in beiden Ansichten gleich."
 },
 "messwerte": {
  "easing": "power3.inOut bzw. power1.inOut (Doku-Beispiele); scroll-gescrubbt none",
  "dauer_ms": "600–1000",
  "stagger_ms": "0–50",
  "distanz": "Ein-/Austritt scale 0,8",
  "sonstiges": "Filter-Werte typisch; Scroll-Werte beobachtet im Codrops-Quellcode",
  "herkunft": "typisch",
  "quelle": "https://raw.githubusercontent.com/codrops/ScrollBasedLayoutAnimations/main/js/index.js",
  "aus_eintrag": [
   "flip-filter-layout-galerie"
  ]
 },
 "kurve": {
  "bezier": [
   0.76,
   0,
   0.24,
   1
  ],
  "css": "cubic-bezier(0.76, 0, 0.24, 1)",
  "name": "power3.inOut",
  "dauer_ms": 600
 },
 "gesehen_bei": [
  {
   "seite": "Codrops – Scroll Based Layout Animations (GitHub-Quellcode)",
   "url": "https://github.com/codrops/ScrollBasedLayoutAnimations",
   "auszeichnung": "",
   "beobachtung": "Quellcode: Flip.to mit ease none, scrub true, start center center, end +=300 % (Galerie 3: +=900 %), pin auf dem Elternelement; simple true; props filter, opacity; Stagger 0 bzw. 0,05; Kinder scale 2 → 1; Lenis lerp 0,1.",
   "art": "demo"
  },
  {
   "seite": "Osmo – List/Grid Toggle (Flip) und Layout Grid Flip",
   "url": "https://www.osmo.supply/resource/list-grid-toggle-flip",
   "auszeichnung": "",
   "beobachtung": "In der Osmo-Ressourcenliste als zwei eigene Flip-Komponenten geführt (Detailseiten gesperrt).",
   "art": "demo"
  },
  {
   "seite": "GSAP Flip-Dokumentation",
   "url": "https://gsap.com/docs/v3/Plugins/Flip/",
   "auszeichnung": "",
   "beobachtung": "Optionen absolute, nested, onEnter/onLeave, prune, fade, simple; Beispiele mit duration 1 und power1.inOut; keine 3D-Transforms.",
   "art": "artikel"
  },
  {
   "seite": "'kin (by-kin.com)",
   "url": "https://by-kin.com/",
   "auszeichnung": "laut hontran.dev Awwwards SOTD + Developer Award, FWA, CSSDA WOTD",
   "beobachtung": "Selbst abgerufen: „Layout“-Steuerung mit Optionen 1 und 2 über der Bildergalerie.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Codrops – Grid View Switch Animation",
   "url": "https://tympanus.net/codrops/2023/04/12/grid-view-switch-animation",
   "auszeichnung": "",
   "beobachtung": "Raster zoomt, Spalten verschieben sich, zwei Bilder füllen als Split (50vw × 100vh) den Screen, dann wird das rechte per Flip zum Vollbild.",
   "art": "artikel"
  },
  {
   "seite": "Cyd Stumpel: Sortier- und Filter-Demo (Women in Tech)",
   "url": "https://conffab.com/presentation/css-tried-to-come-for-my-job-a-practical-guide-to-view-transitions-for-creative-developers/",
   "auszeichnung": "",
   "beobachtung": "Eindeutige Namen plus :only-child-Scale ersetzen den Default-Fade. Gefilterte Elemente haben nur einen old-Zustand, neue nur einen new-Zustand.",
   "art": "artikel"
  },
  {
   "seite": "Chrome 147: Element-scoped View Transitions (Patagonia-Trip-Demo)",
   "url": "https://developer.chrome.com/blog/element-scoped-view-transitions",
   "auszeichnung": "",
   "beobachtung": "Grid filtern, Elemente in Auswahlliste übernehmen und Sidebar aktualisieren, alles parallel. Der Scope-Root bekommt automatisch contain: layout.",
   "art": "artikel"
  },
  {
   "seite": "Piccalilli: Tabelle umsortieren",
   "url": "https://piccalil.li/blog/some-practical-examples-of-view-transitions-to-elevate-your-ui/",
   "auszeichnung": "",
   "beobachtung": "view-transition-name: match-element auf jedem <tr>.",
   "art": "artikel"
  }
 ],
 "tutorials": [
  {
   "titel": "GSAP Flip Plugin",
   "url": "https://gsap.com/docs/v3/Plugins/Flip/"
  },
  {
   "titel": "GitHub: codrops/ScrollBasedLayoutAnimations",
   "url": "https://github.com/codrops/ScrollBasedLayoutAnimations"
  },
  {
   "titel": "Grid View Switch Animation (Codrops)",
   "url": "https://tympanus.net/codrops/2023/04/12/grid-view-switch-animation"
  },
  {
   "titel": "ViewModeSwitch (Codrops GitHub)",
   "url": "https://github.com/codrops/ViewModeSwitch"
  },
  {
   "titel": "Run concurrent and nested view transitions with element-scoped view transitions",
   "url": "https://developer.chrome.com/docs/css-ui/view-transitions/element-scoped-view-transitions"
  },
  {
   "titel": "Same-document view transitions are now Baseline Newly available (web.dev)",
   "url": "https://web.dev/blog/same-document-view-transitions-are-now-baseline-newly-available"
  },
  {
   "titel": "Prevent clipping issues with nested view transition groups",
   "url": "https://developer.chrome.com/docs/css-ui/view-transitions/nested-view-transition-groups?hl=ja"
  }
 ],
 "kombinierbar_mit": [
  "galerie-shared-element-vollbild",
  "unendliche-leinwand-galerie",
  "token-swiss-knackig",
  "projektindex-hover-vorschau",
  "layout-formation-scroll",
  "vt-shared-element-morph",
  "vt-cross-document-mpa"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/galerien-slider/flip-zustandswechsel/",
  "meta": "https://cecodesign.de/lab/fundus/galerien-slider/flip-zustandswechsel/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/galerien-slider/flip-zustandswechsel/demo"
 },
 "herkunft": {
  "quelldateien": [
   "galerien_stile.json",
   "layouts.json",
   "uebergaenge.json",
   "patch-belege-2.json"
  ],
  "pruefnotizen": [
   "patch-belege-2.json: Keine neuen Belege; Awwwards-Inspiration-URLs entfernen (by-kin.com bleibt einziger Website-Beleg)."
  ],
  "zusammengelegt_aus": [
   "flip-filter-layout-galerie",
   "raster-listen-umschalter",
   "element-scoped-zustandsuebergang"
  ],
  "trendstatus_begruendung": "Konflikt etabliert (galerien) vs. aufsteigend (layouts, uebergaenge). Aufgelöst zu 'etabliert' für die Technik (GSAP Flip seit Jahren Standard); aufsteigend ist der native Weg über element-scoped View Transitions, der als Umsetzungsvariante geführt ist.",
  "querverweis_kategorien": [
   "Hero & Section-Layouts",
   "Seitenübergänge"
  ],
  "leistungskosten_spanne": "niedrig–mittel (je nach Variante)"
 },
 "bau": {
  "status": "fertig",
  "kurz": "Filter und Raster-Liste-Umschalter, bei denen jede Projektkachel sichtbar an ihren neuen Platz gleitet: wahlweise mit GSAP Flip oder nativ mit View Transitions.",
  "demo": true,
  "abhaengigkeiten": [
   "gsap@3.15.0",
   "Flip@3.15.0"
  ],
  "werte": {
   "easing": "power3.inOut / cubic-bezier(0.76, 0, 0.24, 1)",
   "dauer_filter_ms": 600,
   "dauer_ansicht_ms": 800,
   "dauer_telefon_ms": 450,
   "stagger_ms": 30,
   "austritt": "opacity 1 → 0, scale 1 → 0.8, 400 ms, power3.inOut",
   "eintritt": "opacity 0 → 1, scale 0.8 → 1, 600 ms, 200 ms verzögert, power3.inOut",
   "text_nach_ansichtswechsel": "opacity 0 → 1, 450 ms power1.out, Start bei 55 % der Dauer, Versatz 30 ms",
   "flip_optionen": "Flip.getState([karten, bilder]); Flip.from(state, { absolute: karten, nested: true, stagger: Versatz je Kartenposition, onEnter, onLeave })",
   "containerhoehe": "alte Höhe → neue Höhe in derselben Dauer und Kurve (GSAP bzw. WAAPI)",
   "vt_aufruf": "liste.startViewTransition(update), sonst document.startViewTransition(update), sonst update()",
   "vt_namen": "view-transition-name karte-1…8 und bild-1…8, view-transition-class karte/bild, Bild mit view-transition-group: nearest",
   "vt_gruppe": "animation-duration 600/800 ms, cubic-bezier(0.76, 0, 0.24, 1), animation-delay 30 ms je sichtbarer Position",
   "vt_text": "Schnappschuss ungestreckt (width/height auto, Gruppe overflow: clip); alt 30 % der Dauer ausblenden, neu ab 55 % in 45 % einblenden",
   "vt_only_child": "::view-transition-new(.karte):only-child scale 0.8 → 1 und Deckkraft in 600 ms, 200 ms verzögert; wegfallende Karten verlieren vor dem Start ihren Namen und blenden mit ::view-transition-old(root) der Liste in 400 ms aus",
   "ui_ms": 150,
   "umschalter_indikator": "translate/width 600 ms cubic-bezier(0.76, 0, 0.24, 1)",
   "reduziert": "sofortiger Wechsel, Liste blendet in 150 ms linear ein"
  },
  "ausloeser": "klick",
  "touch": "Gleiches Verhalten per Tippen mit 450 ms Dauer. Filter-Chips wischen waagerecht, Raster zweispaltig, Liste zeigt Titel, Termin und freie Plätze. Kein Hover-Zoom auf den Bildern.",
  "reduziert": "Kein Gleiten und keine Skalierung: Filter und Ansicht wechseln sofort, die Liste blendet in 150 ms ein. Gilt für beide Varianten; die Trefferzahl rollt nicht, der Umschalter-Indikator springt.",
  "korrekturen": {
   "beschreibung": "Beim Filtern oder beim Wechsel zwischen Raster und Liste springen die Kacheln nicht, sondern gleiten von ihrer alten an ihre neue Position und Größe. Ablauf mit GSAP Flip: Zustand aller Kacheln erfassen (Flip.getState), Filter oder Layoutklasse anwenden, dann animiert Flip.from jede verbleibende Kachel an ihren neuen Platz. Ausgefilterte Kacheln schrumpfen auf scale 0,8 und blenden aus, neue blenden umgekehrt ein. Ein kleiner Versatz (20 bis 50 ms) und eine gemeinsame Kurve halten die Bewegung zusammen. Nativ geht dasselbe mit View Transitions: Jede Kachel bekommt einen Namen, der Browser animiert die Positionen selbst.",
   "warum_es_wirkt": "Ursache und Wirkung bleiben sichtbar: Man sieht, welche Elemente bleiben und wohin sie gehen. Das gibt Orientierung und zeigt, dass es dieselben Projekte sind, nur anders sortiert. Veränderung wird nachvollziehbar statt sprunghaft und wirkt hochwertig. Mit element-scoped View Transitions bleibt der Rest der Seite bedienbar, und mehrere Übergänge können parallel laufen.",
   "wann_einsetzen": "Übersichten mit Kategorien und mindestens acht Einträgen: Portfolios, Projekt- und Archivseiten, Shops mit Bild- und Listenmodus, Team- oder Veranstaltungsseiten.",
   "wann_nicht": "Bei Hunderten Elementen gleichzeitig: Das kostet Leistung, bei View Transitions je ein Schnappschuss pro Name. Nicht, wenn der Filter die Seite serverseitig neu lädt. Nicht bei sehr wenigen Elementen oder wenn eine Ansicht klar genügt. Nicht für Zustandswechsel per Hover.",
   "varianten": [
    "Kategorie-Filter: verbleibende Kacheln gleiten nach, ausgefilterte skalieren heraus",
    "Raster ↔ Liste: dieselben Elemente in anderer Anordnung, gewählte Ansicht wird gemerkt",
    "Dichte-Regler (2/4/8 Spalten) oder groß ↔ klein",
    "Raster → Split-Screen → Vollbild oder Raster → Slideshow",
    "Scroll-gekoppelt: Layoutwechsel gepinnt und mit ScrollTrigger gescrubbt, Kinderbilder skalieren von 2 auf 1",
    "Ein Element wandert per Flip über mehrere Scroll-Wegpunkte",
    "Nativ: document.startViewTransition() oder element.startViewTransition() (ab Chrome 147) mit view-transition-name bzw. match-element und view-transition-class"
   ],
   "umsetzung": "GSAP Flip: const state = Flip.getState(items); dann Filter anwenden (display: none) oder Layoutklasse wechseln; Flip.from(state, { duration: 0.6–0.8, ease: 'power3.inOut', absolute: true, stagger: 0.03, onEnter: els => gsap.fromTo(els, { opacity: 0, scale: 0.8 }, { opacity: 1, scale: 1 }), onLeave: els => gsap.to(els, { opacity: 0, scale: 0.8 }) }). Bei absolute: true die Containerhöhe von alt nach neu mitführen, sonst springt der Inhalt darunter. Ändert sich die Größe stark (Raster ↔ Liste), Bilder als verschachtelte Ziele mitnehmen (nested: true) und den neu umbrechenden Text kurz ausblenden. In React: useLayoutEffect bzw. batch, Ziele neu übergeben.\n\nNativ mit View Transitions: if (grid.startViewTransition) grid.startViewTransition(update); else if (document.startViewTransition) document.startViewTransition(update); else update(). CSS: .card { view-transition-name: match-element; view-transition-class: card } (oder eindeutige Namen je Element); ::view-transition-group(.card) { animation-duration: .6s; animation-timing-function: cubic-bezier(.76,0,.24,1) }; ::view-transition-old(.card):only-child und ::view-transition-new(.card):only-child bekommen eigene Scale-Animationen für Aus- und Eintritt. Versatz über animation-delay je Name. Die Pseudo-Ebene blockiert Hover, deshalb ::view-transition { pointer-events: none } (Hinweis von Cyd Stumpel). Der Scope-Root bekommt bei element-scoped Übergängen automatisch contain: layout.\n\nUmschalter als Buttons mit aria-pressed oder als Radiogruppe; die gewählte Ansicht in localStorage merken (mit try/catch).",
   "mobil": "Gleiches Verhalten mit kürzerer Dauer (etwa 450 ms). Filter als waagerecht wischbare Chips. Oft genügt eine Liste oder ein zweispaltiges Raster; der Umschalter bleibt.",
   "reduzierte_bewegung": "Kein Gleiten der Positionen: sofort umschalten oder höchstens 150 ms einblenden.",
   "barrierefreiheit": "Filter als Buttons mit aria-pressed, Ansicht-Umschalter mit aria-pressed oder als Radiogruppe. Ergebnisanzahl in einer aria-live-Region melden. Der Fokus bleibt auf dem gedrückten Button. Ausgefilterte Elemente nach der Animation mit display: none wirklich aus dem Accessibility-Baum nehmen. Die Reihenfolge der Elemente ist in beiden Ansichten gleich."
  },
  "geprueft": "02.11.2026",
  "notiz": "Projektübersicht des erfundenen Bamberger Vereins Regnitzwerk e. V. im Rezept verein-nonprofit-wirkung (Big Shoulders, Archivo, Navy, Gelb nur für Spenden; eigene SVG-Illustrationen statt Fotos). Filter-Chips und Raster-Liste-Umschalter; der dezente Technik-Schalter wechselt zwischen GSAP Flip und nativer element-scoped View Transition (Fallback document.startViewTransition). Karte und Bild bekommen denselben Versatz, die Containerhöhe läuft mit. Bei View Transitions wird der Kartentext nicht gestreckt, sondern überblendet. Die Vorführung klickt mit gezeichnetem Zeiger durch Filter und Ansichten. AD-Review 01.11.2026: Note 4. Varianten 01.11.2026: Der Technik-Schalter ist jetzt der Varianten-Umschalter nach Regel 13 (?v=flip, ?v=nativ); die Vorführung bleibt in der gewählten Variante. Die native Variante hat eine Weiche mit sichtbarem Hinweis (element-scoped, sonst Dokument-Übergang, sonst GSAP Flip) und zeigt einen zweiten, parallelen Übergang: die Trefferzahl rollt in ihrem eigenen Scope. Fehler behoben: In Chromium 153 brach der element-scoped Übergang beim Ausfiltern ab (benannte Karten verschwanden); wegfallende Karten verlieren jetzt vorher ihren Namen und blenden mit dem Schnappschuss der Liste aus.",
  "varianten": [
   {
    "id": "flip",
    "name": "GSAP Flip",
    "wann": "Standard für Filter und Raster-Liste-Wechsel in allen Browsern, auch mit verschachtelten Bildern, Stagger und mitlaufender Containerhöhe.",
    "werte": {
     "technik": "Flip.getState([karten, bilder]) → Flip.from({ absolute: karten, nested: true })",
     "kurve": "power3.inOut",
     "dauer_ms": "Filter 600, Ansicht 800, Telefon 450",
     "stagger_ms": 30,
     "austritt": "opacity 1 → 0, scale 1 → 0.8, 400 ms",
     "eintritt": "opacity 0 → 1, scale 0.8 → 1, 600 ms, 200 ms verzögert",
     "abhaengigkeiten": "gsap, Flip"
    }
   },
   {
    "id": "nativ",
    "name": "Nativ: element-scoped View Transition",
    "wann": "Wenn ohne Bibliothek gebaut wird und mehrere Bereiche gleichzeitig wechseln (Filterliste und Trefferzahl); Rest der Seite bleibt bedienbar. Ab Chrome 147, sonst Rückfall.",
    "werte": {
     "technik": "liste.startViewTransition(update) (element-scoped, Chrome 147+); Weiche: sonst document.startViewTransition, sonst GSAP Flip; die Werte-Zeile zeigt, welche Stufe greift",
     "namen": "view-transition-name karte-1…8 und bild-1…8, view-transition-class karte und bild, Bild mit view-transition-group: nearest",
     "kurve": "cubic-bezier(0.76, 0, 0.24, 1)",
     "dauer_ms": "Gruppe 600 (Filter) und 800 (Ansicht), Telefon 450; animation-delay 30 ms je sichtbarer Position",
     "eintritt": "::view-transition-new(.karte):only-child scale 0.8 → 1 und Deckkraft in 600 ms, 200 ms verzögert",
     "austritt": "wegfallende Karten verlieren vor dem Start ihren Namen und blenden mit ::view-transition-old(root) des Scopes in 400 ms aus (Chromium bricht sonst ab)",
     "text": "Schnappschuss ungestreckt, alt in 30 % der Dauer aus, neu ab 55 % in 45 % ein",
     "parallel": "Trefferzahl im eigenen Scope: anzahl.startViewTransition, alt translate 0 → -70 %, neu 70 % → 0, mit Deckkraft, gleiche Dauer und Kurve",
     "abhaengigkeiten": "keine (GSAP nur für den Rückfall)"
    }
   }
  ]
 }
}
