nabavizadeh.de

til

Today I Learned

Kurznotizen aus dem Bauen dieser Website — kleine Aha-Momente, die keinen ganzen Blog-Artikel brauchen.

$ cat gsap-clearprops-hover.mdx

GSAP blockiert CSS-Hover-Transforms — clearProps räumt auf

gsapcssanimation

Nach einem abgeschlossenen Tween lässt GSAP seine Inline-Styles am Element stehen — unter anderem translate: none. Das überschreibt jede CSS-Hover-Transform (auf dieser Seite: der Karten-Lift motion-safe:hover:-translate-y-0.5), weil Inline-Styles vor Klassen gewinnen.

Die Lösung ist eingebaut: clearProps entfernt die Inline-Styles, sobald die Animation fertig ist.

components/page-animations.tsx (Ausschnitt)
gsap.to(heroItems, {
  opacity: 1,
  y: 0,
  duration: 0.7,
  ease: "power2.out",
  stagger: 0.09,
  delay: 0.1,
  // Inline-Styles entfernen, sobald fertig — GSAP setzt sonst u. a.
  // `translate: none` inline und blockiert CSS-Hover-Transforms
  onComplete: () => gsap.set(heroItems, { clearProps: "all" }),
});

Gefunden beim Feinschliff der Scroll-Reveals: Karten faden korrekt ein, aber der Hover-Lift war danach tot. Die Reveals machen es deshalb genauso (dort heißt die Gruppe batch) — festgehalten als Kommentar direkt an beiden onComplete-Hooks in components/page-animations.tsx.

$ cat lighthouse-windows-eperm.mdx

Lighthouse auf Windows: EPERM im chrome-launcher umgehen

lighthousewindowstooling

@lhci/cli bricht auf diesem Windows-Setup reproduzierbar mit EPERM ab — beim Aufräumen des Temp-Profils, das der chrome-launcher anlegt, hält der Virenscanner noch Datei-Handles. Drei Versuche (inklusive eigenem user-data-dir) haben nichts geändert.

Der Workaround: den Launcher komplett weglassen. Chrome selbst mit Debugging-Port starten und lighthouse --port verbindet sich nur noch — identische Engine, identische Presets, kein Temp-Cleanup.

~/nabavizadeh

$ chrome --headless=new --remote-debugging-port=9333 &

$ lighthouse http://localhost:3108/ --port=9333 --preset=desktop

Das komplette Skript liegt im Repo unter scripts/lighthouse-local.sh; die Budgets in lighthouserc.js bleiben für CI-Umgebungen bestehen — Entscheidung „lighthouse-windows-workaround" in docs/DECISIONS.md.

$ cat lottie-currentcolor.mdx

Monochrome Lottie-Icons folgen dem Theme per currentColor

lottiecsstheming

Animierte Lottie-Icons in Light UND Dark Mode — ohne doppelte JSON-Dateien und ohne die Farben in den Dateien zu editieren: Der SVG-Renderer von lottie-web schreibt stroke/fill als Attribute ins DOM, und die lassen sich per CSS auf currentColor zwingen.

app/globals.css (Ausschnitt)
.lottie-icon svg [stroke] {
  stroke: currentColor;
}
.lottie-icon svg [fill]:not([fill="none"]) {
  fill: currentColor;
}

Damit erben die Icons ihre Farbe von der umgebenden Tailwind-Klasse (z. B. text-muted-foreground) und wechseln automatisch mit dem Theme. Genau deshalb fiel die Wahl auf den lottie_light-SVG-Renderer statt @lottiefiles/dotlottie-react (dotlottie lädt seine WASM-Runtime per Default vom CDN; der SVG-Renderer erlaubt dagegen currentColor-Theming) — Abwägung in docs/DECISIONS.md unter „lottie-icons".

$ cat shiki-dual-theme-aa.mdx

Die normalen GitHub-Themes von shiki reißen die AA-Kontrastgrenze

shikia11yblog

Beim axe-Check der Code-Blöcke fiel auf: Das Standard-Theme github-light verwendet eine Token-Farbe (#e36209), die auf Weiß nur ein Kontrastverhältnis von 3,48:1 erreicht — WCAG AA verlangt 4,5:1 für normalen Text.

Zwei Stellschrauben haben es gelöst:

  1. Die High-Contrast-Varianten verwenden: github-light-high-contrast / github-dark-high-contrast.
  2. Code-Blöcke auf bg-background statt bg-muted rendern — die High-Contrast-Farben halten AA sicher nur auf maximalem Hintergrund-Kontrast; die Abgrenzung übernehmen Border und Dateinamen-Leiste.

Das Dual-Theme schaltet dabei rein über CSS-Variablen um: shiki schreibt pro Token --shiki-light/--shiki-dark, die .dark-Klasse wählt aus. Protokolliert in docs/DECISIONS.md unter „syntax-highlighting" und „codeblock-hintergrund".

$ cd ../blog — die längeren Artikel