/* ═══════════════════════════════════════════════════════════
   Herta — fx katmanı (assets/js/fx.js)
   Yalnız iki düğüm: özel imleç ve film grain. İkisi de JS ile
   eklenir; script yüklenmezse bu dosya hiçbir şeyi etkilemez
   (JS kapalıyken sayfa aynen görünür kalır).
   Değişkenler style.css'ten gelir; fallback'ler yalnız fx.css
   tek başına yüklendiğinde devreye girer.
   ═══════════════════════════════════════════════════════════ */

/* ── Özel imleç ───────────────────────────────────────────
   Gerçek imleç GİZLENMEZ: bu daire onun üstüne eklenen bir
   katmandır (erişilebilirlik + "imleç kayboldu" hissi yok).
   mix-blend-mode kullanılmaz; koyu zeminde renk JS ile döner.
   Daire aria-hidden'dır; içindeki etiket metni ekran okuyucuya
   düşmez, bağlantının kendi adı zaten okunur. */
.fx-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 210;                 /* .pt (190) ve preloader (200) üstünde */
  width: var(--fx-cur-size, 26px);
  height: var(--fx-cur-size, 26px);
  box-sizing: border-box;
  border: 1px solid currentColor;
  border-radius: 50%;           /* tek istisna: imleç bir daire */
  /* --black / --white BİLEREK: --ink ve --bg koyu sayfada çevriliyor
     (style.css data-tema). İmleç zemini kendi luminansıyla okuyor
     (fx.js), yani temayı ZATEN biliyor; çevrilen belirteçlere
     yaslanırsa iki mekanizma üst üste biner ve etiket metni beyaz
     dolgu üstünde beyaz kalırdı. */
  color: var(--black, #000);
  --fx-cur-fill: rgba(0, 0, 0, 0.08);
  --fx-cur-fill-strong: rgba(0, 0, 0, 0.92);
  --fx-cur-ink: #fff;                    /* etiket metni: dairenin kontrastı */
  background-color: transparent;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transform: translate3d(-120px, -120px, 0) translate(-50%, -50%);
  transition:
    width 0.4s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    height 0.4s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    background-color 0.4s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    border-color 0.3s linear,
    color 0.3s linear,
    opacity 0.28s ease;
}

/* dairenin merkezindeki nokta: hedefi işaret eden asıl uç.
   Etiketli durumda (daire dolarken) gizlenir. */
.fx-cursor::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 3px;
  height: 3px;
  margin: -1.5px 0 0 -1.5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.85;
  transition: opacity 0.3s ease, transform 0.4s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fx-cursor.is-active::after { opacity: 0.55; transform: scale(0.8); }
.fx-cursor.is-label::after { opacity: 0; }
.fx-cursor.is-visible { opacity: 1; }

/* bağlantı / düğme / satır üzerinde: 44px + %8 dolgu */
.fx-cursor.is-active {
  --fx-cur-size: 44px;
  background-color: var(--fx-cur-fill);
}

/* koyu zeminler (footer, cta görseli, menü, geçiş perdesi, dock) */
.fx-cursor.is-dark {
  color: #fff;
  --fx-cur-fill: rgba(255, 255, 255, 0.08);
  --fx-cur-fill-strong: rgba(255, 255, 255, 0.92);
  --fx-cur-ink: #000;
}

/* ── Bağlam etiketi ───────────────────────────────────────
   Proje bağlantısı / lightbox görseli: daire 64px'e açılır ve dolgu
   %8'den %92'ye çıkar ki metin okunsun. Kural .is-active'ten SONRA
   gelir — aynı özgüllükte, sonraki kazanır (64px ve güçlü dolgu). */
.fx-cursor.is-label {
  --fx-cur-size: 64px;
  background-color: var(--fx-cur-fill-strong);
}

/* İki metin gözü aynı grid hücresinde durur: çapraz geçiş sırasında
   ikisi de aynı yerde, aynı genişlikte — hiçbir şey zıplamaz.
   Genişlik SABİT (56px): daire 14 → 64px büyürken metin yeniden
   akmaz, sadece dolgu ve boyut hareket eder. */
.fx-cursor__label {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.fx-cursor__t {
  grid-area: 1 / 1;
  width: 56px;
  font-family: inherit;
  font-size: 9.5px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  /* uzun tek kelimeli çeviri daireden taşmasın: yazı bölünür,
     tire eklenmez — iki satır 64px'lik daireye rahat sığar */
  overflow-wrap: break-word;
  hyphens: none;
  color: var(--fx-cur-ink);
  opacity: 0;
  transition:
    opacity 0.25s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    color 0.3s linear;
}
.fx-cursor__t.is-on { opacity: 1; }

/* ── Film grain ───────────────────────────────────────────
   Tam ekran, tıklamayı geçirir. z-index 100: içeriğin üstünde,
   menü (120) / tooltip (130) / scrollbar (150) / sayfa geçişi
   (190) altında. Kareler önceden üretilir; canlandırma yalnız
   hangi karenin görünür olduğunu değiştirir (CPU'da çizim yok). */
.fx-grain {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: var(--fx-grain-op, 0.035);
  contain: layout paint;
  transform: translateZ(0);     /* kendi katmanı: kare değişimi sayfayı boyamaz */
  transition: opacity 0.7s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}
.fx-grain.is-dark { --fx-grain-op: 0.055; }

.fx-grain__f {
  position: absolute;
  inset: 0;
  background-repeat: repeat;
  background-size: 128px 128px;
  opacity: 0;
}
.fx-grain__f.is-on { opacity: 1; }

/* ── Yardımcılar ──────────────────────────────────────────
   .fx-magnet / .fx-warp yalnız teşhis içindir: dönüşümü JS
   yazar (mıknatıs `translate`, deformasyon `transform`), böylece
   GSAP ve :hover kuralları ezilmez. */
.fx-magnet { will-change: translate; }
.fx-warp { will-change: transform; }

/* JS'in eklediği katmanlar dokunmatikte / azaltılmış harekette
   zaten oluşturulmaz; bu bloklar yalnız emniyet kemeridir.
   Etiket imlecin ÇOCUĞU: daire gizlenince o da gider. */
@media (hover: none) {
  .fx-cursor { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .fx-cursor { display: none !important; }
  .fx-cursor__t { transition: none; }
  .fx-grain { transition: none; }        /* grain kalır, ama hareketsiz */
  .fx-grain__f { transition: none; }
}
