{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "karten-spotlight-glow",
 "name": "Karten-Spotlight (Glow folgt der Maus)",
 "name_en": "Spotlight card / cursor glow / border glow / Spotlight card / cursor-follow radial highlight",
 "kurz": "Ein kühles Licht folgt dem Zeiger über ein dunkles Kartenraster: als Lichtfleck, als leuchtender Rahmen oder als Zeichenrauschen.",
 "kategorie": "Hover",
 "kategorie_slug": "hover",
 "kategorie_nr": 7,
 "bau_chat": "C4",
 "prioritaet": "A",
 "trendstatus": "etabliert",
 "belegstatus": "belegt",
 "website_belege": 2,
 "stimmung": [
  "ruhig",
  "präzise",
  "luxuriös",
  "filmisch"
 ],
 "stimmung_roh": [
  "technisch",
  "premium",
  "dunkel",
  "ruhig",
  "nächtlich",
  "präzise"
 ],
 "technik": [
  "css",
  "vanilla-js",
  "gsap",
  "webgl-shader"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "gsap",
  "webgl"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Jede Karte kennt die Zeigerposition relativ zu sich selbst und speichert sie als CSS-Variablen --x und --y. Eine Deko-Ebene liegt in der Karte: ein Lichtfleck, ein Rahmen oder ein Muster. Ein radial-gradient macht sie nur im Umkreis des Zeigers sichtbar. Beim Betreten blendet die Ebene kurz ein, beim Verlassen aus. Statt Licht kann die Ebene auch eine Textur zeigen, etwa zufällige Zeichen wie bei Evervault.",
  "warum_es_wirkt": "Die Oberfläche reagiert wie Material unter einer Taschenlampe. Das gibt flachen Rastern Tiefe und zeigt ohne Worte, dass die Karten klickbar sind. Der Effekt ist dezenter als ein 3D-Tilt und wirkt hochwertig, typisch für SaaS- und Dev-Tool-Seiten.",
  "wann_einsetzen": "Feature-Raster, Bento-Kacheln, Preis-Karten, Projektkacheln und Kundenlogos auf dunklem Grund. Auch in Dashboards.",
  "wann_nicht": "Auf hellem Grund mit wenig Kontrast, dort verpufft das Licht. Nicht, wenn jede Karte schon ein Bild oder Video trägt. Nicht auf jeder Fläche der Seite, sonst wirkt es generisch. Nicht als Kernfunktion für ein reines Touch-Publikum.",
  "varianten": [
   "Lichtfleck auf der Fläche",
   "Nur der Rahmen leuchtet (Gradient-Border per mask-composite: exclude)",
   "Gemeinsames Licht über alle Karten: jede Karte rechnet die Position relativ zu sich, alle leuchten zugleich",
   "Zeichen-Rauschen unter der Maske, bei jeder Bewegung neu gemischt (Evervault)",
   "WebGL-Zeichenfeld mit Glyphen-Atlas statt DOM-Text (Codrops-Repo)",
   "Kombiniert mit 3D-Tilt (rotateX/Y nach Zeiger)",
   "Als Materiallicht auf Glas- und Dunkelflächen"
  ],
  "umsetzung": "Ein pointermove-Listener am Raster. Die Rechtecke der Karten bei resize und scroll cachen, nicht bei jeder Bewegung getBoundingClientRect aufrufen. Pro Frame (requestAnimationFrame) für jede Karte --x und --y in px setzen, sonst nichts: kein Layout, nur Custom Properties. CSS für die Fläche: .card::before { content: ''; position: absolute; inset: 0; background: radial-gradient(360px circle at var(--x) var(--y), rgb(232 234 237 / .08), transparent 60%); opacity: 0; transition: opacity 420ms ease-out; } .card:hover::before { opacity: 1; }. Rahmen: ::after mit padding: 1px, dem Verlauf als Hintergrund und mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0). Achtung: overflow: hidden an der Karte schneidet den Rahmen ab, besser clip-path: inset(0 round <radius>). Zeichen-Variante: Text mit background-clip: text einfärben und per mask-image auf den Zeigerumkreis begrenzen.",
  "mobil": "Ohne Hover entfällt das Folgen. Entweder ein statisches Licht in einer Ecke oder ein kurzes Aufleuchten an der Tippstelle. Die Zeichen-Variante nicht dauernd neu mischen.",
  "reduzierte_bewegung": "Der Effekt darf bleiben, weil der Nutzer ihn direkt steuert. Das Licht folgt ohne Nachlauf, das Ein- und Ausblenden entfällt oder wird sehr kurz. Zeichen nicht neu generieren.",
  "barrierefreiheit": "Bei :focus-visible das Licht zentriert zeigen, damit Tastaturnutzer dasselbe Feedback bekommen. Die Zufallszeichen mit aria-hidden ausblenden, sonst liest der Screenreader hunderte Zeichen vor. Das Licht ist Dekoration: Text und Rand brauchen auch ohne Licht genug Kontrast."
 },
 "messwerte": {
  "easing": "ease-out (Liveblocks); Standard (Inngest)",
  "dauer_ms": "420 Einblenden (Inngest); 150 (Liveblocks)",
  "stagger_ms": "",
  "distanz": "Gradient-Radius 360 px, Deckkraft 8 % (Inngest); Glow 200 px (Liveblocks)",
  "sonstiges": "Einblenden nur bei prefers-reduced-motion: no-preference (motion-safe) bei Inngest",
  "herkunft": "beobachtet",
  "quelle": "https://www.inngest.com/ ; https://liveblocks.io/",
  "aus_eintrag": [
   "karten-spotlight-glow"
  ]
 },
 "kurve": {
  "bezier": [
   0.0,
   0.0,
   0.58,
   1.0
  ],
  "css": "cubic-bezier(0, 0, 0.58, 1)",
  "name": "ease-out",
  "dauer_ms": 420
 },
 "gesehen_bei": [
  {
   "seite": "Evervault – Customers",
   "url": "https://evervault.com/customers",
   "auszeichnung": "",
   "beobachtung": "Kundenkarten enthalten weiterhin lange Ketten zufälliger Großbuchstaben vor dem Firmennamen – Indiz, dass das Zeichen-Spotlight live ist (Seitenabruf; Effekt selbst nicht per Text prüfbar).",
   "art": "website-ungeprueft",
   "browser_gemessen": true
  },
  {
   "seite": "Codrops AnimatedCodeBackground (Repo)",
   "url": "https://github.com/codrops/AnimatedCodeBackground",
   "auszeichnung": "",
   "beobachtung": "Quellcode: gsap.quickSetter für --x/--y; Varianten 2+ zeichnen den Code per WebGL ohne CSS-Maske.",
   "art": "demo"
  },
  {
   "seite": "Chrome Developers: Interactive content reveal",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/interactive-content-reveal",
   "auszeichnung": "",
   "beobachtung": "Pointer-folgendes Spotlight mit CSS-Masken als offizielles Muster.",
   "art": "artikel"
  },
  {
   "seite": "Inngest",
   "url": "https://www.inngest.com/",
   "auszeichnung": "",
   "beobachtung": "Karten-Overlay: background radial-gradient(360px circle at var(--mx) var(--my), rgba(232,234,237,.08), transparent 60%); group-hover:opacity-100, motion-safe:transition-opacity duration-[420ms].",
   "art": "website"
  },
  {
   "seite": "Liveblocks",
   "url": "https://liveblocks.io/",
   "auszeichnung": "",
   "beobachtung": "Glow-Element 200×200 px wird per --pointer-x/--pointer-y (px) über translate verschoben; opacity 0 → 1 bei group-hover, transition-opacity 150 ms ease-out.",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Codrops: Evervault-Hover-Nachbau",
   "url": "https://tympanus.net/codrops/?p=72017"
  },
  {
   "titel": "Chrome: Interactive content reveal",
   "url": "https://developer.chrome.com/docs/modern-web-guidance/guides/ui-behaviors/interactive-content-reveal"
  }
 ],
 "kombinierbar_mit": [
  "scramble-decode",
  "kippen-3d-karten",
  "nachbarn-reagieren-hover",
  "verlaufs-rahmen",
  "linien-punkt-raster",
  "css-3d-transforms"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/hover/karten-spotlight-glow/",
  "meta": "https://cecodesign.de/lab/fundus/hover/karten-spotlight-glow/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/hover/karten-spotlight-glow/demo"
 },
 "herkunft": {
  "quelldateien": [
   "hover.json",
   "material3d.json",
   "patch-belege-1.json"
  ],
  "pruefnotizen": [
   "patch-belege-1.json: 2 Produktionsbelege; alte Messwert-Quelle (?p=72017-Permalink) durch Produktionswerte ersetzt."
  ],
  "zusammengelegt_aus": [
   "karten-spotlight-glow",
   "spotlight-hover"
  ],
  "querverweis_kategorien": [
   "Glas & Material"
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein kühles Licht folgt dem Zeiger über ein dunkles Kartenraster: als Lichtfleck, als leuchtender Rahmen oder als Zeichenrauschen.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0, 0, 0.58, 1) (ease-out, gemessen bei Inngest und Liveblocks)",
   "dauer_ms": {
    "flaeche_ein_aus": 420,
    "rahmen_ein_aus": 150,
    "zeichen_ein_aus": 420,
    "touch_blitz": 700
   },
   "variablen": "--mx/--my in px relativ zur Karte, per JS; CSS: --x: var(--mx, 50%), --y: var(--my, 50%)",
   "flaeche": "radial-gradient(360px circle at var(--x) var(--y), rgb(232 234 237 / .08), transparent 60%) auf ::before (Farbe wie bei Inngest), nur Karte unter dem Zeiger",
   "rahmen": "::after, inset -1px, padding 1px, radial-gradient(300px circle, rgb(232 234 237) 0 %, Markenton rgb(124 131 255 / .6) 50 %, transparent 100 %), mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); gruppenweit: alle Karten leuchten, Fläche dazu mit Deckkraft .55",
   "zeichen": "Geist Mono 11/14 px, A–Z 0–9, Anzahl aus Kartengröße, neu gemischt je Frame (rAF) nur in der Karte unter dem Zeiger; Farbverlauf #f7f8f8 → #b8bcff → #7c83ff → #8a8f98 per background-clip: text; mask-image radial-gradient(200px circle, #000 15 %, transparent)",
   "licht": "rgb(232 234 237), kühles Weiß; Markenton #7c83ff nur im Rahmenlicht, Fokus und Touch-Eckenlicht",
   "karte": "Grund #161718 auf #08090a, Rand #242728, Radius 16 px, Abstand 12 px",
   "leistung": "ein Listener am Raster, Rechtecke bei resize/scroll gecacht, Ausgabe gebündelt per requestAnimationFrame, nur Custom Properties",
   "vorfuehrung": "gedachter Zeiger auf Lissajous-Bahn, je Variante 6 s (Rahmen, Zeichen, Fläche), kurz außerhalb zum Aus- und Einblenden"
  },
  "ausloeser": "hover",
  "touch": "Statisches Eckenlicht oben links auf Fläche und Rahmen (reines CSS unter hover: none). Beim Tippen blitzt die aktive Variante 700 ms an der Tippstelle auf; Zeichen werden dabei nicht neu gemischt.",
  "reduziert": "Licht folgt dem Zeiger direkt, aber ohne Ein- und Ausblenden (transition: none). Zeichen werden nur einmal erzeugt und nicht neu gemischt. Die Vorführung springt von Karte zu Karte statt zu gleiten.",
  "korrekturen": {
   "beschreibung": "Jede Karte kennt die Zeigerposition relativ zu sich selbst und speichert sie als CSS-Variablen --x und --y. Eine Deko-Ebene liegt in der Karte: ein Lichtfleck, ein Rahmen oder ein Muster. Ein radial-gradient macht sie nur im Umkreis des Zeigers sichtbar. Beim Betreten blendet die Ebene kurz ein, beim Verlassen aus. Statt Licht kann die Ebene auch eine Textur zeigen, etwa zufällige Zeichen wie bei Evervault.",
   "warum_es_wirkt": "Die Oberfläche reagiert wie Material unter einer Taschenlampe. Das gibt flachen Rastern Tiefe und zeigt ohne Worte, dass die Karten klickbar sind. Der Effekt ist dezenter als ein 3D-Tilt und wirkt hochwertig, typisch für SaaS- und Dev-Tool-Seiten.",
   "wann_einsetzen": "Feature-Raster, Bento-Kacheln, Preis-Karten, Projektkacheln und Kundenlogos auf dunklem Grund. Auch in Dashboards.",
   "wann_nicht": "Auf hellem Grund mit wenig Kontrast, dort verpufft das Licht. Nicht, wenn jede Karte schon ein Bild oder Video trägt. Nicht auf jeder Fläche der Seite, sonst wirkt es generisch. Nicht als Kernfunktion für ein reines Touch-Publikum.",
   "varianten": [
    "Lichtfleck auf der Fläche",
    "Nur der Rahmen leuchtet (Gradient-Border per mask-composite: exclude)",
    "Gemeinsames Licht über alle Karten: jede Karte rechnet die Position relativ zu sich, alle leuchten zugleich",
    "Zeichen-Rauschen unter der Maske, bei jeder Bewegung neu gemischt (Evervault)",
    "WebGL-Zeichenfeld mit Glyphen-Atlas statt DOM-Text (Codrops-Repo)",
    "Kombiniert mit 3D-Tilt (rotateX/Y nach Zeiger)",
    "Als Materiallicht auf Glas- und Dunkelflächen"
   ],
   "umsetzung": "Ein pointermove-Listener am Raster. Die Rechtecke der Karten bei resize und scroll cachen, nicht bei jeder Bewegung getBoundingClientRect aufrufen. Pro Frame (requestAnimationFrame) für jede Karte --x und --y in px setzen, sonst nichts: kein Layout, nur Custom Properties. CSS für die Fläche: .card::before { content: ''; position: absolute; inset: 0; background: radial-gradient(360px circle at var(--x) var(--y), rgb(232 234 237 / .08), transparent 60%); opacity: 0; transition: opacity 420ms ease-out; } .card:hover::before { opacity: 1; }. Rahmen: ::after mit padding: 1px, dem Verlauf als Hintergrund und mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0). Achtung: overflow: hidden an der Karte schneidet den Rahmen ab, besser clip-path: inset(0 round <radius>). Zeichen-Variante: Text mit background-clip: text einfärben und per mask-image auf den Zeigerumkreis begrenzen.",
   "mobil": "Ohne Hover entfällt das Folgen. Entweder ein statisches Licht in einer Ecke oder ein kurzes Aufleuchten an der Tippstelle. Die Zeichen-Variante nicht dauernd neu mischen.",
   "reduzierte_bewegung": "Der Effekt darf bleiben, weil der Nutzer ihn direkt steuert. Das Licht folgt ohne Nachlauf, das Ein- und Ausblenden entfällt oder wird sehr kurz. Zeichen nicht neu generieren.",
   "barrierefreiheit": "Bei :focus-visible das Licht zentriert zeigen, damit Tastaturnutzer dasselbe Feedback bekommen. Die Zufallszeichen mit aria-hidden ausblenden, sonst liest der Screenreader hunderte Zeichen vor. Das Licht ist Dekoration: Text und Rand brauchen auch ohne Licht genug Kontrast."
  },
  "geprueft": "01.11.2026",
  "notiz": "Neue Welt (01.11.2026): Funktionsübersicht der erfundenen KI-/Entwickler-Plattform Vektorhaus (Vektorsuche, Embeddings, Funktionen, Agenten, Hosting in Frankfurt) im Dunkeln, nach Rezept saas-produkt-praezise: Geist + Geist Mono, Graustufen nach Linear/Raycast plus ein Markenton #7c83ff, Statusgrün nur im UI-Ausschnitt. Bento mit echtem Produkt-Ausschnitt als HTML (Suchanfrage mit Treffern und Ähnlichkeitswerten) und eigenen SVG-Grafiken (Vektorraum mit Nachbarn, Latenz-Histogramm, Agenten-Kette, Verfügbarkeitsbalken), keine medien/-Bilder. Umschalter für drei Varianten: Fläche (Inngest-Werte 360 px, 8 %, 420 ms), Rahmen gruppenweit über alle Karten (150 ms), Zeichen-Rauschen. Bewegungswerte unverändert. Ein Listener mit gecachten Rechtecken und rAF. Die Vorführung zeigt alle drei Varianten nacheinander; in der Vorschau entfallen die Beschreibungstexte. Zugang 02.11.2026: --still #6c7179 → #838993 (≥ 4,8:1 auch auf der Karte im Hover); bei ≤ 360 px brechen Trefferzeilen und Quellen um statt Auslassungspunkte; Knopf-Rahmen im Kontrastmodus."
 }
}
