{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "kontextueller-cursor",
 "name": "Kontextueller Cursor (wächst, dockt an, zeigt Label)",
 "name_en": "Contextual cursor label (‚View‘, ‚Drag‘, ‚Play‘) / Contextual custom cursor / sticky cursor / cursor label / Sticky / morphing cursor that snaps to elements",
 "kurz": "Ein Cursor, der über Medien zum Label wächst („Abspielen“, „Ansehen“, „Ziehen“) und an Buttons andockt.",
 "kategorie": "Cursor",
 "kategorie_slug": "cursor",
 "kategorie_nr": 8,
 "bau_chat": "C4",
 "prioritaet": "A",
 "trendstatus": "etabliert",
 "belegstatus": "belegt",
 "website_belege": 3,
 "stimmung": [
  "editorial",
  "präzise",
  "luxuriös",
  "verspielt",
  "laut"
 ],
 "stimmung_roh": [
  "hochwertig",
  "editorial",
  "agenturhaft",
  "verspielt",
  "kreativ",
  "selbstbewusst",
  "präzise",
  "technisch"
 ],
 "technik": [
  "gsap",
  "vanilla-js",
  "css",
  "motion",
  "framer-motion"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap",
  "andere"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Über bestimmten Bereichen wie Projektkacheln, Slidern oder Videos wächst ein kleiner Punkt am Zeiger zu einem Kreis oder einer Pille mit kurzem Label: „Ansehen“, „Ziehen“, „Abspielen“. Der Text kommt per data-cursor-Attribut vom Ziel. Wechselt das Ziel, morphen Größe und Text. An Buttons und Icons dockt der Cursor an: Er springt in die Mitte, folgt dem Zeiger nur noch ein wenig und dehnt sich in seine Richtung. Der Cursor folgt dem Zeiger mit leichter Verzögerung.",
  "warum_es_wirkt": "Der Cursor erklärt die Interaktion genau dort, wo sie passiert, etwa „Ziehen“ bei einem Slider. Das ist die funktional sinnvollste Form eigener Cursor. Galerien bekommen einen klaren Fokus, die Seite eine eigene Stimme. Das Andocken lässt Cursor und Bedienelement verschmelzen, wie beim iPadOS-Zeiger. Das fühlt sich präzise und gebaut an.",
  "wann_einsetzen": "Portfolio- und Studio-Seiten, Projekt-Grids, Bildgalerien, Drag-Slider, Video-Teaser und Case-Study-Links. Andocken passt zu Navigationen mit wenigen Links, Icon-Buttons und Toolbars.",
  "wann_nicht": "In Formularen, Shops, Textseiten und dichten Oberflächen mit langen Linklisten. Nicht über Textlinks im Fließtext. Nie als Ersatz für sichtbare Bedienelemente, denn das Label sehen nur Nutzer mit Maus. Den System-Cursor nie seitenweit verstecken.",
  "varianten": [
   "Kreis mit Text (Standard): Punkt wächst zum Kreis mit Label",
   "Pille mit Icon und Text: Breite richtet sich nach dem Label",
   "Morph (iOS-Zeiger): der Cursor wird zur Hervorhebungsfläche des Buttons, der Inhalt wandert mit",
   "Sticky Cursor: springt in die Button-Mitte, dehnt sich Richtung Zeiger (scaleX bis 1,3, scaleY bis 0,8) und dreht sich per atan2",
   "Geschwindigkeitsabhängiges Strecken im freien Flug",
   "Label mit Laufschrift innerhalb des Cursors",
   "Blend-Mode-Kreis, der über einer Überschrift wächst (30 → 400 px, mix-blend-mode: difference)",
   "Text-Cursor als Balken über markierbarem Text",
   "Mehrere nachlaufende Kreise (Multi-follow)"
  ],
  "umsetzung": "Ein fixes Element (position: fixed; top/left 0; pointer-events: none; aria-hidden) wird per gsap.quickTo(el, 'x', { duration: .55, ease: 'expo.out' }) bewegt, ebenso y. Alternativ per requestAnimationFrame mit Lerp 1/12. Das Ziel unter dem Zeiger liefert document.elementFromPoint(x, y).closest('[data-cursor], [data-dock]'). Label-Ziele tragen den Text in data-cursor, Andock-Ziele das Attribut data-dock. Beim Andocken gilt: Position = Mitte + (Zeiger − Mitte) × 0,15. Die Dehnung ergibt sich aus dem Abstand zur Mitte, die Drehung aus atan2. Die Transform-Reihenfolge bleibt fest: translate, dann rotate, dann scale. Für reine Kreise reicht scale statt width/height. Bei Pille und Morph ändert sich die Form, dort Breite, Höhe und Radius animieren. Rects bei jedem Zeiger- und Scroll-Ereignis neu messen. Nur aktivieren bei matchMedia('(hover: hover) and (pointer: fine)'). Den System-Cursor nicht verstecken; in der Morph-Variante nur über den Andock-Zielen. z-index über dem Inhalt, aber unter Modals.",
  "mobil": "Auf Touch entfällt der Cursor komplett. Die Information der Labels muss als sichtbares Element vorhanden sein, etwa als Play-Knopf, Pfeile oder „Wischen“-Hinweis.",
  "reduzierte_bewegung": "Kein Nachlaufen und keine Dehnung. Der System-Cursor bleibt, das Label erscheint statisch in der Kachelecke oder als Tooltip.",
  "barrierefreiheit": "Das Cursor-Element ist aria-hidden. Die Bedeutung, etwa „Video abspielen“, gehört in den zugänglichen Namen des Ziels. Tastaturfokus braucht eigene sichtbare Fokus-Stile, unabhängig vom Cursor. Den System-Cursor nicht entfernen, weil Vergrößerungssoftware und präzises Zeigen davon abhängen."
 },
 "messwerte": {
  "easing": "expo.out (Cuberto); Lerp 1/12 ≈ 0,083 (Dennis)",
  "dauer_ms": "550 pro Mausbewegung (Cuberto); Hide-Timeout 300",
  "stagger_ms": "",
  "distanz": "Stick-Faktor 0,15; Skew max 0,15",
  "sonstiges": "Zustände per Klassen am Cursor-Element",
  "herkunft": "beobachtet",
  "quelle": "https://cuberto.com/_astro/index.astro_astro_type_script_index_0_lang.B2DOFWPC.js ; https://dennissnellenberg.com/assets/js/index-new.js",
  "aus_eintrag": [
   "kontextueller-cursor"
  ]
 },
 "kurve": {
  "bezier": [
   0.16,
   1,
   0.3,
   1
  ],
  "css": "cubic-bezier(0.16, 1, 0.3, 1)",
  "name": "expo.out",
  "dauer_ms": 550
 },
 "gesehen_bei": [
  {
   "seite": "Osmo – Dynamic Custom Text Cursor / Cursor with Marquee Effect",
   "url": "https://www.osmo.supply/resource/dynamic-custom-text-cursor",
   "auszeichnung": "",
   "beobachtung": "Ressourcen gelistet (nur Titel gesehen).",
   "art": "demo"
  },
  {
   "seite": "Olivier Larose: Blend Mode Cursor",
   "url": "https://blog.olivierlarose.com/tutorials/blend-mode-cursor",
   "auszeichnung": "",
   "beobachtung": "Inspiriert von trionn.com; Kreis 30 px → 400 px beim Text-Hover, Blur 0 → 30 px, Lerp 0.075, Größen-Transition 0.3 s ease-out, mix-blend-mode: difference.",
   "art": "artikel"
  },
  {
   "seite": "Trionn",
   "url": "https://trionn.com/",
   "auszeichnung": "",
   "beobachtung": "Inspirationsquelle laut Tutorial (nicht selbst geöffnet).",
   "art": "website-ungeprueft",
   "browser_gemessen": true
  },
  {
   "seite": "Olivier Larose: Sticky Cursor",
   "url": "https://blog.olivierlarose.com/tutorials/sticky-cursor",
   "auszeichnung": "",
   "beobachtung": "15 → 60 px, Spring damping 20 / stiffness 300 / mass 0.5, Mitte + 10 % Mausversatz, Dehnung scaleX 1–1.3 / scaleY 1–0.8, Rotation atan2.",
   "art": "artikel",
   "weitere_beobachtung": "useSpring {damping 20, stiffness 300, mass 0,5}; Größe 15 → 60; 10 % Zug Richtung Zeiger; scaleX 1→1,3 / scaleY 1→0,8 nach Distanz; Rotation per Math.atan2; transformTemplate rotate vor scale."
  },
  {
   "seite": "Motion Examples: Cursor follow / iOS pointer",
   "url": "https://motion.dev/examples/react-ios-pointer",
   "auszeichnung": "",
   "beobachtung": "Offizielle Cursor-Beispiele (Follow, Multi-follow, Custom content, Floating/Magnetic target).",
   "art": "demo"
  },
  {
   "seite": "Motion+ Cursor",
   "url": "https://motion.dev/docs/cursor",
   "auszeichnung": "",
   "beobachtung": "Zustandsabhängiger Cursor über Links, Buttons, markierbarem Text und beim Drücken; magnetisch; basiert auf Layout-Animationen; für Reduced Motion abschaltbar.",
   "art": "artikel"
  },
  {
   "seite": "Cuberto",
   "url": "https://cuberto.com/",
   "auszeichnung": "",
   "beobachtung": "Mouse-Follower (eigene Lib) im Bundle: Zustände -text/-icon/-media/-active, data-cursor-icon, speed 0.55 s ease expo.out, skewing (Delta 0.001, max 0.15), stickDelta 0.15, hideTimeout 300 ms.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Dennis Snellenberg",
   "url": "https://dennissnellenberg.com/",
   "auszeichnung": "",
   "beobachtung": "Sticky Cursor with Delay: Bild-, Button- und 'View'-Label-Ebene folgen per Lerp pos += (maus − pos)/12 in einem 120-Hz-GSAP-Ticker.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Basic/Dept",
   "url": "https://www.basicagency.com/",
   "auszeichnung": "",
   "beobachtung": "Karussell-Cursor im HTML: .carousel_cursor mit data-cursor, data-dragging, data-is-over-anchor und Pfeil-Carets (Drag-Hinweis).",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Codrops Tag ‚cursor‘",
   "url": "https://tympanus.net/codrops/tag/cursor/"
  },
  {
   "titel": "Osmo – Dynamic Custom Text Cursor",
   "url": "https://www.osmo.supply/resource/dynamic-custom-text-cursor"
  },
  {
   "titel": "Olivier Larose: Sticky Cursor",
   "url": "https://blog.olivierlarose.com/tutorials/sticky-cursor"
  },
  {
   "titel": "Olivier Larose: Blend Mode Cursor",
   "url": "https://blog.olivierlarose.com/tutorials/blend-mode-cursor"
  },
  {
   "titel": "Motion+ Cursor",
   "url": "https://motion.dev/docs/cursor"
  }
 ],
 "kombinierbar_mit": [
  "magnetische-elemente",
  "listen-hover-bildvorschau",
  "text-roll-hover",
  "cursor-masken-reveal"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/cursor/kontextueller-cursor/",
  "meta": "https://cecodesign.de/lab/fundus/cursor/kontextueller-cursor/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/cursor/kontextueller-cursor/demo"
 },
 "herkunft": {
  "quelldateien": [
   "schriftanimation.json",
   "hover.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: 3 Produktionsbelege; dennissnellenberg.com jetzt verifiziert."
  ],
  "zusammengelegt_aus": [
   "context-label-cursor",
   "kontextueller-cursor",
   "sticky-morph-cursor"
  ],
  "querverweis_kategorien": [
   "Hover"
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein Cursor, der über Medien zum Label wächst („Abspielen“, „Ansehen“, „Ziehen“) und an Buttons andockt.",
  "demo": true,
  "abhaengigkeiten": [
   "gsap@3.15.0"
  ],
  "werte": {
   "folgen": "gsap.quickTo x/y, 550 ms, expo.out (Cuberto)",
   "easing": "expo.out cubic-bezier(0.16, 1, 0.3, 1) für Folgen, Wachsen, Label-Wechsel und Leiste",
   "dauer_ms": 550,
   "ui_ms": 150,
   "punkt_px": 10,
   "label_kreis_px": 96,
   "label_kreis_beim_ziehen_px": 80,
   "pille": "Höhe 44 px, Innenabstand 18 px, Icon 14 px, Abstand 8 px",
   "label_text": "Geist Mono 600, 11 px, versal, Laufweite 0,14em; Wechsel per Maske yPercent 115 → 0 (neu) bzw. 0 → -115 (alt, 330 ms)",
   "farben": "Label #f0532a (Text #151413); Punkt und Andock-Kreis #fff mit mix-blend-mode: difference; Morph-Fläche rgba(21, 20, 19, .11)",
   "stick_faktor": 0.15,
   "andock_kreis": "Durchmesser = größere Seite des Button-Inhalts + 16 px, begrenzt auf 48–76 px",
   "dehnung_angedockt": "scaleX 1 → 1,3, scaleY 1 → 0,8 nach Abstand Zeiger–Mitte / halbe Button-Größe, Drehung atan2",
   "dehnung_frei": "Abstand Zeiger–Cursor × 0,001, höchstens 0,15 (scaleX 1 + s, scaleY 1 − s), Drehung atan2",
   "dehnung_glaettung": 0.22,
   "morph": "Button-Fläche + 4 px je Seite, Radius = Button-Radius + 4 px; Button-Inhalt wandert 15 % mit",
   "zieh_pfeile": "Abstand Kreisrand + 12 px, beim Ziehen + 18 px",
   "verstecken_ms": 300,
   "transform_reihenfolge": "translate (Anker) → rotate → scale (Dehnung) → Form"
  },
  "ausloeser": "hover",
  "touch": "Kein eigener Cursor. Die Labels stehen als sichtbare Hinweise in den Kachelecken („Abspielen“, „Ansehen“), die Leiste scrollt nativ mit Scroll-Snap und zeigt „Wischen“.",
  "reduziert": "Kein eigener Cursor, kein Nachlaufen. Die Hinweise stehen fest in den Kachelecken und färben sich bei Hover oder Fokus in 150 ms ein. Die Vorführung lässt sie nacheinander aufleuchten.",
  "korrekturen": {
   "beschreibung": "Über bestimmten Bereichen wie Projektkacheln, Slidern oder Videos wächst ein kleiner Punkt am Zeiger zu einem Kreis oder einer Pille mit kurzem Label: „Ansehen“, „Ziehen“, „Abspielen“. Der Text kommt per data-cursor-Attribut vom Ziel. Wechselt das Ziel, morphen Größe und Text. An Buttons und Icons dockt der Cursor an: Er springt in die Mitte, folgt dem Zeiger nur noch ein wenig und dehnt sich in seine Richtung. Der Cursor folgt dem Zeiger mit leichter Verzögerung.",
   "warum_es_wirkt": "Der Cursor erklärt die Interaktion genau dort, wo sie passiert, etwa „Ziehen“ bei einem Slider. Das ist die funktional sinnvollste Form eigener Cursor. Galerien bekommen einen klaren Fokus, die Seite eine eigene Stimme. Das Andocken lässt Cursor und Bedienelement verschmelzen, wie beim iPadOS-Zeiger. Das fühlt sich präzise und gebaut an.",
   "wann_einsetzen": "Portfolio- und Studio-Seiten, Projekt-Grids, Bildgalerien, Drag-Slider, Video-Teaser und Case-Study-Links. Andocken passt zu Navigationen mit wenigen Links, Icon-Buttons und Toolbars.",
   "wann_nicht": "In Formularen, Shops, Textseiten und dichten Oberflächen mit langen Linklisten. Nicht über Textlinks im Fließtext. Nie als Ersatz für sichtbare Bedienelemente, denn das Label sehen nur Nutzer mit Maus. Den System-Cursor nie seitenweit verstecken.",
   "varianten": [
    "Kreis mit Text (Standard): Punkt wächst zum Kreis mit Label",
    "Pille mit Icon und Text: Breite richtet sich nach dem Label",
    "Morph (iOS-Zeiger): der Cursor wird zur Hervorhebungsfläche des Buttons, der Inhalt wandert mit",
    "Sticky Cursor: springt in die Button-Mitte, dehnt sich Richtung Zeiger (scaleX bis 1,3, scaleY bis 0,8) und dreht sich per atan2",
    "Geschwindigkeitsabhängiges Strecken im freien Flug",
    "Label mit Laufschrift innerhalb des Cursors",
    "Blend-Mode-Kreis, der über einer Überschrift wächst (30 → 400 px, mix-blend-mode: difference)",
    "Text-Cursor als Balken über markierbarem Text",
    "Mehrere nachlaufende Kreise (Multi-follow)"
   ],
   "umsetzung": "Ein fixes Element (position: fixed; top/left 0; pointer-events: none; aria-hidden) wird per gsap.quickTo(el, 'x', { duration: .55, ease: 'expo.out' }) bewegt, ebenso y. Alternativ per requestAnimationFrame mit Lerp 1/12. Das Ziel unter dem Zeiger liefert document.elementFromPoint(x, y).closest('[data-cursor], [data-dock]'). Label-Ziele tragen den Text in data-cursor, Andock-Ziele das Attribut data-dock. Beim Andocken gilt: Position = Mitte + (Zeiger − Mitte) × 0,15. Die Dehnung ergibt sich aus dem Abstand zur Mitte, die Drehung aus atan2. Die Transform-Reihenfolge bleibt fest: translate, dann rotate, dann scale. Für reine Kreise reicht scale statt width/height. Bei Pille und Morph ändert sich die Form, dort Breite, Höhe und Radius animieren. Rects bei jedem Zeiger- und Scroll-Ereignis neu messen. Nur aktivieren bei matchMedia('(hover: hover) and (pointer: fine)'). Den System-Cursor nicht verstecken; in der Morph-Variante nur über den Andock-Zielen. z-index über dem Inhalt, aber unter Modals.",
   "mobil": "Auf Touch entfällt der Cursor komplett. Die Information der Labels muss als sichtbares Element vorhanden sein, etwa als Play-Knopf, Pfeile oder „Wischen“-Hinweis.",
   "reduzierte_bewegung": "Kein Nachlaufen und keine Dehnung. Der System-Cursor bleibt, das Label erscheint statisch in der Kachelecke oder als Tooltip.",
   "barrierefreiheit": "Das Cursor-Element ist aria-hidden. Die Bedeutung, etwa „Video abspielen“, gehört in den zugänglichen Namen des Ziels. Tastaturfokus braucht eigene sichtbare Fokus-Stile, unabhängig vom Cursor. Den System-Cursor nicht entfernen, weil Vergrößerungssoftware und präzises Zeigen davon abhängen."
  },
  "geprueft": "31.10.2026",
  "notiz": "Studio-Startseite (Ostwind, Leipzig) mit allen drei Zuständen: dunkler Punkt folgt mit 550 ms expo.out und streckt sich im Flug; über dem Markenfilm wächst er zum Label „Abspielen“ (Klick schaltet auf „Pause“), über dem Magazin Gefüge morpht der Text zu „Ansehen“, über der Leiste zu „Ziehen“ mit Pfeilen (Leiste per Maus ziehbar); an Navigation und Menüknopf dockt er an (Mitte + 15 %, Dehnung, Blend difference). Umschalter Kreis / Pille / Morph. Die Vorführung fährt alle Ziele ab und wechselt jede Runde die Variante. Bilder 01.11.2026: eigene Bilder statt Portfolio. Zugang 02.11.2026: --leise .56 → .64 (5,0:1), Mennige der h1-Kursive über --signal-schrift #e65028 (3,2:1 für große Schrift; Cursor bleibt #f0532a), Kontrastmodus-Rahmen für Knöpfe."
 }
}
