// Tema geçişi (DESIGN.md §2.3): açık ↔ koyu değişimi ekranı bir anda // çevirmez; yeni tema, header'daki KolayTercih işaretinin biçiminde logodan // başlayıp büyüyerek ekrana yayılır (View Transitions API + CSS maskesi, // globals.css `.kt-tema-gecis`). Tarayıcı View Transitions bilmiyorsa ya da // kullanıcı hareketi azaltmışsa tema düz değişir. /** Header'daki işaretin kök elemanı (site-header.tsx, AnimasyonluMark). */ export const TEMA_ODAK_ID = "kt-tema-odak"; /** Geçiş sırasında 'de duran sınıf ve maskenin merkez değişkenleri. */ const GECIS_SINIFI = "kt-tema-gecis"; let suruyor = false; /** * `uygula` temayı değiştiren çağrıdır (ör. `setTheme("dark")`). Geçiş * destekleniyorsa yeni tema işaretin bulunduğu noktadan maskeyle açılır; * işaret ekranda değilse (krom gizli sayfalar) sol üst köşeden açılır. */ export function temayiGecisle(uygula: () => void) { if (typeof document === "undefined") { uygula(); return; } const azHareket = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (!document.startViewTransition || azHareket || suruyor) { uygula(); return; } const odak = document.getElementById(TEMA_ODAK_ID)?.getBoundingClientRect(); const kok = document.documentElement; const x = odak && odak.width > 0 ? odak.left + odak.width / 2 : 40; const y = odak && odak.height > 0 ? odak.top + odak.height / 2 : 48; // Maske merkezden ekranın en uzak köşesine kadar büyümeli. const uzak = Math.hypot( Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y), ); kok.style.setProperty("--kt-tema-x", `${x}px`); kok.style.setProperty("--kt-tema-y", `${y}px`); // İşaretin görünür karesi viewBox'ın ~%67'si; kenar bu oranla çarpılır ki // en büyük hâlde köşe karesi bile ekranı aşsın. kok.style.setProperty("--kt-tema-son", `${Math.ceil(uzak * 3.4)}px`); kok.classList.add(GECIS_SINIFI); suruyor = true; const gecis = document.startViewTransition(uygula); gecis.finished .catch(() => {}) .finally(() => { kok.classList.remove(GECIS_SINIFI); suruyor = false; }); }