{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "fuellung-vom-eintrittspunkt",
 "name": "Füllung vom Eintrittspunkt",
 "name_en": "Direction-aware fill / fill from entry point",
 "kurz": "Leistungszeilen und Knöpfe füllen sich dort, wo der Zeiger eintritt: als Kreis ab dem Eintrittspunkt, von der nächsten Kante oder gewölbt von unten; die Textfarbe wechselt genau an der Kante der Füllung.",
 "kategorie": "Hover",
 "kategorie_slug": "hover",
 "kategorie_nr": 7,
 "bau_chat": "C4",
 "prioritaet": "C",
 "trendstatus": "etabliert",
 "belegstatus": "quellenbelegt",
 "website_belege": 0,
 "stimmung": [
  "ruhig",
  "präzise",
  "luxuriös",
  "verspielt"
 ],
 "stimmung_roh": [
  "flüssig",
  "präzise",
  "premium",
  "verspielt"
 ],
 "technik": [
  "css",
  "vanilla-js",
  "gsap"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "1) Beim Betreten wird ermittelt, wo der Zeiger eintritt: als genaue Koordinate oder als nächstgelegene Kante. 2) Eine Füllfläche wächst von dort über Button oder Zeile, als Kreis (clip-path: circle() an x/y) oder als Fläche von oben oder unten (clip-path: inset() oder translateY von ±100 %). 3) Die Textfarbe wechselt mit, am saubersten über eine deckungsgleiche Kopie des Inhalts in der Füllfläche. 4) Beim Verlassen zieht sich die Füllung zur Austrittsseite zurück.",
  "warum_es_wirkt": "Die Füllung folgt der Hand wie eine Flüssigkeit. Weil sie dort beginnt, wo der Zeiger hereinkommt, fühlt sich die Interaktion echt an. Hohe Wertigkeit bei wenig Aufwand.",
  "wann_einsetzen": "Primärbuttons, Zeilen in Menüs und Leistungs- oder Projektlisten, Karten, Pill-Buttons in hellen und dunklen Designs.",
  "wann_nicht": "Bei sehr kleinen Buttons, weil die Richtung dort nicht wahrnehmbar ist. Neben anderen Hover-Effekten, die um Aufmerksamkeit konkurrieren. Das Pixelraster nicht in ruhigen Marken (Kanzlei, Praxis, Luxus).",
  "varianten": [
   "Kreis wächst ab dem genauen Eintrittspunkt: clip-path: circle(0 at x y) → circle(r at x y), r bis zur fernsten Ecke",
   "Füllung schiebt sich von der nächsten Kante oben oder unten (K72 von Locomotive, closestEdge, 0,6 s expo)",
   "Füllung startet bei y 75 % und läuft auf 0 (Codrops MagneticButtons Demo 4, 0,5 s power3.out)",
   "Feste Richtung von unten mit gewölbter Kante, wie auf Produktionsseiten verbreitet (cuberto.com: translateY(101%) → 0 und border-radius 50% 50% 0 0 → 0)",
   "Laufband-Streifen mit gegenläufigem Innenwrapper (K72)",
   "Ripple beim Klick statt Hover (siehe klick-ripple)",
   "Organische Blob-Füllung per SVG-Path-Morph",
   "Pixelraster: Zellen füllen gestaffelt vom Eintrittspunkt (Prinzip Pixel-Button), clip-path: path() aus Rasterzellen, 6 Stufen à 80 ms"
  ],
  "umsetzung": "Füllfläche als eigenes Element (oder ::before) mit position: absolute; inset: 0. Für exakten Farbwechsel eine Kopie des Inhalts mit aria-hidden hineinlegen und beide mit derselben clip-path schneiden. Kreis: btn.addEventListener('pointerenter', e => { const r = btn.getBoundingClientRect(), x = e.clientX - r.left, y = e.clientY - r.top; … }). Zuerst den Startzustand ohne Transition setzen (fill.style.transition = 'none'; fill.style.clipPath = `circle(0px at ${x}px ${y}px)`), Layout lesen (getBoundingClientRect), dann Transition zurück und Ziel setzen: circle(Rpx at x y) mit R = Abstand zur fernsten Ecke. Ohne diesen Zwischenschritt wandert der Kreismittelpunkt von der alten Stelle herüber. pointerleave setzt circle(0px at Austrittspunkt). Kanten-Variante: Eintritt in der oberen oder unteren Hälfte entscheidet über inset(0 0 100% 0) bzw. inset(100% 0 0 0) als Start, Ziel inset(0). Werte: 0,6 s cubic-bezier(0.16, 1, 0.3, 1). Fallstrick: pageX und offsetTop brechen bei transformierten Eltern, deshalb getBoundingClientRect mit clientX/Y. Für Tastaturfokus ab 50 % / 50 % füllen.",
  "mobil": "Beim Tippen den Kreis vom Tipp-Punkt wachsen lassen (wirkt wie ein Ripple), kurz stehen lassen, dann navigieren.",
  "reduzierte_bewegung": "Sofortiger Farbwechsel oder ein kurzer Crossfade von 150 ms statt der wachsenden Form.",
  "barrierefreiheit": "Kontrast in beiden Zuständen prüfen. Die Textfarbe muss synchron zur Füllung wechseln, sonst steht dunkler Text kurz auf dunkler Fläche. :focus-visible bekommt denselben Effekt ab der Mitte. Die Kopie des Inhalts ist aria-hidden und enthält keine fokussierbaren Elemente."
 },
 "messwerte": {
  "easing": "expo (K72); power3.out (Codrops Demo 4)",
  "dauer_ms": "600 (K72); 500 (Demo 4)",
  "stagger_ms": "",
  "distanz": "±101 % Startversatz; Kreisradius bis 150 % für volle Abdeckung",
  "sonstiges": "",
  "herkunft": "beobachtet",
  "quelle": "https://tympanus.net/codrops/2021/06/30/how-to-code-the-k72-marquee-hover-animation/ ; https://github.com/codrops/MagneticButtons (demo4)"
 },
 "kurve": {
  "bezier": [
   0.16,
   1.0,
   0.3,
   1.0
  ],
  "css": "cubic-bezier(0.16, 1, 0.3, 1)",
  "name": "expo.out",
  "dauer_ms": 600
 },
 "gesehen_bei": [
  {
   "seite": "Codrops: How to Code the K72 Marquee Hover Animation",
   "url": "https://tympanus.net/codrops/2021/06/30/how-to-code-the-k72-marquee-hover-animation/",
   "auszeichnung": "",
   "beobachtung": "findClosestEdge → 'top'/'bottom'; Außen y ±101 %, Innen gegenläufig; gemeinsame Defaults 0.6 s ease 'expo'. Original von Locomotive für K72.",
   "art": "artikel"
  },
  {
   "seite": "Codrops MagneticButtons Demo 4",
   "url": "https://github.com/codrops/MagneticButtons",
   "auszeichnung": "",
   "beobachtung": "Quellcode: filler startAt y 75 % → 0 % in 0.5 s power3.out; Text 0.1 s raus (-10 %), 0.25 s rein von 30 %.",
   "art": "demo"
  },
  {
   "seite": "Motion Examples: Material Design Ripple",
   "url": "https://motion.dev/examples/js-material-design-ripple",
   "auszeichnung": "",
   "beobachtung": "Kreis wächst vom Klickpunkt (Klick-Variante).",
   "art": "demo"
  }
 ],
 "tutorials": [
  {
   "titel": "Codrops: K72 Marquee Hover Animation",
   "url": "https://tympanus.net/codrops/2021/06/30/how-to-code-the-k72-marquee-hover-animation/"
  }
 ],
 "kombinierbar_mit": [
  "magnetische-elemente",
  "text-roll-hover",
  "listen-hover-bildvorschau"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hover/fuellung-vom-eintrittspunkt/",
  "meta": "https://cecodesign.de/lab/fundus/hover/fuellung-vom-eintrittspunkt/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hover/fuellung-vom-eintrittspunkt/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: Kein Produktionscode mit Eintrittspunkt-Erkennung gefunden (k72.ca-Bundle geprüft, Logik nicht auffindbar; ca. 230 Seiten durchsucht). Real verbreitet ist die Variante mit fester Richtung: dennissnellenberg.com (.btn-fill startAt y 76 % → 0, 0,6 s Power2.easeInOut, raus nach −76 %) und cuberto.com (.ripple span translateY(101%) → 0, border-radius 50% 50% 0 0 → 0, .5s/.9s cubic-bezier(.4,0,0,1)) – evtl. als Variante aufnehmen."
  ],
  "prioritaet_hinweis": "31.10.2026: A → C laut patch-belege-1.json (Kein Produktionscode mit Eintrittspunkt-Erkennung gefunden (k72.ca-Bundle geprüft, Logik nicht auffindbar; ca. 230 Seiten durchsucht). Real verbreitet ist die Variante mit fester Richtung: dennissnell)"
 },
 "bau": {
  "status": "fertig",
  "kurz": "Leistungszeilen und Knöpfe füllen sich dort, wo der Zeiger eintritt: als Kreis ab dem Eintrittspunkt, von der nächsten Kante oder gewölbt von unten; die Textfarbe wechselt genau an der Kante der Füllung.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0.16, 1, 0.3, 1) (expo.out) für Füllen und Rückzug",
   "dauer_ms": 600,
   "rueckzug_ms": 600,
   "technik": "Füllfläche als absolut liegendes span mit einer deckungsgleichen Kopie des Inhalts (aria-hidden), beide per clip-path geschnitten; Startzustand ohne Transition setzen, Layout lesen, dann Ziel setzen",
   "kreis": "clip-path: circle(0px at x y) → circle(r at x y), r = Abstand zur fernsten Ecke + 2 px; Verlassen: circle(0px at Austrittspunkt)",
   "kante": "Eintritt in der oberen Hälfte: inset(0 0 100% 0) → inset(0); in der unteren: inset(100% 0 0 0) → inset(0); Verlassen zur nächsten Kante (K72-Logik mit 100 % Versatz)",
   "gewoelbt": "inset(100% 0 0 0 round 50% 50% 0 0) → inset(0 0 0 0 round 0 0 0 0); Verlassen nach oben: inset(0 0 100% 0 round 0 0 50% 50%)",
   "koordinaten": "getBoundingClientRect + clientX/Y, nur bei pointerType mouse",
   "fokus": ":focus-visible füllt ab der Mitte (50 % / 50 %), Umriss 2 px #FB6100 mit 3 px Abstand",
   "touch": "pointerdown setzt den Tipp-Punkt, Füllung 600 ms, bleibt 250 ms stehen, zieht sich dann zum Tipp-Punkt zurück",
   "reduziert": "keine Form, opacity 0 → 1 in 150 ms linear",
   "ui": "Umschalter und Navigation 150 ms cubic-bezier(0.4, 0, 0.2, 1)",
   "farben": "Zeilen: Füllung #1A1A1A, Text #EFEDEA, Beschreibung #D3CDC2, Preis-Pille #FB6100; Knopf Anfrage: #FB6100 → Füllung #1A1A1A mit weißem Text; Knopf Telefon: Kontur #1A1A1A → Füllung #FB6100",
   "schrift": "Special Gothic 700 (Zeilen clamp(1.5rem, 1rem + 1.5vw, 2.25rem)), Labels Special Gothic Breite 75 %, 13 px versal, +0.04em; Text Atkinson Hyperlegible Next 16–17 px",
   "vorfuehrung": "6,2 s je Variante (Kreis, Kante, gewölbt): Zeiger kommt von unten in die letzte Zeile, fährt schräg nach oben durch die Liste, verlässt sie seitlich und tritt von links in den Anfrage-Knopf"
  },
  "ausloeser": "hover",
  "touch": "Kein Hover. Ein Tippen lässt die Füllung vom Tipp-Punkt wachsen wie ein Ripple, sie bleibt 250 ms stehen und zieht sich zurück; danach würde der Link zur Zielseite führen (in der Demo unterdrückt, Telefon-Links funktionieren). Auf dem Telefon liegt unten fest die Leiste Anrufen, Anfrage, WhatsApp mit demselben Effekt.",
  "reduziert": "Keine wachsende Form: Die Füllung blendet in 150 ms linear über, Textfarbe wechselt mit. Der Vorführ-Zeiger entfällt.",
  "korrekturen": {
   "beschreibung": "1) Beim Betreten wird ermittelt, wo der Zeiger eintritt: als genaue Koordinate oder als nächstgelegene Kante. 2) Eine Füllfläche wächst von dort über Button oder Zeile, als Kreis (clip-path: circle() an x/y) oder als Fläche von oben oder unten (clip-path: inset() oder translateY von ±100 %). 3) Die Textfarbe wechselt mit, am saubersten über eine deckungsgleiche Kopie des Inhalts in der Füllfläche. 4) Beim Verlassen zieht sich die Füllung zur Austrittsseite zurück.",
   "warum_es_wirkt": "Die Füllung folgt der Hand wie eine Flüssigkeit. Weil sie dort beginnt, wo der Zeiger hereinkommt, fühlt sich die Interaktion echt an. Hohe Wertigkeit bei wenig Aufwand.",
   "wann_einsetzen": "Primärbuttons, Zeilen in Menüs und Leistungs- oder Projektlisten, Karten, Pill-Buttons in hellen und dunklen Designs.",
   "wann_nicht": "Bei sehr kleinen Buttons, weil die Richtung dort nicht wahrnehmbar ist. Neben anderen Hover-Effekten, die um Aufmerksamkeit konkurrieren. Das Pixelraster nicht in ruhigen Marken (Kanzlei, Praxis, Luxus).",
   "varianten": [
    "Kreis wächst ab dem genauen Eintrittspunkt: clip-path: circle(0 at x y) → circle(r at x y), r bis zur fernsten Ecke",
    "Füllung schiebt sich von der nächsten Kante oben oder unten (K72 von Locomotive, closestEdge, 0,6 s expo)",
    "Füllung startet bei y 75 % und läuft auf 0 (Codrops MagneticButtons Demo 4, 0,5 s power3.out)",
    "Feste Richtung von unten mit gewölbter Kante, wie auf Produktionsseiten verbreitet (cuberto.com: translateY(101%) → 0 und border-radius 50% 50% 0 0 → 0)",
    "Laufband-Streifen mit gegenläufigem Innenwrapper (K72)",
    "Ripple beim Klick statt Hover (siehe klick-ripple)",
    "Organische Blob-Füllung per SVG-Path-Morph",
    "Pixelraster: Zellen füllen gestaffelt vom Eintrittspunkt (Prinzip Pixel-Button), clip-path: path() aus Rasterzellen, 6 Stufen à 80 ms"
   ],
   "umsetzung": "Füllfläche als eigenes Element (oder ::before) mit position: absolute; inset: 0. Für exakten Farbwechsel eine Kopie des Inhalts mit aria-hidden hineinlegen und beide mit derselben clip-path schneiden. Kreis: btn.addEventListener('pointerenter', e => { const r = btn.getBoundingClientRect(), x = e.clientX - r.left, y = e.clientY - r.top; … }). Zuerst den Startzustand ohne Transition setzen (fill.style.transition = 'none'; fill.style.clipPath = `circle(0px at ${x}px ${y}px)`), Layout lesen (getBoundingClientRect), dann Transition zurück und Ziel setzen: circle(Rpx at x y) mit R = Abstand zur fernsten Ecke. Ohne diesen Zwischenschritt wandert der Kreismittelpunkt von der alten Stelle herüber. pointerleave setzt circle(0px at Austrittspunkt). Kanten-Variante: Eintritt in der oberen oder unteren Hälfte entscheidet über inset(0 0 100% 0) bzw. inset(100% 0 0 0) als Start, Ziel inset(0). Werte: 0,6 s cubic-bezier(0.16, 1, 0.3, 1). Fallstrick: pageX und offsetTop brechen bei transformierten Eltern, deshalb getBoundingClientRect mit clientX/Y. Für Tastaturfokus ab 50 % / 50 % füllen.",
   "mobil": "Beim Tippen den Kreis vom Tipp-Punkt wachsen lassen (wirkt wie ein Ripple), kurz stehen lassen, dann navigieren.",
   "reduzierte_bewegung": "Sofortiger Farbwechsel oder ein kurzer Crossfade von 150 ms statt der wachsenden Form.",
   "barrierefreiheit": "Kontrast in beiden Zuständen prüfen. Die Textfarbe muss synchron zur Füllung wechseln, sonst steht dunkler Text kurz auf dunkler Fläche. :focus-visible bekommt denselben Effekt ab der Mitte. Die Kopie des Inhalts ist aria-hidden und enthält keine fokussierbaren Elemente."
  },
  "geprueft": "02.11.2026",
  "notiz": "Welt: Tischlerei Hasekamp in Osnabrück-Eversburg, Inhaber Jens Wöstmann (Rezept handwerk-werkstatt-klartext): Special Gothic und Atkinson Hyperlegible Next, Materialfarben, Signal #FB6100 nur für Anfrage und Anruf, Ab-Preise offen, mobil unten Anrufen/Anfrage/WhatsApp. Leistungsliste mit eigenen Werkzeichnungen statt Fotos (keine Holz-Fake-Texturen). Umschalter Kreis ab Eintritt, Nächste Kante (K72), Von unten gewölbt (Produktionsvariante laut Prüfnotiz). Die Dauer folgt der Messung des Musters (600 ms expo.out) statt den 150 ms des Rezepts, weil die Richtung sonst nicht wahrnehmbar ist. Referenzen nur als Prinzip: k72.ca (große Pill-Buttons), designacademy.nl (schlichte Versal-Navigation). AD-Review 01.11.2026: Note 4 Korrektur 02.11.2026: Varianten nach Regel 13 (?v=basis|pixel), die bisherigen drei Formen stehen in der Grundvariante unter „Form“. pixel: Programm des erfundenen Festivals Kanalrauschen in Siegen (Rezept kultur-programm-haltung), Zeilen füllen in Spartenfarbe, Ticket-Knöpfe eckig; Füllung als clip-path: path() aus 8- bzw. 16-px-Zellen in 6 Stufen à 80 ms (Werte aus token-brutal-hart).",
  "varianten": [
   {
    "id": "basis",
    "name": "Clip-Path-Formen (Tischlerei)",
    "knopf": "Clip-Path",
    "wann": "Leistungslisten und Knöpfe in direkten, ruhigen Rezepten (Handwerk, Agentur, Beratung): Kreis ab Eintritt, nächste Kante oder gewölbt von unten, Unterumschalter Form.",
    "werte": {
     "rezept": "handwerk-werkstatt-klartext",
     "technik": "clip-path circle() / inset() auf deckungsgleicher Kopie",
     "dauer_ms": 600,
     "easing": "cubic-bezier(0.16, 1, 0.3, 1)"
    }
   },
   {
    "id": "pixel",
    "name": "Pixelraster vom Eintrittspunkt (Festivalprogramm)",
    "knopf": "Pixelraster",
    "wann": "Kultur, Festival, Kreativ- und Tech-Seiten mit Raster- oder Retro-Charakter: Programmzeilen und Ticket-Knöpfe füllen sich in Zellen vom Eintrittspunkt aus. Passt zu token-brutal-hart. Nicht für ruhige Marken (Kanzlei, Praxis, Luxus).",
    "werte": {
     "rezept": "kultur-programm-haltung, Takt aus token-brutal-hart (pixel: takt_ms 80, gesamt_ms 480)",
     "technik": "dieselbe aria-hidden Kopie, geschnitten mit clip-path: path() aus Rasterzellen; Zellen einer Reihe zu Streifen zusammengefasst (M x y h w v z h −w Z), nonzero ergibt die Vereinigung; transition none",
     "zelle_px": {
      "knopf": 8,
      "zeile": 16
     },
     "stufen": 6,
     "takt_ms": 80,
     "gesamt_ms": 480,
     "staffel": "Stufe = round(Abstand Zellmitte zum Eintrittspunkt / größter Abstand × 5 ± Zufall 0,7), auf 0 bis 5 geklemmt",
     "austritt": "gleiche Stufen mit 1 − Abstand/max zum Austrittspunkt: ferne Zellen gehen zuerst, der Rest zieht sich zum Austritt zurück",
     "easing": "keine Kurve, setTimeout-Takt 80 ms (Stufen)",
     "farben": "Zeilen füllen in Spartenfarbe mit weißer Schrift (#c4421a Musik, #b0186b Film, #2f7d4a Kunst, #3d5f9a Tanz, je ≥ 5:1 zu Weiß); Knopf #0b0b0b → #c4421a, Zweitknopf Kontur → #0b0b0b; Grund #efede9",
     "form": "eckig (kein Radius), Knöpfe 52 px hoch",
     "fokus": "wie Grundvariante: Füllung ab der Mitte, outline 2px #c4421a",
     "touch": "Tipp-Punkt startet die Füllung, 480 ms + 250 ms stehen, dann Rückzug",
     "reduziert": "keine Zellen, opacity 0 → 1 in 150 ms linear",
     "schrift": "Big Shoulders 800 versal (h1 clamp(2.75rem, 1.6rem + 4.4vw, 5.75rem)/.95, Zeilentitel clamp(1.625rem, 1.1rem + 1.4vw, 2.375rem)), Atkinson Hyperlegible Next Text 1.125rem/1.6, IBM Plex Mono 500 12,5 px für Datum, Sparte, Preis"
    }
   }
  ]
 }
}
