/* ==========================================================================
   Nextern — Bileşen kütüphanesi (A: buton · form · kart · rozet · avatar)

   KURAL: bu dosya sabit RENK içermez; her renk tokens.css'ten gelir (test eder).

   ⭐ KURAL DEĞİŞTİ (Efe, 31 Tem 2026): *"Tüm ikonlarımız, objelerimiz scalable
   olmalı — native app için CTO küçültmesi gerekebilir."* Bu dosyanın eski kuralı
   ("bileşene özgü ölçüler sabit yazılır, bunlar bileşenin kendi geometrisidir")
   ARTIK GEÇERLİ DEĞİL. İKON · AVATAR · DENETİM boyları literal px yazılmaz;
   `--nx-ikon-*` / `--nx-avatar-*` / `--nx-kontrol-*` merdivenlerinden gelir
   (tokens.css §NESNE BOYU MERDİVENLERİ). Uzam/boşluk zaten token'dandı.

   Merdivene ÇEKİLMEYENLER (bilinçli, tek kullanımlık ya da düzen ölçüsü):
   `.nx-textarea` 96px içerik yüksekliği · üst çubuk kabuk yüksekliği
   *(15 Ağu 2026: literal DEĞİL artık — `--nx-ust-cubuk-taban`, D43)* ·
   mobil `.nx-segmented` 38px · yan menü 220px · dropdown 320px
   tavanı · ipucu 260px · tablo 560px tabanı · quest şeridi 12px · alt sayfa
   tutamacı 36×4. Bunlar DÜZEN/kabuk ölçüsüdür; native'de düzen zaten yeniden
   yazılır. Yeni bir İKON/AVATAR/DENETİM boyu gerekiyorsa merdivene eklenir.
   KURAL: mobil/native kurallar bu dosyada DEĞİL, mobile.css'te yaşar (ayrık katman).

   Efe'nin sistem kararları (bkz. Notes/karar-kart-buton-derinlik.md):
   · Yükselti = HALKA (`--nx-ring`), blur'lu gölge yok.
   · Hover/basma geri bildirimi = ÖLÇEK (`.nx-scalable`), yükselme yok.
   · Lime dolgu NADİRDİR — yalnız kullanıcıyı yönlendiren eylemler
     (Başvur · İleri · Premium). Sıradan eylemler halka/ikincil biçim kullanır.
   · Zemin değişen her durumda YAZI RENGİ de tanımlanır (yoksa metin okunmaz olur).
   · Semantik renk = işaret (ikon/kenarlık/tint), metin her zaman nötr.

   YÜKLEME SIRASI: tokens.css → ikon katmanları → components.css → mobile.css
   ========================================================================== */

/* ==========================================================================
   ODAK HALKASI — KANONİK VARSAYILAN (Tur B L-94, 1 Eki 2026 · taban töreni)
   Kendi `:focus-visible` kuralı olmayan odaklanabilir öğe (yalın bağ ·
   `tamamlar-bar` · doğrulama rozeti · profil verim halkası) tarayıcının
   varsayılan halkasına düşüyordu: ince, koyu; koyu temada 1–1,2:1, görünmez
   (B3, 1 Eki: `giris` · `kayit` · `gorevlerim` · `kimlik` · `profil`).
   ⇒ Sistemin halkası (`--nx-accent-on`, 2 px, dışa 2 px) tabanın varsayılanı.
   `:where()` ÖZGÜLLÜĞÜ 0: kendi kuralı olan her öğe (içe halka · dolgu
   üstünde ink · `outline: none` + başka gösterge) kendi kuralında kalır; bu
   blok yalnız BOŞLUĞU doldurur. Çatallarda aynı blok (components-sirket.css ·
   components-uni.css). Tablo satırında halka İÇE (kaydırma kabında kırpılmasın).
   📌 Dolgu kuralı: halka `--nx-accent-on`da kalır (`CLAUDE.md` §DOLGU KURALI);
      DOLGUNUN ÜSTÜNDE duran halka dolgunun yazı rengini alır (alt tab bar).
   ========================================================================== */
:where(:focus-visible) { outline: 2px solid var(--nx-accent-on); outline-offset: 2px; }
:where(tr:focus-visible) { outline-offset: -2px; }

/* ==========================================================================
   ODAK ÇUBUĞUN ALTINDA KALMAZ — KAYDIRMA PAYI (Tur B L-95, 1 Eki 2026 · taban töreni)
   Efe ESKİZ'de S1: «kaydırma çubuğun boyunu hesaba katar». Ölçüldü (B3,
   ORTULU-TAM 13, WCAG 2.4.11): Shift+Tab'la yukarı çıkarken tarayıcı odağı
   görünür alanın tepesine kaydırıyor, yapışkan üst çubuk (`.nx-topbar`) onu
   TAMAMEN örtüyordu (`bildirimler` · `egitim_sayfasi` · `gorevlerim` ·
   `profil` · `tum_ilanlar` · `tum_sirketler`); altta sabit hap ileri Tab'da
   kısmen örtüyordu (AAA 2.4.12).
   ⇒ Odaklanabilir öğe kaydırılırken üstte çubuk boyu + xs, mobilde altta hap
     payı kadar boşluk kalır (pay `.nx-sayfa-govde` formülü, mobile.css).
   ⭐ `html { scroll-padding }` DEĞİL: iki ekran (`kaydedilenler` liste öğesi ·
      `ayarlar` belge başlığı) üst çubuğu kendi `scroll-margin`inde zaten
      sayıyor — kaydırıcı payı ona EKLENİRDİ (çift sayım, odak boşluğu 4 → 48
      px). Öğe payı `:where()` ile özgüllük 0: ekranın kendi kuralı onu EZER.
      İç kaydırıcılar (çekmece · diyalog · liste kutusu) ve native tam ekran
      kipi (`body.nx-native`, `gorevlerim`: çubuklar gizli) hariç — orada çubuk
      yok (native dışlaması: Codex SOL kod kontrolü, 1 Eki). */
:where(a[href], button, input, select, textarea, summary, [tabindex]):not(:where(.nx-sheet, .nx-modal, [role="dialog"], [role="listbox"], .nx-native) *) {
  scroll-margin-top: calc(var(--nx-ust-cubuk) + var(--nx-space-xs));
}
@media (max-width: 599px) {
  :where(a[href], button, input, select, textarea, summary, [tabindex]):not(:where(.nx-sheet, .nx-modal, [role="dialog"], [role="listbox"], .nx-native) *) {
    scroll-margin-bottom: calc(var(--nx-tap-min) + var(--nx-space-md) + var(--nx-space-lg)
                               + env(safe-area-inset-bottom, 0px));
  }
}

/* ==========================================================================
   BUTON
   ========================================================================== */
.nx-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--nx-space-sm);
  /* Görsel varsayılan 48px (Efe kararı, 21 Tem 2026 — canlı app uyum oturumu,
     B2: ölçek 36/48/56; Material 48dp ile de hizalı). DOKUNMA TABANI ayrı bir
     kavramdır ve değişmedi: --nx-tap-min 44px, hiçbir dokunulabilir öğe altına
     inmez (36'lık küçük buton bilinen istisna). */
  min-height: var(--nx-kontrol-md);
  /* DİKEY İÇ BOŞLUK ZORUNLU (Efe bulgusu, 21 Tem 2026): yazı ile buton kenarı
     arasında minimum nefes payı — dikey space-sm. min-height tek satırda
     belirleyici kalır (boylar 36/48/56). */
  padding: var(--nx-space-sm) var(--nx-space-lg);
  border: 1px solid transparent;
  border-radius: var(--nx-radius-full);      /* pill — keskin köşe marka dışı */
  font-family: var(--nx-font);
  font-size: var(--nx-fs-label);
  font-weight: var(--nx-fw-semibold);
  line-height: 1.25;
  cursor: pointer;
  text-decoration: none;
  /* BUTON ASLA İKİ SATIR OLMAZ (Efe kararı, 21 Tem 2026): etiket sığmıyorsa
     bileşen sarmaz — METİN KISALTILIR. Taşan buton, "bu etiketi kısalt"
     sinyalidir; tasarım hatası butondadır sanılmasın diye buraya yazıldı. */
  white-space: nowrap;
  background: transparent;
  color: var(--nx-text);
}
.nx-btn:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 3px;
}
.nx-btn:disabled, .nx-btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; pointer-events: none;
}

/* --- Varsayılan (birincil değil): halka biçimi ---------------------------
   Sıradan eylemler burayı kullanır: Kaydet · Filtrele · Düzenle */
.nx-btn--default {
  box-shadow: var(--nx-ring);
  color: var(--nx-text);
}
@media (hover: hover) and (pointer: fine) {
  .nx-btn--default:hover {
    box-shadow: var(--nx-ring-hover);
    background: var(--nx-surface-2);
    color: var(--nx-text);                   /* zemin değişti → renk tanımlı */
  }
}

/* --- Sessiz (ghost): en düşük vurgu -------------------------------------- */
.nx-btn--ghost { color: var(--nx-muted); }
@media (hover: hover) and (pointer: fine) {
  .nx-btn--ghost:hover { background: var(--nx-surface-2); color: var(--nx-text); }
}

/* --- Vurgulu (accent): NADİR — yönlendirme eylemleri ---------------------
   Başvur · İleri · Premium'a geç

   Koyu tema: lime dolgu + kalın ink metin + glow · hover'da DOLGU koyulaşır
   Açık tema: ink dolgu + kırık beyaz metin        · hover'da METİN lime olur

   Neden farklı katman: lime dolgu üstünde ink dışında okunabilir metin rengi
   yok (kırık beyaz 1.16:1). Bu yüzden koyu tema hover cevabını dolguda verir.
   Ayna kuralının etkileşim boyutu — bkz. tokens.css "AKSAN AYNA KURALI". */
/* DOLGU KURALI (Efe, 31 Tem 2026 — Notes/karar-dolgu-glow-kurali.md):
   dolgu iki temada da lime, yazı ink, kenar yalnız glow'dan. Buton ≥40px → lg. */

/* ⭐⭐ NE ZAMAN `--accent`? — KAPSAM KURALI (Efe, 6 Ağu 2026)
   Efe: *"Kullanıcıyı bir ayar veya bir filtreye değil de KARİYERİNDE BİR YERE
   götürmeye yönlendirecek bütün butonlar aslında lime olmalı. Devam et gibi
   butonlar da lime olsun, göze batsın ki devam etsin."*

   🔴 **DÜZELTME — ölçüt GENİŞLEDİ (Efe, aynı gün):** *"bizim kuralımız kariyerde
   ileri taşıyan evet ama SADECE o değil ki. ANA YÖNLENDİRME butonları da lime
   olacak; çünkü kariyerde ileri taşıyan butonlar da yönlendirme, sadece kariyere
   yön veriyor."*

   ⭐⭐ TEK SORU (nihai): **bu, bulunduğu bağlamın ANA YÖNLENDİREN butonu mu?**
   Yani bu ekranın/çekmecenin/kartın asıl eylemi, kullanıcıyı bir sonraki adıma
   taşıyan şey bu mu? **Kariyeri ilerletenler bunun en önemli ALT KÜMESİDİR,
   tamamı değil.**

   ⚠️ BU BİR DARALTMA DEĞİL, GENİŞLETMEDİR. Önceki dar okuma yüzünden bir tur
     boyunca *"Kaydet · Değiştir · Şimdi ekle lime olmamalı"* sanılmıştı —
     **yanlıştı**: her biri kendi formunun/çekmecesinin ana yönlendiren butonu.
     Dokunulmadılar.

   ✅ LİME — bağlamın ana yönlendiren butonu:
      • kariyer hamlesi: Başvur · Başvuruyu gönder · Devam et · İncele · Başla ·
        Teste Başla · Eğitime git · Referans Talebi Gönder
      • avantaj satın alma: Premium'a geç · Paketleri gör
      • durum taşıyan yönlendirme: **Takip Et**
      • formun/çekmecenin asıl eylemi: Kaydet · Değiştir · Şimdi ekle
      • boş hâlin tek çıkış yolu: İlan alarmı kur · Eğitimleri keşfet ·
        İlanları keşfet · İlk sertifikanı kazan

   ⛔ LİME DEĞİL — ana eylem OLMAYANLAR:
      • liste denetimi: Filtrele · Temizle · Filtreleri temizle · Sayfa boyu · Sırala
      • gezinme: **Tümünü gör** · **Reddedilenleri gör** · Daha Fazla Göster
      • geri alma / ikincil: Vazgeç · Tekrar dene · tema/sıfırla test denetimleri
      • tamamlanmış durum: **Takip ediliyor** (davet bitti, artık bir durum)

   🔴 **"TAKİP ET" ⛔'DEN ✅'YE TAŞINDI (Efe, 6 Ağu 2026).** Önceki satır
   *"Takip Et — bir DURUM, eylem değil"* diyerek onu dışarıda tutuyordu; **yanlıştı.**
   Efe: *"şirketi takip etmesi öğrenci kullanıcı için kariyerinde bir AVANTAJ
   hareketi."* ⇒ Bir şeyin durum taşıması onu ölçütün dışına çıkarmıyor.
   ⭐ **A SEÇENEĞİ (Efe):** DAVET lime, DURUM nötr — `Takip Et` lime, basılınca
     `Takip ediliyor` nötre döner. Lime bir sonraki takip edilecek şirkete kalır.
     ⚠️ Kaydet düğmesinin TERSİ yönde, bilerek: kaydet sessiz bir **ikon** jesti
       (durumu işaretler), Takip Et **yazılı bir çağrıdır** (eylemi davet eder).

   ⭐ PRATİK SINAMA — **bir bağlamda EN FAZLA BİR lime.** İki lime yan yana
   çıkıyorsa ya biri ana eylem değildir ya da bağlam ikiye bölünmelidir.
   (6 Ağu'da tam bu oldu: profil video çekmecesinde iki lime alt alta düştü;
   Efe üç butonu **bire** indirdi.)

   ⭐ SINIRDAKİ ÜÇ GRUP KARARA BAĞLANDI (Efe, 6 Ağu 2026):
   ① **Premium/paket → LİME.** Efe: *"premium kariyerinde ileri taşıması için ona
      AVANTAJ SAĞLAYAN bir şey değil mi? EVET öyle, yani lime olacak."*
      ⇒ Ölçüt genişlemedi, doğru uygulandı: paket kullanıcının kariyerine avantaj
        satın alıyor. `profil.html`de nötr kalan tek premium butonu lime'a çevrildi;
        böylece premium eylemleri **üç ekranda da tutarlı**.
   ② **"Tümünü gör" / "Reddedilenleri gör" → NÖTR.** Listeye gitmek gezinmedir,
      "Daha Fazla Göster" ile aynı aile. Bugünkü hâl zaten doğruydu, dokunulmadı.
   ③ **"İlan alarmı kur" → LİME KALDI.** Mekanizması ayar ama boş hâlin TEK ileri
      yolu; boş hâl CTA'ları emsali (kimlik.html) zaten lime.
   ④ **"Takip Et" → LİME** (yukarıda, A seçeneği).
   ⑤ **Premium çekmecesi ÜÇ butondan BİRE indi** (Efe): *"sadece 1 premium
      önerilecek; onu almak için tıkladığında zaten paket sayfasında Premium+
      seçeneğini görecek. 1dk 2dk falan olmasın butonda ve tek buton olsun.
      Bastığında kamera ve galeri çıkacak zaten işletim sistemi arayüzünde."*
      ⇒ Kaynak seçimi (galeri/kamera) native picker'ın işi; süre bir PAKET
        DETAYI, buton etiketi değil. Bu, ⑤'in *"bir bağlamda en fazla bir lime"*
        sınamasının ilk gerçek uygulaması.

   ⚠️ BU, 30 Tem'deki *"lime buton nadir kalır"* kararını GEÇERSİZ KILMAZ, ona
   ÖLÇÜT verir. Eskiden "nadir" öznel bir sıklık hedefiydi; artık nadirlik bir
   SONUÇ: her bağlamda BİR ana eylem olduğu için oran kendiliğinden düşük kalıyor.

   📌 **ŞİRKET TARAFI (`adaylar.html`) KAPSAM DIŞI** — Efe, 6 Ağu 2026:
   *"Şirket sayfasına şu an hiçbir şey yapmıyoruz; bu bir mobil native app
   öncelikli ÖĞRENCİ tasarımı. Şirket kısmı tamamen farklı da olabilir,
   o sonranın çok sonranın işi."*
   ⇒ Bu kural **öğrenci tarafına** yazılmıştır; şirket tarafına UYGULANMAZ ve
     `adaylar.html`in bugünkü lime butonlarına **dokunulmaz**. */
.nx-btn--accent {
  background: var(--nx-dolgu);
  color: var(--nx-dolgu-yazi);
  font-weight: var(--nx-fw-on-accent);
  box-shadow: var(--nx-glow-lg);
}
@media (hover: hover) and (pointer: fine) {
  /* HOVER (Efe, 31 Tem 2026): AÇIKTA dolgu koyulaşır · KOYUDA glow güçlenir.
     Tek kural iki temayı da anlatıyor, çünkü token'lar temaya göre ayarlı:
       --nx-dolgu-hover   → koyu: sabit lime · açık: #2FE00F (koyulaşır)
       --nx-glow-lg-hover → koyu: opaklık .85 · açık: değişmez
     Yazı hover'da DEĞİŞMEZ (ink kalır) — eski "yazılı buton istisnası" düştü. */
  .nx-btn--accent:hover {
    background: var(--nx-dolgu-hover);
    box-shadow: var(--nx-glow-lg-hover);
  }
}

/* ⭐ KÜÇÜK ACCENT BUTON `md` KADEMESİ KULLANIR (Efe, 7 Ağu 2026).
   Efe sordu: *"düşürmen daha doğru değil mi?"* — evet, doğrusu buydu.
   Ben `profil.html`in "Ekle" panelinde Kaydet butonunun üst kenarının
   kırpıldığını görüp **kabın payını büyütmeyi** önermiştim; asıl hata payda
   değil, **butonun glow kademesinde**.
   CLAUDE.md merdiveni: ≥40px → 8px · **16-40px → 4px**.
   `.nx-btn--sm` = `--nx-kontrol-sm` = **36px** ⇒ `md` bandında, ama
   `.nx-btn--accent` boyuttan bağımsız `lg` (8px) yazıyordu.
   📌 Emsal zaten dosyada: doğrulama rozeti *"~29px olduğu için lg değil MD
     kademe"* diye açıkça md kullanıyor (aşağıda §ROZET). Kural biliniyordu,
     `--sm` butona uygulanmamıştı.
   ⇒ Yan kazanç: 36px buton için hover ihtiyacı 9,08px'ten **5,08px**'e iner
     ve 8px'lik panel payına SIĞAR — kırpılma kabı büyütmeden biter.
   ⚠️ Varsayılan buton (`--nx-kontrol-md` = 48px) ve `--lg` (56px) `lg`de
     KALIR; onlar merdivenin ≥40px basamağında. */
.nx-btn--accent.nx-btn--sm { box-shadow: var(--nx-glow-md); }
@media (hover: hover) and (pointer: fine) {
  .nx-btn--accent.nx-btn--sm:hover { box-shadow: var(--nx-glow-md-hover); }
}

/* --- Tehlikeli eylem -----------------------------------------------------
   Semantik renk kuralı: kenarlık ve ikon renkli, METİN NÖTR. */
.nx-btn--danger { box-shadow: 0 0 0 1px var(--nx-danger); color: var(--nx-text); }
.nx-btn--danger .nx-icon { color: var(--nx-danger); }
@media (hover: hover) and (pointer: fine) {
  .nx-btn--danger:hover { background: var(--nx-danger-tint); color: var(--nx-text); }
}

/* --- Boyut ve genişlik --------------------------------------------------- */
.nx-btn--sm { min-height: var(--nx-kontrol-sm); padding: var(--nx-space-xs) var(--nx-space-md);
              font-size: var(--nx-fs-caption); }
.nx-btn--lg { min-height: var(--nx-kontrol-lg); padding: var(--nx-space-sm) var(--nx-space-xl);
              font-size: var(--nx-fs-body-lg); }
.nx-btn--block { display: flex; width: 100%; }

/* ==========================================================================
   FORM
   ========================================================================== */
.nx-field {
  display: flex; flex-direction: column; gap: var(--nx-space-xs);
  margin-bottom: var(--nx-space-md);
}
.nx-label {
  font-size: var(--nx-fs-label); font-weight: var(--nx-fw-semibold);
  color: var(--nx-text);
}
.nx-label__ek { color: var(--nx-muted); font-weight: var(--nx-fw-regular); }

.nx-input, .nx-textarea, .nx-select {
  width: 100%;
  min-height: var(--nx-tap-min);
  padding: var(--nx-space-sm) var(--nx-space-md);
  background: var(--nx-surface-2);
  color: var(--nx-text);
  /* Girdi kenarı bir DENETİM ÖĞESİ sınırıdır → WCAG 1.4.11 gereği ≥3:1 */
  border: 1px solid var(--nx-border-field);
  border-radius: var(--nx-radius-md);
  font-family: var(--nx-font);
  font-size: var(--nx-fs-body-md);
  transition: border-color var(--nx-dur-fast) var(--nx-ease),
              box-shadow var(--nx-dur-fast) var(--nx-ease);
}
.nx-textarea { min-height: 96px; resize: vertical; line-height: var(--nx-lh-body);
               padding-top: var(--nx-space-md); }
.nx-select { appearance: none; cursor: pointer;
             padding-right: var(--nx-space-2xl); }

.nx-input::placeholder, .nx-textarea::placeholder { color: var(--nx-muted); }

/* 🔴 TARAYICININ KENDİ ARAMA SÜSLERİ KAPATILDI (Efe bildirdi, 6 Ağu 2026)
   Efe: *"burda neden 2 tane çarpı var ki, biri bize hiç uymuyor?"*

   `<input type="search">` tarayıcının KENDİ temizle düğmesini basar
   (`::-webkit-search-cancel-button`). Bizim `aria-label`lı, 44×44 dokunma hedefli
   temizle düğmemizin yanına ikinci ve YABANCI bir çarpı geliyordu: farklı boyda,
   farklı renkte, tema anahtarına tepkisiz, dokunma hedefi küçük.

   ⇒ Bizimki KALIR, tarayıcınınki gider. Gerekçe: yalnız estetik değil —
     tarayıcının düğmesi biçimlendirilemiyor (renk/boy/odak halkası hiçbiri bize
     bağlanmıyor) ve dokunma hedefi WCAG 2.5.8 tabanının altında kalıyor.

   ⚠️ SİSTEME YAZILDI, ekrana değil: aynı çift çarpı ALTI yerde birden vardı —
     Keşfet · dört liste ekranının arama çubuğu · filtre çekmecelerindeki faset
     arama alanı. Ekran-yerel düzeltilseydi altı kopya olurdu ve yedincisi
     unutulurdu.
   📌 `::-webkit-search-decoration` de kapatılıyor: bazı motorlarda soldaki
     büyüteç süsünü basar, bizim kendi arama ikonumuz zaten orada. */
.nx-input[type="search"]::-webkit-search-cancel-button,
.nx-input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

.nx-input:focus, .nx-textarea:focus, .nx-select:focus {
  outline: none;
  border-color: var(--nx-accent-on);
  box-shadow: 0 0 0 3px var(--nx-accent-soft);
}
.nx-input:disabled, .nx-textarea:disabled, .nx-select:disabled {
  opacity: .5; cursor: not-allowed;
}

/* Yardım metni nötr; hata durumunda da NÖTR kalır (semantik renk kuralı),
   rengi ikon ve kenarlık taşır. */
.nx-field__hint { font-size: var(--nx-fs-caption); color: var(--nx-muted); }

.nx-field--error .nx-input,
.nx-field--error .nx-textarea,
.nx-field--error .nx-select { border-color: var(--nx-danger); }
/* Hatalı alanda odak: kenar danger kalır (hata işareti), odak kanonik halkayla görünür — yalnız
   `--nx-accent-soft` hale (koyu ~1,3 · açık 1,18:1) WCAG 1.4.11'in altındaydı (Tur E kör denetçi). */
.nx-field--error .nx-input:focus-visible,
.nx-field--error .nx-textarea:focus-visible,
.nx-field--error .nx-select:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: 2px; }
.nx-field--error .nx-field__hint {
  display: flex; align-items: center; gap: var(--nx-space-xs);
  color: var(--nx-text); font-weight: var(--nx-fw-semibold);
}
.nx-field--error .nx-field__hint .nx-icon { color: var(--nx-danger); flex: none; }

/* --- Onay kutusu -----------------------------------------------------------
   Native görünüm KAPATILDI (`appearance: none`) çünkü tarayıcı varsayılanı
   köşe yarıçapını kabul etmiyor ve keskin kare kalıyor — bu, markanın
   "yuvarlak, samimi geometri" kuralını bozuyordu (Efe bildirdi, 21 Tem 2026).
   Öğe hâlâ gerçek bir `<input type="checkbox">`: klavye, ekran okuyucu ve
   form davranışı korunur.
   Dokunma hedefi etiketle birlikte 44px. */
.nx-check {
  display: flex; align-items: center; gap: var(--nx-space-sm);
  min-height: var(--nx-tap-min); cursor: pointer;
  font-size: var(--nx-fs-body-sm); color: var(--nx-text);
}
.nx-check input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  position: relative;
  width: var(--nx-kontrol-kutu); height: var(--nx-kontrol-kutu);
  flex: none; margin: 0; cursor: pointer;
  background: var(--nx-surface-2);
  border: 1px solid var(--nx-border-field);
  border-radius: var(--nx-radius-xs);      /* köşe ölçeğinden — keskin kare yok,
                                              ama daire de değil (radyo ile karışmasın) */
  transition: background var(--nx-dur-fast) var(--nx-ease),
              border-color var(--nx-dur-fast) var(--nx-ease);
}
/* İşaretli hal: lime dolgu + ink tik.
   ⛔ Buradaki eski gerekçe ("açık temada `--nx-accent-on` ink'e döndüğü için
   marka kuralı korunur") ARTIK GEÇERSİZ — dolgu iki temada da lime, ink'e
   dönen bir şey yok. Tik'in rengi bu yüzden dolgudan TÜRETİLİR, aksan
   token'ından değil; bkz. `::after` kuralındaki uyarı. */
/* DOLGU KURALI: 20px kare → md kademe (4px). Kenarlık dolguyla aynı renk
   olduğu için "kontur yok" maddesi onu da dolguya bağlar. */
.nx-check input[type="checkbox"]:checked {
  background: var(--nx-dolgu);
  border-color: var(--nx-dolgu);
  box-shadow: var(--nx-glow-md);
}
/* Tik işareti — MARKA İKON SETİNİN `check` yolu (2px strok, yuvarlak uç),
   maske olarak kullanılıyor. Böylece CSS ile "yeni bir tik çizmiyoruz";
   şekil setle birebir aynı, rengi token'dan geliyor.
   Kaynak: 02_Kurumsal_Kimlik/Ikon_Sistemi/Ikon_Seti_v1/svg/check.svg

   ⚠️⚠️ RENK `--nx-dolgu-yazi` OLMAK ZORUNDA, `--nx-on-accent` DEĞİL
   (final denetim bulgusu B1, 31 Tem 2026). O token AÇIK TEMADA LİME'dır;
   dolgu da artık iki temada lime olduğu için tik dolguyla BİREBİR aynı renge
   düşüyordu — ölçüldü: kontrast **1.00:1**, tik tamamen görünmez. Yani
   işaretli kutu açık temada İŞARETSİZ görünüyordu; kozmetik değil, işlevsel
   bir erişilebilirlik hatasıydı. Koyu temada 14.60:1 olduğu için gözden
   kaçmıştı. Kural: dolgunun ÜSTÜNDE duran her işaret `--nx-dolgu-yazi`
   kullanır — dolgu lime'a çevrildiyse üstündeki de birlikte taşınmalıdır. */
.nx-check input[type="checkbox"]::after {
  content: "";
  position: absolute; inset: 0;
  background: var(--nx-dolgu-yazi);
  -webkit-mask: var(--nx-tik-maske) center / 14px 14px no-repeat;
          mask: var(--nx-tik-maske) center / 14px 14px no-repeat;
  transform: scale(.4);
  opacity: 0;
  transition: transform var(--nx-dur-fast) var(--nx-ease),
              opacity var(--nx-dur-fast) var(--nx-ease);
}
.nx-check input[type="checkbox"]:checked::after {
  transform: scale(1); opacity: 1;
}
@media (hover: hover) and (pointer: fine) {
  .nx-check:hover input[type="checkbox"]:not(:checked) {
    border-color: var(--nx-text); background: var(--nx-surface-3);
  }
}
.nx-check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 2px;
}
.nx-check input[type="checkbox"]:disabled {
  opacity: .45; cursor: not-allowed;
}
@media (prefers-reduced-motion: reduce) {
  .nx-check input[type="checkbox"],
  .nx-check input[type="checkbox"]::after { transition: none; }
}

/* ==========================================================================
   TASARIM ANOTASYONU `.nx-hedef-rozeti` — KALDIRILDI (Efe kararı, 5 Ağu 2026)

   Ekranların tepesinde "🎯 Web + Mobil (parite)" gibi bir rozet duruyordu. Ürün
   UI’ı değildi; hangi platformu hedeflediğimizi iskelet üzerinde gösteren bir
   geliştirme notuydu ve Claude tarafından eklenmişti — tasarımın parçası değildi.

   Efe: "Bu zımbırtı bizim tasarımımız değil, senin koyduğun ve demo için...
   kalkması gerekiyorsa kalksın."

   Neden kalktı: iki ayrı bağımsız denetimde (1 Ağu ve 5 Ağu) marka dışı çok renkli
   glif olarak işaretlendi. 1 Ağu’da yalnız görünürlüğü kapatılmıştı
   (`display:none` + `body.nx-prototip` ile geri açma), ama emoji yerinde kaldığı
   için iskeleti açan herkes (CTO dâhil) görmeye devam ediyordu.

   Bilgi kaybolmadı: her ekran hedefini `<meta name="nx-hedef" content="...">` ile
   taşımaya devam ediyor — makine tarafından okunur, ekranda görünmez, marka
   yüzeyine hiç değmez.
   ========================================================================== */

/* ==========================================================================
   KART
   Derinlik HALKA ile verilir (Efe kararı: blur'lu gölge yok).
   İç içe kart ASLA.
   ========================================================================== */
.nx-card {
  background: var(--nx-surface-2);
  /* Kart bir <button> olarak da kullanılabilir (.nx-card--tiklanabilir). Tarayıcı
     düğmeye varsayılan `border: 1.25px outset buttonface` + `color: buttontext`
     uygular; halkamız `box-shadow` ile verildiği için bu bevel SIFIRLANMAZSA
     üstüne biner. Ölçüldü (31 Tem final denetim, B2): üst/sol gri, alt/sağ SAF
     SİYAH, iki temada birebir aynı — yani tema token'ı değil UA varsayılanı;
     375px'te 2px'e çıkıyor. `color` da miras alınmalı, yoksa buttontext siyahı
     token'ın yerine geçer. */
  border: 0;
  color: inherit;
  /* ⚠️ B2'nin KARDEŞİ (Efe, 4 Ağu): kart bir `<a>` olarak da kullanılabiliyor
     (Keşfet'te öyle) ve UA varsayılanı TÜM kart metnini altı çizili yapıyordu —
     şirket adı, meta satırı, hepsi. `color: inherit` yazılmış ama
     `text-decoration` sıfırlanmamıştı. Canlı yakalandı. */
  text-decoration: none;
  border-radius: var(--nx-radius-lg);
  box-shadow: var(--nx-ring);
  /* ⭐ KART DOLGUSU TEK TOKEN (Efe, 13 Ağu — "a şıkkı"): profil ekranındaki
     kartlar da ilan kartıyla AYNI kenar ölçüsüne geldi.
     ÖNCE: taban kart masaüstünde `lg` (24px), mobilde `md` (16px) kullanıyordu;
     ilan/şirket/eğitim kartları ise 12px'e ezilmişti ⇒ aynı ekranda iki farklı
     kart kenarı vardı ve profil tarafı sağdan/soldan/alttan/üstten yer
     kaybediyordu. Artık hepsi `--nx-kart-dolgu`.
     ⚠️ mobile.css'teki `.nx-card { padding }` kuralı da aynı token'a çekildi —
        o dosya components.css'ten SONRA yükleniyor ve aynı özgüllükte (0,1,0)
        kazanıyor; yalnız burayı değiştirmek sessizce etkisiz kalırdı
        (bu tuzak 6 Ağu'da yaşandı, aşağıdaki `.nx-ilan-kart` notuna bakılabilir).
     ⭐ 14 Ağu 2026: dolgu YATAY/DİKEY ayrıldı (D37 — yatay kenar sözleşmesi).
        Dikey 12'de kaldı, yatay 8'e indi ⇒ kartın içinde duran her arka plan
        sayfa kenarından 8+8 = 16px'te oturuyor, kural özyineliyor. */
  padding: var(--nx-kart-dolgu) var(--nx-kart-dolgu-yatay);
  display: flex; flex-direction: column; gap: var(--nx-space-md);
}
.nx-card__header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--nx-space-md);
}
.nx-card__title { font-size: var(--nx-fs-h3); font-weight: var(--nx-fw-bold); }
.nx-card__meta  { color: var(--nx-muted); font-size: var(--nx-fs-caption); }
.nx-card__body  { display: flex; flex-direction: column; gap: var(--nx-space-sm);
                  color: var(--nx-muted); font-size: var(--nx-fs-body-sm); }
.nx-card__footer { display: flex; align-items: center; gap: var(--nx-space-sm);
                   flex-wrap: wrap; }

/* Tıklanabilir kart bir DENETİM ÖĞESİDİR → kenarı ≥3:1 olmalı
   (marka denetçisi uyarısı, tokens.css T3 notu).
   ⚠️ box-shadow BURADA TANIMLANMAZ: aşağıdaki YÜZEN KART bölümündeki
   `.nx-card` kuralı aynı özgüllükte ve SONRA geldiği için buradaki halkayı
   eziyordu. Halka + yüzen gölge birlikte orada tanımlı (bkz. §YÜZEN KART). */
.nx-card--tiklanabilir {
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .nx-card--tiklanabilir:hover { background: var(--nx-surface-3); }
}
.nx-card--tiklanabilir:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 3px;
}

/* ==========================================================================
   ROZET
   ========================================================================== */
.nx-badge {
  display: inline-flex; align-items: center; gap: var(--nx-space-xs);
  padding: var(--nx-space-xs) var(--nx-space-sm);
  border-radius: var(--nx-radius-full);
  font-size: var(--nx-fs-caption); font-weight: var(--nx-fw-semibold);
  background: var(--nx-surface-3); color: var(--nx-muted);
  white-space: nowrap;
}
.nx-badge--neutral { color: var(--nx-text); }

/* ==========================================================================
   ⭐⭐ GÖSTERGE ROZETİ — KENDİNİ AÇIKLAR   (D48 · Efe, 15 Ağu 2026)

   11 Ağu kararı (`karar-gosterge-ogeleri-aciklanabilir`): işlevi OLMAYAN,
   yalnız bir durumu işaret eden öğe dokunulduğunda ne olduğunu anlatır — ve
   **öğe = dokunma alanı**, yani 44px'e çıkar, görünmez alan taşımaz.

   🔬 KAPSAM ÖLÇÜLDÜ, TAHMİN EDİLMEDİ (15 Ağu, 11 ekranda canlı DOM taraması):
   Devir notu dört aday sayıyordu; üçü **gösterge değil DENETİM** çıktı:
     · `.nx-sirket-kart__puan` → yorum çekmecesi açıyor (`yorumlariAc`)
     · `huni__satir` → hepsi `<button data-yakinda="Başvurularım · …">`
     · doğrulama rozeti → biri `<button>`, öteki bir `<button>`in içinde
     · "nadirlik göstergesi" → **böyle bir öğe hiç yok**
   ⇒ Gerçek gösterge ÜÇ taneydi; ikisi bu kuralı alıyor.

   🔶 BİLEREK KAPSAM DIŞI — `.nx-egitim-kart__puan` (Efe kararı, 15 Ağu):
     Bağlamak için 44px'e çıkması gerekiyordu ve ölçüldü: eğitim kartı
     116,6 → **140,3px** (tur başından beri +%34). Efe bedeli görüp seçmedi.
     Gerekçe: yıldız+sayı zaten kendini açıklıyor ve ekran okuyucuda
     *"4,9 üzerinden 5 puan"* diye tam okunuyor (gizli metin `tl-gizli`).
     ⛔ Bu bir unutma değil, **yazılı bir istisna** — sonraki oturum "eksik"
       sanıp eklemesin.
   ========================================================================== */
/* ⚠️ SEÇİCİ MODİFIER'A BAĞLI, `button.nx-badge`e DEĞİL — Codex iki regresyon
   gösterdi (15 Ağu) ve ilk yazımda seçici fazla genişti:
   ① `button.nx-badge:hover { color: var(--nx-text) }` kuralı
      `.nx-badge--verify { color: var(--nx-dolgu-yazi) }`ı **eziyordu** ⇒ koyu
      temada LİME DOLGU ÜSTÜNDE kırık beyaz metin (marka kuralı ihlali).
   ② `profil`in sertifika doğrulama düğmesi de `button.nx-badge` ⇒ yerel olarak
      ~29px tutulan hap 44px'e çıkıyor, sertifika satırı ~15px uzuyordu.
      Bu, D48'in kapsamında OLMAYAN üçüncü bir yerleşim değişikliğiydi.
   ⇒ Kural yalnız GÖSTERGE rozetlerine bağlandı. Bir rozet bu sınıfı ancak
     "işlevi yok, yalnız işaret ediyor" ölçüsünü geçerse alır. */
.nx-badge--gosterge {
  /* Öğe = dokunma alanı: rozetin GÖRÜNEN kutusu 44px olur, altında görünmez
     bir alan taşımaz. `min-height` tabanı; metin uzunsa rozet zaten büyür. */
  min-height: var(--nx-tap-min);
  /* Rozet bir düğme oldu ama görünüşü DEĞİŞMEZ — taban `.nx-badge` ne diyorsa o.
     Tarayıcının kendi düğme biçimlendirmesi sıfırlanır. */
  border: 0; cursor: pointer; font-family: var(--nx-font);
  /* ⚠️ GERİLMİŞ BAĞLANTININ ÜSTÜNDE — `.nx-kart-kaydet` ve `.nx-sirket-kart__puan`
     ile aynı gerekçe: gerilmiş `::after` kaplaması taşıyan bir kabın içine
     konursa rozete dokunmak kartı açar ve baloncuk hiç görünmez.
     📌 Bugünkü iki kullanıcısında gerilmiş kaplama YOK (profil referans yuvası
       bir `<div>`, gorevlerim kilitli satırı eylemsiz) — kural oralarda
       görünmez ama koruyucu; sonraki gösterge bir kartın içine düşerse çalışır. */
  position: relative; z-index: 1;
}
.nx-badge--gosterge:focus-visible { outline: 2px solid var(--nx-accent-on);
                                    outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .nx-badge--gosterge:hover { color: var(--nx-text); }
}

/* ⭐ Ürünün hendeği: "Üniversite Doğrulamalı" / "Onaylı Referans".
   HER İKİ TEMADA DA LİME (Efe kararı, 21 Tem 2026).

   Açık temada önce ink metin + soluk tint yapılmıştı; rozet silikleşiyor ve
   öne çıkması gereken şey kayboluyordu. Çözüm "koyu ada" kalıbı (buton için
   zaten onaylanmıştı): rozetin KENDİ ZEMİNİ koyulaşır, lime metin okunur
   kalır (14.60:1) ve marka kuralı korunur — lime yine koyu zeminde yaşıyor.
   İkon `currentColor` kullandığı için o da lime olur. */
/* DOLGU KURALI: doğrulama adası ~29px → md kademe. Eskiden koyuda yumuşak
   lime tint + lime yazı, açıkta ink ada + lime yazıydı; artık İKİ TEMADA DA
   lime dolgu + ink yazı. Tema başına ayrı kural gerekmiyor, tek kural yeter. */
.nx-badge--verify {
  background: var(--nx-dolgu);
  color: var(--nx-dolgu-yazi);
  box-shadow: var(--nx-glow-md);
}
/* HOVER — yalnız TIKLANABİLİR örneklere (Efe, 31 Tem 2026).
   Rozet iki biçimde yaşıyor: statik `<span>` (ör. `.ref-rozet` — sadece bilgi)
   ve `<button>` (`.sertifika__rozet` · kimlik-hub `.dogrulama` — doğrulama
   kaydını açar). Denetimde ölçüldü: düğme hâli hover'da HİÇ cevap vermiyordu
   (glow .55'te sabit) — dolgu kuralının hover maddesi bu öğeyi kapsadığı hâlde
   atlanmıştı. `button` seçicisi statik rozetleri dışarıda bırakır: bilgi veren
   bir rozetin hover'a cevap vermesi yanlış bir tıklanabilirlik sinyali olurdu.

   Sözleşme accent butonla AYNI: açıkta dolgu koyulaşır (--nx-dolgu-hover),
   koyuda glow güçlenir (--nx-glow-md-hover, opaklık .55→.85). Rozet ~29px
   olduğu için lg değil MD kademe. Yazı hover'da değişmez (ink kalır).

   `@media (hover: hover) and (pointer: fine)`: dokunmatikte yapışkan hover
   olmasın — `.nx-btn--accent` ile aynı koruma.
   Reduced-motion ayrıca yazılmadı: tokens.css'teki evrensel kural
   `transition-duration`'ı da kısıyor (§prefers-reduced-motion). */
@media (hover: hover) and (pointer: fine) {
  button.nx-badge--verify {
    /* `transform` şart — tokens.css'teki ölçek sözleşmesini ezmemek için. */
    transition: background var(--nx-dur-fast) var(--nx-ease),
                box-shadow  var(--nx-dur-fast) var(--nx-ease),
                transform   var(--nx-dur-fast) var(--nx-ease);
  }
  button.nx-badge--verify:hover {
    background: var(--nx-dolgu-hover);
    box-shadow: var(--nx-glow-md-hover);
  }
}

/* ⚠️⚠️ LİME DOLGU İÇİNDEKİ İKONUN AKSAN YOLU — final denetim bulgusu İ1
   (31 Tem 2026). `ikon.css` ikonun aksan parçasına `--nx-accent: var(--nx-accent-on)`
   verir; o token KOYU TEMADA LİME'dır. Dolgu da artık iki temada lime olduğu için
   aksan yolu dolguyla BİREBİR aynı renge düşüyordu — ölçüldü: doğrulama rozetindeki
   kalkan ikonunun iç tiki koyu temada **1.00:1**, yani görünmez. (Açık temada
   14.60:1 olduğu için gözden kaçmıştı; B1/B2'nin tam AYNASI — onlar açıkta,
   bu koyuda kayboluyordu.)

   `ikon.css:50` "ada kendi rengini ezer" diyordu ama bileşenlerin çoğu bu ezmeyi
   HİÇ YAZMAMIŞTI; boşluk oradaydı.

   Çözüm `--nx-dolgu-yazi` değil **`currentColor`**: bu kurallar zaten
   `color: var(--nx-dolgu-yazi)` yazıyor, yani aksan bileşenin KENDİ yazı rengini
   izler ve renk sistemi değişirse kendini onarır.

   ⚠️ YENİ BİR LİME DOLGULU BİLEŞEN EKLERKEN bu listeye de ekle — yoksa içindeki
   ikonun aksan yolu koyu temada kaybolur. Ekran-yerel dolgular kendi dosyalarında
   aynı satırı taşır.

   ⚠️⚠️ HEDEF `.nx-ico`/`.nx-icon` OLMAK ZORUNDA, KABIN KENDİSİ DEĞİL.
   `ikon.css` `--nx-accent`'i DOĞRUDAN `.nx-ico` üzerine yazıyor; özel değişken
   MİRASI, aynı öğedeki bir bildirime YENİLİR. Kaba yazmak hiçbir şey yapmaz —
   ilk denemede tam olarak bu oldu: ölçümde kap `currentColor` gösterirken ikon
   hâlâ `#39FF14` taşıyordu. Aşağıdaki `(0,2,0)` özgüllük `ikon.css`'in `(0,1,0)`
   bildirimini yener. */
.nx-btn--accent :is(.nx-ico, .nx-icon),
.nx-badge--verify :is(.nx-ico, .nx-icon),
.nx-chip[aria-pressed="true"] :is(.nx-ico, .nx-icon),
.nx-segmented button[aria-pressed="true"] :is(.nx-ico, .nx-icon),
/* ⭐ 7 Ağu 2026 — denetimde yakalandı, Efe kuralı: *"kendi içinde lime aksan olan
   ikonların hepsinde o lime'lar kalacak; ancak arkasında lime dolgu olacağı
   durumlarda o kısımlar da ink olacak Kİ GÖZÜKSÜNLER."*
   ⇒ Aksan lime KALIR (pasif sekmede, kartta, listede); yalnız LİME DOLGUNUN
     ÜSTÜNDE ink'e döner. Aşağıdaki iki satır o boşluğu kapatıyor.
   🔴 Alt tab 6 Ağu'da lime dolgulu bir bileşen oldu ama bu listeye eklenmemişti:
     aktif sekme ikonunun aksan yolu koyu temada lime dolgu üstünde lime kalıyordu
     (ölçüldü: 1.00:1). Aksan yolu taşıyan sekmeler: Kimlik (`target`) ·
     Başvurularım (`apply`). Açık temada sorun yoktu — `--nx-accent-on` orada
     zaten ink, yani hata yalnız KOYU temada görünüyordu. */
.nx-tabbar__item.is-active :is(.nx-ico, .nx-icon),
.nx-kart-kaydet[aria-pressed="true"] :is(.nx-ico, .nx-icon) {
  --nx-accent: currentColor;
}

/* ⭐ DAR KAPTA İKONLU ROZET = YALNIZ İKON (Efe kararı, 13 Ağu 2026)
   *"320 gibi daralmalarda 'doğrulandı' rozeti gibi ikonlu rozetlerde sadece ikon
   gözüksün, aksi hâlde yazıları sıkıştırıyor. Sıkışmanın olmayacağı mesela
   375'te rozet komple gelebilir."*

   ⭐ `@media` DEĞİL `@container`: bu bir İÇERİK kararı (D13). Rozet, ekranın
      genişliğine değil İÇİNDE BULUNDUĞU KABIN genişliğine göre sıkışıyor —
      masaüstünde viewport 1280 ama öğrenci sütunu 430px, `@media` orada yanlış
      cevap verirdi. Görev 6'da kurulan `ekran` container'ının ilk gerçek kullanımı.

   ⛔ METİN SİLİNMEZ, GÖRSEL OLARAK GİZLENİR: erişilebilir ad DOM'da kalır,
      ekran okuyucu "Doğrulandı"yı okumaya devam eder. Alt tab'daki profil
      etiketiyle aynı kalıp (1×1 + `clip-path`), aynı gerekçe.
   ⚠️ Kalıp 1×1'e sabittir, `--nx-nesne-olcek`e BAĞLANMAZ (CLAUDE.md: ekran
      okuyucu kırpma kalıbı ölçeklenmez). */
@container ekran (max-width: 320px) {
  .nx-badge__yazi {
    position: absolute; inline-size: 1px; block-size: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

/* Semantik rozetler: renk ikon ve kenarlıkta, METİN NÖTR */
.nx-badge--danger  { background: var(--nx-danger-tint);  color: var(--nx-text);
                     box-shadow: 0 0 0 1px var(--nx-danger); }
.nx-badge--warning { background: var(--nx-warning-tint); color: var(--nx-text);
                     box-shadow: 0 0 0 1px var(--nx-warning); }
.nx-badge--success { background: var(--nx-success-tint); color: var(--nx-text);
                     box-shadow: 0 0 0 1px var(--nx-success); }
.nx-badge--danger  .nx-icon { color: var(--nx-danger); }
.nx-badge--warning .nx-icon { color: var(--nx-warning); }
.nx-badge--success .nx-icon { color: var(--nx-success); }

/* BAŞARI — AÇIK TEMADA İNK+LİME ADA (Efe değerlendirmesinde, 22 Tem 2026).
   Doğrulama rozetinin "koyu ada" istisnasıyla aynı mantık, bileşen yerine
   İKON ölçeğinde: başarı ikonu ink bir disk üstünde lime yanar — lime açık
   zemine hiç değmez, kural korunur. Kenar/tint --nx-success üzerinden zaten
   ink/nötr'e döndü (tokens.css açık tema bloğu). Koyu temada değişiklik YOK. */
[data-theme="light"] :is(.nx-badge--success, .nx-alert--success, .nx-toast--success) .nx-icon {
  /* DOLGU KURALI (31 Tem): ada tersine döndü — eskiden lime ikon + ink disk,
     artık ink ikon + LİME disk. Disk hâlâ gerekli: lime ikon çıplak krem
     zeminde 1.16:1 ile kaybolurdu. ~20px → md kademe. */
  color: var(--nx-dolgu-yazi);
  background: var(--nx-dolgu);
  /* İ1: bu kural ZATEN ikonun kendisine (`.nx-icon`) uygulanıyor, o yüzden
     `--nx-accent` burada doğrudan yazılabilir — kap değil, hedef öğe. */
  --nx-accent: currentColor;
  box-shadow: var(--nx-glow-md);
  border-radius: var(--nx-radius-full);
  padding: 3px;
}

/* ==========================================================================
   AVATAR
   ========================================================================== */
.nx-avatar {
  width: var(--nx-avatar-md); height: var(--nx-avatar-md); flex: none;
  border-radius: var(--nx-radius-full);
  background: var(--nx-surface-3); color: var(--nx-text);
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: var(--nx-fw-semibold); font-size: var(--nx-fs-body-md);
  overflow: hidden; position: relative;
  user-select: none;
}
.nx-avatar img { width: 100%; height: 100%; object-fit: cover; }
/* `--xs`: GEZİNMEDEKİ profil görseli (Efe isteği, 21 Tem 2026 — Instagram
   kalıbı: profil sekmesinde ikon değil kullanıcının fotoğrafı durur).
   24px = gezinme ikonlarıyla aynı boy. */
.nx-avatar--xs { width: var(--nx-avatar-xs); height: var(--nx-avatar-xs); font-size: var(--nx-fs-caption); }
.nx-avatar--sm { width: var(--nx-avatar-sm); height: var(--nx-avatar-sm); font-size: var(--nx-fs-caption); }
.nx-avatar--lg { width: var(--nx-avatar-lg); height: var(--nx-avatar-lg); font-size: var(--nx-fs-h3); }

/* Gezinmede profil sekmesi aktifken avatar AKSAN HALKASI alır (Instagram'ın
   kalın çemberinin bizim dildeki karşılığı — renk ayna kuralından gelir). */
.nx-tabbar__item.is-active .nx-avatar,
.nx-sidebar__item.is-active .nx-avatar {
  box-shadow: 0 0 0 2px var(--nx-accent-on);
}

/* Doğrulanmış rozeti — avatarın köşesinde küçük aksan nokta */
.nx-avatar--verified::after {
  content: "";
  position: absolute; right: 0; bottom: 0;
  width: 30%; height: 30%;
  border-radius: var(--nx-radius-full);
  /* DOLGU KURALI: avatarın %30'u ≈ 14px → sm kademe (2px).
     Halka (0 0 0 2px surface) glow DEĞİL, avatardan ayıran boşluk — korunur;
     glow onun ardına eklenir. */
  background: var(--nx-dolgu);
  box-shadow: 0 0 0 2px var(--nx-surface-2), var(--nx-glow-sm);
}

/* Üst üste binen avatar dizisi (aday listesi, ekip) */
.nx-avatar-grup { display: inline-flex; }
.nx-avatar-grup .nx-avatar + .nx-avatar { margin-left: calc(var(--nx-space-sm) * -1); }
.nx-avatar-grup .nx-avatar { box-shadow: 0 0 0 2px var(--nx-surface); }

/* ==========================================================================
   ==========  B: GEZİNME · TABLO · GERİ BİLDİRİM · BOŞ DURUM  ==============
   ========================================================================== */

/* ==========================================================================
   ÜST ÇUBUK
   ========================================================================== */
.nx-topbar {
  display: flex; align-items: center; gap: var(--nx-space-md);
  /* ⭐ D43 (15 Ağu 2026): literal 64/56 GİTTİ, taban token'dan geliyor.
     Eskiden bu satır `min-height: 64px` yazıyordu ve `--nx-ust-cubuk` ile
     BAĞLI DEĞİLDİ — biri değişince öteki sessizce kaymıştı (10 Ağu bulgusu).
     ⛔ Burada KULLANILAN boy (`--nx-ust-cubuk`) okunmaz, TABAN okunur:
        çubuk kendi ölçülen yüksekliğini min-height olarak geri yerse
        küçülme kilitlenir (geri besleme döngüsü — Codex, 15 Ağu). */
  min-height: var(--nx-ust-cubuk-taban);
  padding: 0 var(--nx-space-lg);
  background: var(--nx-surface);
  border-bottom: 1px solid var(--nx-border);
  position: sticky; top: 0; z-index: var(--nx-z-sticky);
}

/* ⭐⭐ BAŞLIK SÖZLEŞMESİ — D43 (Efe, 15 Ağu 2026)
   *"Sarsın, çubuk uzasın"* — yazı büyütülünce başlık KISALTILMAZ.

   🔴 ÜÇ ÖLÇÜLMÜŞ KUSURU BİRDEN KAPATIR:
   ① `line-height` ARTIK SINIFIN KENDİSİNDE. Eskiden yoktu ⇒ `<h1>` global
      `h1,h2,h3 { line-height: 1.15 }` alıyor, `<p class="nx-topbar__title">`
      ise gövdeden **1.6** miras alıyordu. Ölçüldü: %200'de satır kutusu 46 ↔
      **64px**, çubuk 56 ↔ **65px**. `sirket_sayfasi` ve `egitim_sayfasi`
      başlığı bilerek `<p>` yazıyor (içerikteki gerçek ad `h1` olsun diye) ve
      yanlarına *"görsel hiçbir şey değişmiyor"* yorumu düşülmüştü — o cümle
      %200'de **ölçülebilir biçimde yanlıştı**.
   ② `min-inline-size: 0` — `min-width:auto` tuzağının bu projede DOKUZUNCU
      örneği. Onsuz tek kelimelik başlık (`Görevlerim` %200'de 213,4px)
      min-content'inin altına inemiyor ve satırı geriyor.
   ③ Tavan İKİ SATIR (Efe'nin seçtiği şıkkın metni: *"iki satıra kadar sarar"*).
      🔴 DÜRÜST OL: `-webkit-line-clamp` bir TAVAN değil KIRPMADIR — üçüncü
      satır gerekirse gizlenir ve Edge sonuna kendi eksiltmesini koyar.
      Yani *"içerik kaybı yok"* garantisi **iki satıra kadar** geçerlidir.
      📌 Bugün hiçbir başlık üçüncü satıra çıkmıyor (ölçüldü: @320 %200'de en
      uzun başlık `Tüm sertifikalar` 299,9px max-content, iki satıra sığıyor).
      Tavan bugün değil GELECEKTE bir uzun başlık geldiğinde iş yapar; o gün
      kırpma yerine çubuğun üçüncü satıra uzaması istenirse bu üç satır silinir.
   ④ `text-wrap` SINIFTA sabitlendi. Yoksa ①'in kardeşi bir ayrışma kalırdı:
      `<h1>` global kuraldan `balance`, `<p>` gövdeden `pretty`, `<span>`
      varsayılan alıyordu ⇒ aynı başlık üç ekranda farklı yerden bölünebilirdi
      (Codex, 15 Ağu). İki satırlık başlıkta `balance` doğru seçim: satırları
      eşitler, tek kelimelik ikinci satır bırakmaz.

   ⛔ `text-overflow: ellipsis` KULLANILMAZ — kırpma tam olarak reddedilen
      şıktı. Ekranların ve TASLAKLARININ yerel `nowrap`/`ellipsis` kopyaları
      bu turda silindi (14'ü birden — taslakları ilk turda atlamıştım, Codex
      yakaladı; `HATALARIM.md`deki "tüketici taraması depo geneli" maddesi).
   📌 `overflow-wrap` yalnız BÖLÜNEMEYEN tek kelime için son çare
      (`Başvurularım` @320 %200 = 254,9px).
   🔴 `hyphens: auto` EDGE'DE TÜRKÇE İÇİN ÇALIŞMIYOR — ölçüldü (15 Ağu):
      `lang="tr"` doğru yazılı ama motorda tr tireleme sözlüğü yok, kelime
      TİRESİZ sert kırılıyor. Bildirim yine de bırakıldı: destekleyen
      motorlarda (Firefox/Safari, ileride Edge) kendiliğinden düzelir ve
      hiçbir yerde zarar vermez. ⛔ *"lang=tr olduğu için tireleme çalışır"*
      diye yazmıştım — YANLIŞTI, ölçümle çürüdü. */
.nx-topbar__title {
  font-size: var(--nx-fs-h3); font-weight: var(--nx-fw-bold);
  line-height: var(--nx-lh-tight);
  text-wrap: balance;
  margin: 0;
  min-inline-size: 0;
  overflow-wrap: break-word;
  hyphens: auto;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
/* 🔴 ZORUNLU — 16 Ağu 2026'da canlıda yakalandı: yukarıdaki `display: -webkit-box`
   bir YAZAR kuralı, `[hidden]`ın `display: none`u ise TARAYICI varsayılanı.
   Yazar kuralı her zaman kazanır ⇒ `baslik.hidden = true` yazmak başlığı
   GİZLEMİYORDU (kimlik'in başlıksız şeridinde "Ka ri…" diye sıkışmış çıktı).
   ⚠️ `display` veren her bileşen kendi `[hidden]` kuralını da yazmak zorunda. */
.nx-topbar__title[hidden] { display: none; }
/* ⛔ MENÜ DARALTMA DÜĞMESİ KALDIRILDI — Efe kararı, 13 Ağu 2026 (A şıkkı).
   Buradaki `.nx-sidebar__toggle` ve `.nx-menu-x` (hamburger → marka X morfu)
   kuralları silindi.

   GEREKÇE: yan menü artık 220px değil, **82px rail**. Daraltma 82 → 64px, yani
   18px kazandırıyordu; düğme amacını kaybetti. Efe: *"A ile devam et."*
   ⇒ Rail TEK BİÇİMLİ: her zaman görünür, etiketler her zaman açık.

   ⚠️ BUNUNLA BİRLİKTE DÜŞEN 21 TEM 2026 KARARLARI (bilerek, kaydı burada):
     · "menü daraltma düğmesi menünün kendi tepesinde yaşar"
     · "daraltma GİZLEME değil rail'e küçültme" (`.is-dar`)
     · "menü açıkken hamburger marka X'ine morflar"
   Bu kararlar YANLIŞ olduğu için değil, dayandıkları 220px'lik menü ortadan
   kalktığı için düştü. `--nx-logo-x` token'ı yerinde duruyor (başka yerde de
   kullanılıyor); ölü kalan tek şey morf kuralıydı, o da silindi.

   ⭐ YAN FAYDA: `.nx-sidebar`ın `transition: width` satırı da gitti — o,
   bilinçli bir layout animasyonuydu ve tasarım kancasının işaretlediği üç
   layout-animasyonu bulgusundan biriydi. Daraltma yoksa animasyon da yok. */
.nx-topbar__actions { margin-left: auto; display: flex; align-items: center;
                      gap: var(--nx-space-sm); }

/* ==========================================================================
   ⭐⭐ BAŞLIKSIZ ÜST ŞERİT — `.nx-topbar--serit`   (Efe, 16 Ağu 2026)

   *"Tüm ANA SAYFALARIMIZ (alt tab'daki 4 sayfa) üstünde üst sütun ve başlık
   bulunmayacak şekilde revize edilecek. Arama çubuğu olan sayfalarda oraya
   arama çubuğu konulacak... her sayfada sağda kebab menü dursun, ıvır zıvırları
   hep oraya atarız."*

   NEDEN BAŞLIK GİTTİ: alt tab zaten hangi sekmede olduğunu söylüyor; başlık
   aynı bilgiyi ikinci kez veriyor ve ekranın en değerli şeridini yiyordu.
   ⇒ Şerit artık ekranın BİRİNCİL DENETİMİNİ taşıyor.

   KAPSAM — yalnız dört sekme ekranı: `kesfet` · `basvurularim` · `kimlik` ·
   `profil`. Alt sayfalar (dört `tum_*`, üç detay, `gorevlerim`) başlıklı üst
   çubuğu KORUR — orada geri düğmesi var ve başlık nerede olduğunu söylüyor.

   ⛔ `.nx-topbar`ın KENDİSİ kullanılıyor, yeni bir öğe icat edilmedi. Gerekçe:
     çentik payı · `sticky` · `z-index` · ve D43'ün `--nx-ust-cubuk` ölçümü
     (`kabuk.js` `.nx-topbar`ı ölçüyor) hepsi zaten burada. Yeni bir kap
     bunların dördünü de baştan kurmayı gerektirirdi.
   ========================================================================== */
.nx-topbar--serit {
  /* ⭐ ÜÇ YUVA — Efe, 16 Ağu 2026: *"onu da ortala, solda geri butonu varmış gibi
     olsun hepsi. Ama geri butonu olmayacak ana sayfalarda — varmış gibi olsun,
     geri butonu koyma oraya."*
     ⇒ SOL YUVA HER ZAMAN AYRILIR (44px) ama ana sayfalarda BOŞ durur. Böylece
       arama çubuğu alt sayfalardaki (geri düğmeli) hizasıyla BİREBİR aynı yerde
       başlar; sekmeler arası geçişte çubuk yatay olarak ZIPLAMAZ.
     📌 Sağ yuva `auto`: arama olan ekranlarda tek kebab (44) ⇒ iki yan eşit,
       çubuk gerçekten ortalı. `profil` gibi sağ kümesi kalabalık ekranlarda
       ortada arama zaten yok. */
  display: grid;
  grid-template-columns: var(--nx-tap-min) minmax(0, 1fr) auto;
  gap: var(--nx-space-sm);
  align-items: center;
}
/* Sol yuva — ana sayfalarda BOŞ (geri düğmesi YOK, yeri var). */
.nx-topbar__yuva { grid-column: 1; display: inline-flex; align-items: center; }
/* Birincil yuva: arama çubuğu · hedef düğmesi — ne gelirse. */
.nx-topbar__birincil { grid-column: 2; min-inline-size: 0; display: flex;
                       align-items: center; gap: var(--nx-space-sm);
                       /* ⭐ Tur B taban-6: çubuğun iç kutusu = taban − alt çizgi (43 px). Yuvaya
                          44 px'lik dokunma hedefi girince (Aura › hedef satırı) çubuk 45'e
                          çıkıyordu ⇒ öbür ekranlardan 1 px ayrışma. `.nx-kart-kaydet` kalıbı:
                          hedef 44 px KALIR, satıra çizgi kadar az katılır (simetrik ⇒ ortası
                          yerinde). 36 px'lik arama hapında etkisiz. */
                       margin-block: -0.5px; }
.nx-topbar--serit .nx-topbar__actions { grid-column: 3; margin-left: 0; }

/* ==========================================================================
   ⭐⭐ ARAMA ÇUBUĞU — `.nx-arama`   (Efe, 16 Ağu 2026)

   *"Arama çubuğunu tüm sayfalarda eşitle. Keşfet sayfasındaki gibi olacak."*
   ⇒ Keşfet'in ekran-yerel `.kf-arama` kuralı SİSTEME çıktı; Başvurularım da
     aynı bileşeni kullanıyor. Tek kaynak, tek görünüş.

   🔴 PILL ZORUNLU — Efe: *"biz PİLL yapısında olmayan yatay hiçbir şey
     kullanmıyoruz, unutma bunu."* Taban `.nx-input` `--nx-radius-md` (12px)
     kullanıyor; ölçüldü, Başvurularım'ın çubuğu 312×44'te r=12 ile yuvarlak
     DİKDÖRTGEN görünüyordu (Efe ekran görüntüsünde işaretledi).
   ========================================================================== */
.nx-arama { position: relative; display: flex; min-inline-size: 0;
            flex: 1 1 auto; }
/* ⭐ D56 (Efe, 16 Ağu 2026): pil 48 → 36 (`--nx-kontrol-md` → `--nx-kontrol-sm`).
   ⚠️ Punto DEĞİŞMEDİ — 14px (`--nx-fs-govde`) kalıyor. Sunulan C görüntüsünde
   13px denenmişti; D24 sistemde ÜÇ punto tanımlıyor (20/14/12) ve 13 bilerek
   kaldırılmıştı ⇒ geri getirilmedi. Okunan metin gövde puntosunda kalır. */
.nx-arama .nx-input {
  min-height: var(--nx-kontrol-sm);
  border-radius: var(--nx-radius-full);            /* PILL — pazarlıksız */
  /* İki yanda ikon + nefes payı: solda arama ikonu, sağda temizle düğmesi.
     İkonlar D56'da `sm`(18) → `xs`(16) indiği için formül de onu okur. */
  padding-inline: calc(var(--nx-space-md) + var(--nx-ikon-xs) + var(--nx-space-sm))
                  calc(var(--nx-space-md) + var(--nx-ikon-xs) + var(--nx-space-sm));
  font-size: var(--nx-fs-body-sm);
  /* D51 — açıkta içe, koyuda dışa gölge (derinlik). */
  box-shadow: var(--nx-alan-derinlik);
}
.nx-arama .nx-input:focus { box-shadow: none; }   /* odak halkasına yer aç */
.nx-arama__ikon { position: absolute; left: var(--nx-space-md); top: 50%;
                  transform: translateY(-50%); color: var(--nx-muted);
                  pointer-events: none; display: inline-flex; }
.nx-arama__ikon .nx-icon { width: var(--nx-ikon-xs); height: var(--nx-ikon-xs); }
/* ⚠️ D56: temizle düğmesi `--nx-tap-min`(44) DEĞİL `--nx-kontrol-sm`(36) —
   36px'lik pilin içinde 44px'lik bir kutu pili dikeyde taşırırdı. Bu, D56'da
   Efe'nin bilerek seçtiği 44px ödününün ikinci yeri. */
.nx-arama__sil { position: absolute; right: 0; top: 50%; transform: translateY(-50%);
                 width: var(--nx-kontrol-sm); height: var(--nx-kontrol-sm);
                 display: inline-flex; align-items: center; justify-content: center;
                 background: none; border: 0; padding: 0; cursor: pointer;
                 color: var(--nx-muted); border-radius: var(--nx-radius-full); }
.nx-arama__sil:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: -2px; }
.nx-arama__sil .nx-icon { width: var(--nx-ikon-xs); height: var(--nx-ikon-xs); }
.nx-arama__sil[hidden] { display: none; }

/* ⭐ D56 — ÜST ÇUBUKTAKİ İKON DÜĞMELERİ 44 → 36 (`--nx-kontrol-sm`).
   ⛔ SEÇİCİ NEDEN `.nx-topbar` ÖNEKLİ (0,2,0): `.nx-icon-btn`in tabanı
   `ikon.css`te (0,1,0) ve o dosya bundan ÖNCE yükleniyor — çıplak
   `.nx-icon-btn` yazsaydım eşit özgüllükte olur, bu dosya sonra geldiği için
   BUGÜN kazanırdı ama `mobile.css` ya da bir ekran `<style>`ı aynı özgüllükte
   bir kural yazdığı anda sessizce düşerdi. 16 Ağu'da aynı tuzağa ÜÇ kez
   düşüldü (`HATALARIM.md` §33). Önek bunu yapısal olarak imkânsız kılıyor.
   ⚠️ Kapsam BİLEREK dar: yalnız üst çubuk. Diğer yerlerdeki ikon düğmeleri
   44px tabanında KALIR — D56 üst çubuğun daralması kararıydı, sistem geneli
   bir dokunma hedefi indirimi değil. */
.nx-topbar .nx-icon-btn {
  min-width: var(--nx-kontrol-sm);
  min-height: var(--nx-kontrol-sm);
}

/* ==========================================================================
   ALAN DERİNLİĞİ — arama çubuğu ve benzeri "içine yazılan" yüzeyler
   Efe, 16 Ağu 2026: *"iç gölgeli bir tarzımız vardı, açıkta onu kullanalım;
   koyuda dış gölge yapalım ki arka planın birinde üstünde birinde içindeymiş
   gibi görünsün, derinlik katsın."*

   Aynalama ekseni dolgu/glow kuralının aynısı: **koyuda dışa, açıkta içe.**
   ⚠️ Renk LİME DEĞİL — bu bir marka aksanı değil yüzey derinliği. Lime dolgu
     *kullanıcının eylemini/durumunu* işaretler (6 Ağu netleştirmesi); boş bir
     arama alanı ne eylem ne durum.
   ========================================================================== */
.nx-derinlik { box-shadow: var(--nx-alan-derinlik); }
/* Odakta derinlik yerini odak halkasına bırakır — ikisi üst üste binerse
   halka okunmaz olur (odak halkası WCAG 2.4.7, derinlik yalnız süs). */
.nx-derinlik:focus-within { box-shadow: none; }

/* ==========================================================================
   SOL RAIL (≥600px) — mobilde yerini alt tab bar alır
   ========================================================================== */

/* ⭐ İKİ KATMAN — ALT TAB BAR'IN DİKEY İKİZİ (Efe, 13 Ağu 2026):
   *"rail da alt tab gibi ekranın dikeyinde tam ortalanmış olarak bulunmalı."*

   Alt tab bar da tam olarak böyle kurulu: DIŞ katman konumlandırır, İÇ katman
   yüzen hap'tır. Rail'de eksen dikeye döner:
     · `.nx-sidebar`      → şeffaf İZ. Yerini ayırır ve hapı dikeyde ortalar.
     · `.nx-sidebar__hap` → görünen yüzen kapsül (zemin + kenar + tam yuvarlak).

   ⛔ `position: fixed` KULLANILMADI — bilinçli. Alt tab bar `fixed` çünkü
      içeriğin ÜSTÜNDE yüzmesi isteniyor ve ekranlar ona alt boşluk payı
      bırakıyor (TAB-BAĞIMLI kurallar ailesi). Rail'i `fixed` yapsaydım aynı
      şeyi 11 ekranın SOL tarafı için baştan kurmak gerekirdi. `sticky` yerini
      akışta ayırdığı için içerik railin altına kaymaz, ek kural gerekmez.
   ⛔ ESKİ HÂL: 220px, tepeye yaslı, tam boy, sağında kenar çizgisi olan panel.
      Kenar çizgisi de kalktı — yüzen bir kapsülün panel kenarı olmaz. */
.nx-sidebar {
  flex: none;
  align-self: stretch;
  /* İz sayfayla kaymaz: üst çubuğun altına kilitlenir ve görünür alanı kaplar,
     hap onun İÇİNDE ortalandığı için kaydırma boyunca dikey merkezde kalır. */
  position: sticky;
  /* ⭐ D43 (15 Ağu 2026): üç literal `64px` token'a bağlandı. Yorum zaten
     *"= üst çubuk min yüksekliği"* diyordu, yani bağ niyet olarak vardı ama
     kodda YOKTU. Codex doğruladı ki bu değişim bugün davranış-nötr:
     `<600px`'te rail `display:none` (mobile.css), `≥600px`'te token zaten 64.
     ⚠️ ARTIK NÖTR DEĞİL, ÇALIŞIYOR: başlık sarıp çubuk uzayınca rail de
        onunla iniyor. Literal kalsaydı %200'de rail 1px yukarıda kelepçelenip
        çubuğun altına girerdi (ölçüldü: `egitim_sayfasi` @≥600 %200). */
  top: var(--nx-ust-cubuk);
  height: calc(100vh - var(--nx-ust-cubuk));         /* dvh/ölçek bilmeyene taban */
  height: calc(var(--nx-ekran-y) - var(--nx-ust-cubuk));   /* ölçeğe duyarlı */
  display: grid;
  align-content: center;              /* ⭐ dikey ortalama burada olur */
  justify-content: center;
  padding-inline: var(--nx-space-md);
  /* İz görünmez: zemin ve kenar artık hapın üstünde. */
  background: none;
  border: 0;
}

/* ⭐ RAIL DİKEYDE UZAR — YATAY HAPIN GERÇEK AYNASI (Efe, 13 Ağu 2026):
   *"yukarı ve aşağı doğru uzayacak ki tam yataydaki pill gibi bu da dikeyde
   pill görünümüne kavuşsun... yatayda sabit kalabilir ama uzasın, şu an çok
   basık duruyor."*

   ÖLÇÜLEN SORUN: yatay hap 298×54 ⇒ uzama oranı 5,5. İlk rail 82×230 ⇒ 2,8.
   Yani kapsül değil, yuvarlatılmış bir kutu gibi okunuyordu.

   ⛔ GENİŞLİK DEĞİŞMEZ (Efe: "yatayda sabit kalabilir"): yatay dolgu `xs`te
      kalır, hap 82px'te durur. Uzama YALNIZ dikey eksende.
   ⚠️ ÖĞE DİKEY DOLGUSU BURADA TAB BAR'DAN AYRILIR (8 → 16). Bu bir kayma DEĞİL,
      eksen farkı: yatay hapta öğeler pilin KISA eksenine diziliyor, dikeyde ise
      UZUN eksenine. Aynı dolguyu vermek dikeyde hapı basıklaştırıyordu.
      📌 Kısıt korunur: dolgu üstte ve altta EŞİT kaldığı için `g + L = i`
         (4 + 14 = 18) bozulmaz — o kural ikonun dolgu içindeki merkezlenmesini
         yönetir, dolgunun KALINLIĞINI değil. Paylaşılan `i · g · L` değişmedi.

   🔴 CASCADE TUZAĞI — ölçümde yakalandı (13 Ağu): bu ayrım önce
      `.nx-sidebar { --nx-tab-ust: … }` diye ezme olarak yazılmıştı ve
      SESSİZCE ÇALIŞMADI. Sebep: paylaşılan `.nx-tabbar, .nx-sidebar { --nx-tab-ust: 8px }`
      bildirimi dosyada DAHA SONRA (tab bar bölümünde) geliyor; aynı özgüllükte
      sonra gelen kazanır. Hap 230→250 büyüdü ama öğe 52'de kaldı, yani sayı
      değişti hata görünmedi. ⇒ Ezme, değişken üzerinden değil TÜKETEN KURALIN
      kendisinde yapılır (aşağıdaki `.nx-sidebar__item` dolgusu). */

.nx-sidebar__hap {
  /* ⭐ TEK SÜTUN GRID (D11b/D15). `justify-items: stretch` + `fit-content` ⇒
     sütun EN GENİŞ öğeye ("Başvurular") oturur ve DÖRDÜ BİRDEN ona eşitlenir.
     Biri uzarsa dördü birden büyür — `min-inline-size` bunu VERMEZ, D15'in
     gerekçesi tam olarak buydu.
     ⛔ `grid-auto-flow: column` VERİLMEZ — o rail'i YATAY çizer. 12 Ağu'da tam
        bu oldu ve ölçümde 310×66 olarak yakalandı; `row` açıkça yazılıyor. */
  display: grid;
  grid-auto-flow: row;
  justify-items: stretch;
  inline-size: fit-content;
  block-size: fit-content;
  /* Dikeyde nefes: öğe arası ve hap iç dolgusu bir kademe açılır (4 → 8).
     Yatay dolgu `xs`te KALIR — genişlik 82px'te sabit (Efe). */
  gap: var(--nx-space-sm);
  /* ⭐ `+ 1px` KENARLIK TELAFİSİ (12 Eyl 2026) — süs değil, ÖLÇÜ koruması.
     Aşağıdaki `border: 0` kararıyla birlikte doğdu: kenarlık kutuyu büyütür,
     kalkınca kapsül 82×314 → 80×312'ye düştü ve yan menü normal akışta olduğu
     için `main.nx-icerik` ile birlikte SAYFA İÇERİĞİ 1px sola kaydı. Ölçüldü:
     kesfet 323 · profil 377 · ayarlar 109 öğe kaymıştı.
     ⛔ Bu 1px'ler kaldırılamaz — kaldıran, üstteki "82px'te sabit (Efe)"
        kararını sessizce bozar. İkisi TEK karardır.
     📌 Ders (HATALARIM §110): `box-shadow: 0 0 0 1px` BOYASAL, `border: 1px`
        ÖLÇÜSEL. Ekranda ikisi de 1px çizgidir, ama yalnız ikincisi kutuyu
        büyütür. Kart ailesinde halka silinirken telafi gerekmedi; burada
        gerekti. Aynı kefeye konamazlar. */
  padding: calc(var(--nx-space-sm) + 1px) calc(var(--nx-space-xs) + 1px);
  /* Hap biçimi alt tab bar'la aynı sözleşmeden gelir: zemin + 1px kenar +
     tam yuvarlak + `overflow: hidden` (uç öğeler kapsülün köşesini takip eder).
     ⭐ CAM (Efe, 13 Ağu): rail de alt tab gibi bulanık. Aynı token, aynı yarıçap —
     iki gezinme biçimi tek görsel dilde kalır. */
  background: var(--nx-cam);
  backdrop-filter: blur(var(--nx-cam-blur));
  -webkit-backdrop-filter: blur(var(--nx-cam-blur));
  /* ⭐ KENARLIK KALDIRILDI — "B seçeneği" (Efe kararı, 12 Eyl 2026).
     Efe üç seçenek arasından seçti: cam KALIR, çizgi gider, kenarı yalnız
     yumuşak gölge taşır. (A: cam gidip opak kart zemini olacaktı.)
     🔴 BURASI KARTLARDAN FARKLIYDI, ÖLÇÜLDÜ: hapın hiç `box-shadow`u yoktu —
        1px çizgi onun TEK kenarıydı. Kartlarda halkayı silmek yeterliydi çünkü
        altta zaten `--nx-yuzen` duruyordu; burada gölge YAZILMASAYDI kapsül
        sınırsız kalırdı. ⇒ `box-shadow` bu kararla EKLENDİ, devralınmadı.
     📌 Alt tab bar'ın çizgisi DURUYOR: o dört kenar değil tek kenar
        (`border-top`), yani kapsül konturu değil AYRAÇ. Geometriyi paylaşıyorlar,
        bu kuralı paylaşmıyorlar. */
  border: 0;
  box-shadow: var(--nx-yuzen);
  border-radius: var(--nx-radius-full);
  /* ⛔ `overflow: hidden` KALDIRILDI — Efe, 16 Ağu 2026 (aynı gerekçe
     `mobile.css` `.nx-tabbar`da): bildirim noktası TAM DAİRE olarak hapın
     dışında görünmeli. */
  /* Etiket tek satırda kalmalı: öğe boyu `g + L = i` kısıtından geliyor ve L
     tek satır kutusu varsayıyor. Sarma olsaydı öğe 52px'i aşar, hücre
     eşitliği ve kısıt birlikte bozulurdu. */
  white-space: nowrap;
}
/* ⛔ GERİ DÜŞÜŞ — cam desteklenmiyorsa OPAK zemin (alt tab bar ile aynı gerekçe).
   Rail yalnız components.css'te tanımlı, sonra gelen bir ezme yok ⇒ blok burada
   durabilir. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nx-sidebar__hap { background: var(--nx-surface); }
}

/* ⛔ `.is-dar` (64px ikon şeridi) KALDIRILDI — Efe kararı 13 Ağu, A şıkkı.
   Rail zaten dar olduğu için daraltma 18px kazandırıyordu. Gerekçe ve düşen
   21 Tem kararlarının kaydı yukarıda, `.nx-topbar__actions` üstündeki blokta. */

/* Tam gizleme HÂLÂ tanımlı ama VARSAYILAN DEĞİL: yalnız içerik-kanvası odaklı
   ekranlar (örn. tam ekran video inceleme) gerekçesiyle kullanılabilir. */
.nx-sidebar.is-kapali { display: none; }

/* ⭐ RAIL ÖĞESİ — ETİKET İKONUN ALTINDA (D11b).
   Geometri alt tab bar'la BİREBİR AYNI değişkenlerden gelir (yukarıdaki
   `.nx-tabbar, .nx-sidebar` bloğu): `g + L = i` kısıtı iki gezinme biçiminde
   de aynı sayılarla çözülür. Gerekçe (Efe, 12 Ağu): kullanıcı telefonda
   öğrendiği adı tablette AYNI YERDE görür.
   ⚠️ Değişkenler paylaşıldığı için ikisi sessizce ayrışamaz — ayrı ayrı
      yazılsalardı biri güncellenip öteki unutulurdu. */
.nx-sidebar__item {
  display: grid; justify-items: center; align-content: start;
  gap: var(--nx-tab-aralik);
  /* Üst ve alt EŞİT — alt tab bar'daki kısıt ② burada da geçerli.
     ⚠️ DİKEY dolgu `md` (16), tab bar'ın `--nx-tab-ust`u (8) DEĞİL: rail uzun
     eksende dizildiği için aynı dolgu onu basıklaştırıyor (Efe, 13 Ağu).
     Değişken ezmesiyle YAZILMAZ — cascade sırası yüzünden sessizce düşer,
     bkz. yukarıdaki "CASCADE TUZAĞI" notu. Öğe: 16+18+4+14+16 = 68px. */
  padding: var(--nx-space-md) var(--nx-space-xs);
  min-block-size: var(--nx-tap-min);
  border-radius: var(--nx-radius-full);
  color: var(--nx-muted); text-decoration: none;
  position: relative;
  transition: background var(--nx-dur-fast) var(--nx-ease),
              color var(--nx-dur-fast) var(--nx-ease);
}
@media (hover: hover) and (pointer: fine) {
  .nx-sidebar__item:hover { background: var(--nx-surface-2); color: var(--nx-text); }
}
/* ⭐ AKTİF ÖĞE = LİME DOLGU + INK YAZI (CLAUDE.md §DOLGU KURALI).
   Aktif sekme 6 Ağu'da dolgu kuralının İSTİSNASINDAN ÇIKTI: metin ink kalır,
   lime arkaya dolgu olarak geçer (ölçüldü: 14.60:1). Alt tab bar'da bu kayan
   bir `::before` göstergesiyle yapılıyor; rail'de gösterge KAYMAZ —
   ⛔ kayan gösterge JS'ten px konum alıyor (`--nx-tab-x`/`--nx-tab-w`) ve o
      mantık YATAY; dikey rail'e uygulanması ayrı bir iştir, uydurulmadı.
   Dolgu doğrudan öğenin kendisine verilir; biçim yine stadyum.
   ⚠️ Glow `-ic` (inset) ŞART: `.nx-sidebar` `overflow-y: auto` taşıyor, yani
      KIRPAN bir kap — dışa glow orada kare görünür (tokens.css uyarısı).
   ⚠️ Kademe `lg` (8px): öğe 72×52, iki eksende de ≥40px.
   📌 Koyu temada bu glow no-op (lime üstünde lime) — alt tab bar'la aynı
      bilinçli boşluk, bkz. karar-denetim-7agu-netlestirmeler §⑤. */
.nx-sidebar__item.is-active {
  background: var(--nx-dolgu);
  color: var(--nx-dolgu-yazi);
  box-shadow: var(--nx-glow-lg-ic);
}
.nx-sidebar__item:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 2px;
}

/* ==========================================================================
   ALT TAB BAR (native + mobil web)
   ========================================================================== */
/* Masaüstünde GİZLİ — orada gezinmeyi yan menü taşır, ikisi birden gösterilmez
   (Efe bunu doğrulama sayfasında yakaladı, 21 Tem 2026: kural eksikti).
   Mobilde mobile.css açar. */
.nx-tabbar {
  display: none; align-items: stretch;
  background: var(--nx-surface-2);
  border-top: 1px solid var(--nx-border);
  /* iPhone home bar'ın üstünde durur, sekmeler çubuğun altına kaçmaz */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* ⭐ GÖSTERGE GEOMETRİSİ — tek yerden (ölçeklenme göçü, Görev 3 · 12 Ağu 2026)
   Stadyum: iki yarım daire + ortada dikdörtgen, YALNIZ ikonun arkasında;
   etiket onun ALTINDA kalır (Efe, 12 Ağu). Ölçüler `_Taslaklar/
   alt_tab_hap_boyu_KARSILASTIRMA.html`de D varyantı olarak seçildi.
   📌 Literal px BİLEREK: bunlar kabuk/düzen ölçüleri, nesne merdiveni
      kapsamı dışında (CLAUDE.md §Ölçeklenebilirlik — "merdivene
      çekilmeyenler: üst çubuk, yan menü genişliği" ile aynı sınıf). */
/* ⭐ DOLGU İÇİ GEOMETRİ — göz kararı DEĞİL, iki kısıttan çözüldü (Efe, 12 Ağu):
     ① "ikonun alt sınırı dolgunun merkezine denk gelsin"      ⇒ a + i = H/2
     ② "yazının alt sınırı ile ikonun üst sınırı, dolgunun alt
        ve üst sınırına EŞİT uzaklıkta olsun"                  ⇒ a+i+g+L = H−a
   İkisi birleşince tek kural kalır:  ⭐ g + L = i
   (aralık + etiketin satır kutusu = ikon boyu). Sayılar keyfî seçilemez.

   Seçilen çözüm:  H=44 · a=4 · i=18 · g=4 · L=14   →  4+18+4+14+4 = 44 ✓
   ⛔ `--nx-tab-etiket-lh` PX cinsinden SABİT: punto dar ekranda 11→10 düşse
      bile satır kutusu 14px kalır ⇒ geometri bozulmaz. Oransal (1.2) yazılsaydı
      punto her değiştiğinde iki kısıt da sessizce ihlal edilirdi. */
/* ⭐ GEOMETRİ İKİ GEZİNME BİÇİMİNDE PAYLAŞILIR (13 Ağu 2026): alt tab bar ve
   sol rail AYNI değişkenlerden beslenir. Gerekçe: `g + L = i` kısıtı ikisinde
   de geçerli; ayrı ayrı yazılsalardı biri güncellenip öteki unutulurdu ve fark
   ancak canlıda gözle yakalanırdı. Tek kaynak = sessiz ayrışma imkânsız. */
.nx-tabbar,
.nx-sidebar {
  --nx-tab-gos-w: 64px;          /* yatay: öğenin taban genişliği */
  --nx-tab-ikon: 18px;           /* i */
  --nx-tab-aralik: 4px;          /* g */
  --nx-tab-etiket-lh: 14px;      /* L */
  --nx-tab-ust: 8px;             /* dolgu inseti (4) + a (4) */
}

.nx-tabbar__item {
  display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start; gap: var(--nx-tab-aralik);
  min-height: var(--nx-tap-min);
  /* Üst ve alt EŞİT — kısıt ② bunu zorunlu kılıyor */
  padding: var(--nx-tab-ust) var(--nx-space-xs);
  color: var(--nx-muted); text-decoration: none;
  /* ⚠️ SARMA YASAK (6 Ağu 2026, hap daraltılırken eklendi).
     Etiketler `nxKabuk.kisalt()` ile zaten kısaltılmış hâlde geliyor. Yine de
     dar bir cihazda ya da %200 metin büyütmede sararsa, hap İKİ SATIRA çıkar ve
     YÜKSEKLİĞİ DEĞİŞİR — bu yalnız çirkin değil, ekranların düzenini bozar:
     ilan ve eğitim/sertifika sayfalarının alt sabit çubuğu hapın ~65px'lik
     boyuna göre hesaplanıyor.
     📌 13 Ağu 2026: bu cümle eskiden "…ile Keşfet'in solma örtüsü" diye devam
        ediyordu. Solma örtüleri o gün kaldırıldı (alt tab cam oldu), atıf da
        düşürüldü — kalsaydı var olmayan bir bağımlılığı işaret ederdi.
     ⇒ Başarısızlık kipi öngörülebilir olsun: sarmak yerine kırpılır. */
  white-space: nowrap;
  font-size: var(--nx-fs-caption); font-weight: var(--nx-fw-semibold);
  background: none; border: 0; cursor: pointer;
  font-family: var(--nx-font);
  transition: color var(--nx-dur-fast) var(--nx-ease);
}
/* ═══ AKTİF SEKME
   Gösterge öğenin TAMAMINI kaplar (etiket dahil) ⇒ ikon da etiket de LİME
   DOLGUNUN ÜSTÜNDE durur ⇒ ikisi de ink. Renk tek yerden, aşağıdaki kayan
   gösterge bölümünde verilir (§ALT TAB KAYAN GÖSTERGE).
   ⛔ `--nx-accent-on` KULLANILMAZ: o token koyu temada lime'dır ve lime dolgu
      üstünde 1:1 ile kaybolur.
   📌 12 Ağu'da bir ara renk ikiye ayrılmıştı (ikon ink / etiket normal metin),
      çünkü gösterge o sırada yalnız ikonun arkasındaydı ve etiket çıplak hap
      yüzeyine düşüyordu. Gösterge etiketi geri kapsayınca ayrım gereksizleşti.
   📌 Aktiflik üç kanaldan okunur: dolgu · kalın yazı · `aria-current="page"`.
      Renk tek taşıyıcı değil (karar-semantik-renk E1). */
.nx-tabbar__item.is-active { font-weight: var(--nx-fw-bold); }
.nx-tabbar__item:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: -2px;
}

/* ═══ STADYUM GÖSTERGE KABI + ETİKET (12 Ağu 2026) ═══
   İkon bu kabın içinde yaşar; kayan `::before` göstergesi tam bu kabın
   arkasına oturur. Etiket kabın ALTINDA, göstergenin dışında. */
.nx-tabbar__item { position: relative; z-index: 1; }   /* ::before z-index:0'ın üstünde */
/* Kap YALNIZ yatay tabanı verir; dikeyde ikonun kendi boyunda kalır —
   fazladan yükseklik kısıt ①'i (ikon altı = dolgu merkezi) bozardı. */
.nx-tabbar__gosterge,
.nx-sidebar__gosterge {
  display: grid; place-items: center;
  inline-size: var(--nx-tab-gos-w);
  block-size: var(--nx-tab-ikon);
}
/* 🔴 DÜZELTME (13 Ağu 2026, A2 incelemesi): burada eskiden *"İkon merdivende
   yok (18px)"* yazıyordu — **yanlıştı**. 18px merdivende VAR: `--nx-ikon-sm`
   (tokens.css §NESNE BOYU MERDİVENLERİ, "18px metin-içi"). Kaçış yolu
   gereksizdi; kural gereği merdivenden gelmeli.
   ⚠️ ÇİFT ÖLÇEK TUZAĞI — `--nx-tab-ikon`e `var(--nx-ikon-sm)` ATANMAZ:
      o token ölçeği ZATEN içinde taşır (`calc(18px * --nx-nesne-olcek)`),
      eski `calc(var(--nx-tab-ikon) * --nx-nesne-olcek)` satırıyla birleşince
      18 × ölçek² olurdu. Merdiven doğrudan burada kullanılır.
   📌 `--nx-tab-ikon` (18px) YERİNDE KALIR ve ölçeksizdir — o artık ikonun boyu
      değil GEOMETRİ SABİTİ: `g + L = i` kısıtının `i`si, yani göstergenin slot
      yüksekliği. Slot sabit, glif içinde ölçeklenir. */
.nx-tabbar__gosterge :is(.nx-ico, .nx-icon),
.nx-sidebar__gosterge :is(.nx-ico, .nx-icon) {
  inline-size: var(--nx-ikon-sm);
  block-size:  var(--nx-ikon-sm);
}
/* ⛔ `line-height` PX — oransal yazılsaydı punto değişince L de değişir ve
   `g + L = i` kısıtı sessizce bozulurdu (bkz. yukarıdaki geometri notu). */
.nx-tabbar__etiket,
.nx-sidebar__etiket { font-size: 11px; line-height: var(--nx-tab-etiket-lh); }

/* ═══ PROFİL SEKMESİ — ALAN TAMAMEN FOTOĞRAFA (Efe, 12 Ağu 2026) ═══
   Etiket kalksa da ÖĞE BOYU DEĞİŞMEZ, yoksa hücreler eşitliğini kaybederdi:
     diğer sekmeler → 8 + 18(ikon) + 4(aralık) + 14(etiket) + 8 = 52
     profil sekmesi → 8 + 36(avatar)                        + 8 = 52  ✓
   Avatar 36px merdivende yok (24/32/48/72) ⇒ belgelenmiş kaçış yolu: çarpanla
   yaz, `--nx-nesne-olcek` knob'u buraya da ulaşsın.
   ⭐ 36 = ikon + aralık + etiket alanının tamamı ⇒ fotoğraf o alanı bütün alır
      ve dikeyde tam ortalanır (4→40, dolgunun merkezi 22). */
.nx-tabbar, .nx-sidebar { --nx-tab-avatar: calc(36px * var(--nx-nesne-olcek)); }
.nx-tabbar__item--avatar .nx-tabbar__gosterge,
.nx-sidebar__item--avatar .nx-sidebar__gosterge { block-size: var(--nx-tab-avatar); }
.nx-tabbar__item--avatar .nx-avatar,
.nx-sidebar__item--avatar .nx-avatar {
  inline-size: var(--nx-tab-avatar); block-size: var(--nx-tab-avatar);
}
/* ⛔ `display:none` DEĞİL — erişilebilir ad DOM'da kalmalı, ekran okuyucu
   sekmenin adını okuyabilmeli. `position:absolute` aynı zamanda öğeyi flex
   akışından çıkarır ⇒ `gap` da uygulanmaz, avatar tek başına ortalanır. */
.nx-tabbar__item--avatar .nx-tabbar__etiket,
.nx-sidebar__item--avatar .nx-sidebar__etiket {
  position: absolute; inline-size: 1px; block-size: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   BİLDİRİM NOKTASI — .nx-bildirim-nokta   (Efe kararı, 14 Ağu 2026)

   Efe: *"Bildirim geldiğinde, bildirimin ulaşılacağı sayfanın olduğu yerde
   (alt tab veya rail) o sayfa üzerinde notification DOT çıkacak. Rengi lime
   olacak. Belirgin ve ayırt edilebilir olurken kesinlikle dikkat çekmeli.
   Lime dolgu gelince yine ink olacak şekilde düşün."*

   NEDEN ÜST ÇUBUKTAN BURAYA TAŞINDI
   Zil sekiz ekranın üst çubuğundaydı. Efe (14 Ağu): bildirimler referans
   onayları ve başvurulardan geleceği için zil YALNIZ `profil`de kalır.
   ⚠️ Bunun bedeli vardı: zil tek ekrana inince okunmamış bildirim öteki
     ekranlardan görünmez olurdu. Bu nokta o bedeli kapatıyor — kullanıcı
     hangi ekranda olursa olsun, gezinme çubuğunda işareti görüyor.

   ⭐ DOLGU KURALININ AYNASI (CLAUDE.md §DOLGU KURALI): nokta lime'dır; ama
   AKTİF sekmenin arkasında zaten kayan lime dolgu var ⇒ lime nokta lime
   zeminde KAYBOLURDU. Aktifken nokta **ink**e döner. Aynalanan şey rengin
   kendisi değil, "dolgunun üstündeki her şey ink" kuralı.
   ⚠️ Glow da aynalanır: lime noktada dışa lime glow, ink noktada glow YOK
     (ink'in etrafına lime glow koymak onu dolgudan ayırmaz, kirletirdi).
   📌 Boy 10px ⇒ CLAUDE.md kademesi gereği `--nx-glow-sm` (2px). 16px altı
     öğede 8px glow lekeye dönüşürdü.
   ⛔ HALKA/KONTUR YOK — dolgu kuralının açık yasağı. Ayrım glow'dan gelir.
   ⚠️ Nokta `__gosterge`ye göre konumlanır, ÖĞEYE göre değil: öğe 72×68 ve
     köşesi avatardan uzak; işaret fotoğrafın köşesine oturmalı.
   ⛔ Nokta `aria-hidden` — anlamı erişilebilir ADA yazılır (kabuk.js), yoksa
     ekran okuyucu bir süs görür ve bilgiyi hiç almaz.
   ══════════════════════════════════════════════════════════════════════════ */
.nx-tabbar__gosterge,
.nx-sidebar__gosterge { position: relative; }

.nx-bildirim-nokta {
  position: absolute;
  inset-block-start: -2px; inset-inline-end: -2px;
  /* ⭐ BOY 10 → 14px, TAŞMA 2/5 — Efe kararı, 16 Ağu 2026 (A şıkkı).
     *"Notification dot biraz daha belirgin olmalı; büyütüp pilin dışına taşar
     hale getir, yaklaşık 5'te 2'si taşsa yeter."* + *"dışa taşan TAM DAİRE
     olmalı, pilin dışında da o daireyi görmemiz lazım."*
     ⇒ Taşma = boy × 2/5 = 5,6px. Kapların (`--hap` ve `.nx-tabbar`)
       `overflow: hidden`ı bu yüzden kaldırıldı — yoksa yarım daire kalıyordu.
     📌 Sunulan diğer kademeler: B 16px (6,4 taşma) · C 18px (7,2). Efe A'yı seçti. */
  inline-size: calc(14px * var(--nx-nesne-olcek));
  block-size:  calc(14px * var(--nx-nesne-olcek));
  inset-block-start: calc(-5.6px * var(--nx-nesne-olcek));
  inset-inline-end:  calc(-5.6px * var(--nx-nesne-olcek));
  border-radius: var(--nx-radius-full);
  /* ⭐ TURUNCU — Efe, 16 Ağu: *"yeşil gizli kalıyor."* Gerekçe ve renk kaynağı
     `tokens.css` §BİLDİRİM RENGİ. Glow da turuncu, yoksa lime bir hale kalırdı. */
  background: var(--nx-bildirim);
  box-shadow: var(--nx-bildirim-glow);
  pointer-events: none;   /* sekmenin kendi dokunmasını çalmaz */
}
/* ⭐ ÇANIN ÜSTÜNDE DE NOKTA — Efe, 16 Ağu: *"dot varsa bildirim ÇANında da dot
   olmalı."* Zil bir `.nx-icon-btn`; nokta onun sağ üst köşesine oturur.
   ⚠️ Düğmenin `position: relative` olması ŞART, yoksa nokta sayfaya göre
     konumlanır. `.nx-icon-btn` tabanında yok, burada veriliyor. */
.nx-icon-btn:has(> .nx-bildirim-nokta) { position: relative; }
/* ⚠️ ZİLDE NOKTA İKONUN KÖŞESİNE OTURUR, DÜĞMENİNKİNE DEĞİL — canlıda görüldü:
   düğme 44px dokunma hedefi, ikon 24px ve ortada; noktayı düğme köşesine
   koyunca çandan ~10px UZAKTA, havada duruyordu.
   ⇒ Ofset ikonun kenarından hesaplanır: (44 − 24) / 2 = 10px içeri, sonra
     taşma payı kadar dışarı. Sayı değil FORMÜL yazılıyor ki dokunma hedefi ya
     da ikon merdiveni değişirse nokta kendiliğinden takip etsin. */
.nx-icon-btn > .nx-bildirim-nokta {
  /* ⭐ ZİLDE NOKTA ÇANIN ÜSTÜNE BİNER — Efe, 16 Ağu 2026: *"dot çanın üzerine
     gelsin biraz, ve ikonun ana dairesini bozmasın, böylece kebab ile aralığı
     doğru kalsın."*
     ⇒ İKİ KISIT AYNI ANDA:
       ① Nokta ikonun köşesine BİNER (2px dışarı, 12px içeri) — havada durmaz.
       ② Nokta düğmenin 44px'lik dairesinin İÇİNDE kalır ⇒ düğmenin kutusu
          büyümez, kebab ile aralık DEĞİŞMEZ. Ofset ≥ 0 olduğu sürece bu şart
          kendiliğinden sağlanır: (44−24)/2 − 2 = 8px ≥ 0. ✅
     ⚠️ Alt tab'daki nokta bu kuraldan ETKİLENMEZ — orada nokta hapın DIŞINA
       taşmalı (Efe'nin "tam daire görünsün" kararı) ve seçici `.nx-icon-btn >`
       olduğu için sekmelere hiç uğramıyor.
     📌 SAYI DEĞİL FORMÜL: dokunma hedefi ya da ikon merdiveni değişirse nokta
       kendiliğinden takip eder. */
  inset-block-start: calc((var(--nx-tap-min) - var(--nx-ikon-md)) / 2
                          - 2px * var(--nx-nesne-olcek));
  inset-inline-end:  calc((var(--nx-tap-min) - var(--nx-ikon-md)) / 2
                          - 2px * var(--nx-nesne-olcek));
}
/* ⭐ ÇAN ÇALAR — Efe: *"bildirim varsa dot animasyonu sürekli oynasın, yani çan
   çalıyor olsun."* Animasyonun kendisi ikon setinde ZATEN VAR
   (`ikon-animasyon.css`: `.i-bell.play .bell { animation: ring 3s infinite }`);
   burada yalnız tetikleniyor — yeni bir animasyon yazılmadı.
   🔶 WCAG 2.2.2 (5 sn'den uzun hareket durdurulabilir olmalı) ile gerilim var.
     Efe kararı, 16 Ağu: *"prefers-reduced-motion açıksa dursun."* ⇒ Kullanıcının
     sistem tercihi duraklatma yolu; animasyon o tercihte tamamen susuyor. */
@media (prefers-reduced-motion: reduce) {
  .nx-icon-btn:has(> .nx-bildirim-nokta) .i-bell .bell { animation: none !important; }
}
/* ⛔ AKTİF SEKME İSTİSNASI KALDIRILDI — Efe, 16 Ağu 2026.
   Burada *"arkada lime dolgu var ⇒ nokta ink'e döner"* yazıyordu; dolgu
   kuralının aynası. Efe: *"her temada aynı turuncu olsun o DOT."*
   ⇒ Nokta artık HER durumda turuncu: iki temada da, aktif sekmede de.
   📌 Gerekçe tutarlı: kural *"dolgunun üstündeki yazı/ikon ink"* der ve amacı
     okunabilirliktir. Bildirim noktası ne yazı ne ikon — tek işi FARK EDİLMEK,
     ve lime dolgunun üstünde ink bir nokta da lime bir nokta da kayboluyordu.
     Turuncu ikisinden de ayrışıyor. */

/* ==========================================================================
   TABLO
   Mobilde yatay kaydırılır (bkz. mobile.css) — sıkıştırılıp okunmaz yapılmaz.
   ========================================================================== */
.nx-table { width: 100%; border-collapse: collapse; font-size: var(--nx-fs-body-sm); }
.nx-table th, .nx-table td {
  text-align: left; padding: var(--nx-space-md);
  border-bottom: 1px solid var(--nx-border-soft);
}
.nx-table th { color: var(--nx-muted); font-weight: var(--nx-fw-semibold);
               font-size: var(--nx-fs-caption);
               border-bottom-color: var(--nx-border); }
@media (hover: hover) and (pointer: fine) {
  .nx-table tbody tr:hover { background: var(--nx-surface-2); }
}
.nx-table__empty { padding: var(--nx-space-2xl); text-align: center;
                   color: var(--nx-muted); }
/* Kaydırma kabı — mobilde devreye girer, masaüstünde etkisizdir */
.nx-table-sarmal { width: 100%; }

/* ==========================================================================
   İLERLEME ÇUBUĞU
   ========================================================================== */
.nx-progress {
  height: 8px; border-radius: var(--nx-radius-full);
  background: var(--nx-surface-3); overflow: hidden;
}
/* `width` geçişi BİLİNÇLİ (genel kural "layout değil transform animasyonla"
   der; burası istisna): ilerleme dolgusu kavram olarak GENİŞLİKTİR.
   `transform: scaleX` ile yapılırsa uçlardaki yuvarlak köşe yatay eziliyor ve
   çubuk bozuk görünüyor. Sayfada bir-iki adet olduğu için layout maliyeti yok. */
.nx-progress__bar {
  height: 100%; border-radius: inherit;
  background: var(--nx-dolgu);       /* DOLGU KURALI: iki temada da lime */
  /* Şerit 8px → sm kademe (2px). ⚠️ `-ic` (inset) varyantı ŞART: ata kap
     `.nx-progress` `overflow:hidden` taşıyor (yukarı bkz.) ve dışa glow orada
     KARE görünür. Aynı tuzak `.nx-match`'te de vardı, o da inset'e çevrilmişti. */
  box-shadow: var(--nx-glow-sm-ic);
  transition: width var(--nx-dur-slow) var(--nx-ease);
}
/* Quest ilerlemesi: kademeli. Kademe sınırları, dolgunun ÜSTÜNE zemin renginde
   ince çentikler basılarak gösterilir — böylece hem dolan kısımda hem boş
   kısımda aynı kademeler görünür ve "kaç adım kaldı" okunabilir olur.
   Kademe sayısı `--nx-quest-kademe` ile ayarlanır (varsayılan 5). */
.nx-progress--quest {
  height: 12px;
  --nx-quest-kademe: 5;
  position: relative;
}
.nx-progress--quest::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to right,
    transparent 0,
    transparent calc(100% / var(--nx-quest-kademe) - 2px),
    var(--nx-surface) calc(100% / var(--nx-quest-kademe) - 2px),
    var(--nx-surface) calc(100% / var(--nx-quest-kademe))
  );
}

/* ==========================================================================
   BAĞLANTI — .nx-link   (Efe kararı, 31 Tem 2026)
   "Yazıların link olduğunu belirtecek şekilde daha farklı fontta altı çizili
   olmaları gerekiyor."

   ⚠️ "FARKLI FONT" = FARKLI AĞIRLIK, ikinci bir aile DEĞİL. Marka tek font
   zorunlu kılıyor (Raleway, "ASLA sapma" — CLAUDE.md); ikinci bir aile eklemek
   marka ihlali olurdu. Ayrım bu yüzden AĞIRLIK + ALTI ÇİZİLİ ile kuruluyor:
     · gövde metni  regular (400)
     · bağlantı     semibold (600) + altı çizili

   ⚠️ RENK KULLANILMAZ. Klasik "mavi link" burada yok, çünkü:
     · E1 semantik renk kuralı: metin asla renkli olmaz, renk ikon/kenarda yaşar
     · lime açık/kırık-beyaz zeminde metin rengi olamaz (marka kuralı)
   Yani bağlantının işareti rengi değil BİÇİMİ. Renk körlüğünde de çalışır.

   Altı çizgi metne yapışmaz (`text-underline-offset`) ve tarayıcı varsayılanından
   biraz kalındır — küçük puntoda kaybolmasın diye. Hover'da çizgi tam kontrasta
   çıkar, yani hareket rengi değil YOĞUNLUĞU değiştirir.
   ========================================================================== */
.nx-link {
  /* ⚠️ `display` ZORUNLU (Efe, 4 Ağu): satır-içi (non-replaced inline) öğeye
     `transform` UYGULANMAZ. Ölçek sözleşmesine girebilmesi için kutu üretmesi
     gerekiyor. `inline-block` seçildi çünkü satır akışında kalır ve baseline
     hizasını korur. ⚠️ Bedeli: bağlantı artık satır ortasından SARMAZ —
     paragraf içi uzun bağlantılarda tek parça kalır. Mevcut kullanımların
     hepsi tekil/gezinme bağlantısı, prose içi değil (ölçüldü: profil.html 2). */
  display: inline-block;
  color: inherit;
  font-weight: var(--nx-fw-semibold);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-color: var(--nx-border-field);
  /* ⚠️ `transform` BURAYA eklenmek ZORUNDA — `tokens.css`'e yazmak İŞE YARAMAZ:
     bu bildirim `tokens.css`ten SONRA yüklenir ve shorthand olarak onu ezer,
     ölçek animasyonsuz zıplar. (tokens.css:622-628'de adlandırılmış tuzağın
     4. vakası: .nx-icon-btn · .nx-chip · doğrulama rozeti · .nx-link.) */
  transition: text-decoration-color var(--nx-dur-base) var(--nx-ease),
              transform var(--nx-dur-fast) var(--nx-ease);
  will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
  .nx-link:hover { text-decoration-color: currentColor;
                   transform: scale(var(--nx-scale-hover)); }
}
.nx-link:active { transform: scale(var(--nx-scale-active)); }
.nx-link:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 2px;
  border-radius: var(--nx-radius-xs);
}
/* Dış bağlantı: ad yanında küçük ok. İkon METNİN parçası değil, ayrı bir
   işaret — ekran okuyucu için `aria-hidden`, anlam `rel`/başlıkta. */
.nx-link--dis::after {
  content: "↗"; margin-left: 3px; font-weight: var(--nx-fw-regular);
  text-decoration: none; display: inline-block;
}

/* ==========================================================================
   UYARI KUTUSU (.nx-alert) — "E1" ANATOMİSİ
   Renkli ikon + EŞİT 1px renkli kenarlık + soluk tint zemin + NÖTR METİN.
   Kalın sol aksan çubuğu KULLANILMAZ (klişe olarak elendi, Efe kararı).
   Metin asla semantik renkte olmaz — bkz. tokens.css "E1 kuralı".
   ========================================================================== */
.nx-alert {
  display: flex; align-items: flex-start; gap: var(--nx-space-sm);
  padding: var(--nx-space-md);
  border: 1px solid var(--nx-border);
  border-radius: var(--nx-radius-md);
  background: var(--nx-surface-2);
  color: var(--nx-text);
}
.nx-alert .nx-icon { flex: none; }
.nx-alert__govde { display: flex; flex-direction: column; gap: var(--nx-space-xs);
                   min-width: 0; }
.nx-alert__baslik { font-size: var(--nx-fs-label); font-weight: var(--nx-fw-bold);
                    color: var(--nx-text); }
/* Açıklama metni `--nx-muted` — renk değil, HİYERARŞİ farkı. Hâlâ nötr. */
.nx-alert__metin  { font-size: var(--nx-fs-body-sm); color: var(--nx-muted); }

.nx-alert--danger  { border-color: var(--nx-danger);  background: var(--nx-danger-tint); }
.nx-alert--warning { border-color: var(--nx-warning); background: var(--nx-warning-tint); }
.nx-alert--success { border-color: var(--nx-success); background: var(--nx-success-tint); }
.nx-alert--danger  .nx-icon { color: var(--nx-danger); }
.nx-alert--warning .nx-icon { color: var(--nx-warning); }
.nx-alert--success .nx-icon { color: var(--nx-success); }

/* ==========================================================================
   MODAL (masaüstü) — mobilde mobile.css bunu ALT SAYFA'ya çevirir
   ========================================================================== */
.nx-modal {
  position: fixed; inset: 0; z-index: var(--nx-z-modal);
  display: flex; align-items: center; justify-content: center;
  padding: var(--nx-space-lg);
}
.nx-modal[hidden] { display: none; }
.nx-modal__scrim { position: absolute; inset: 0; background: var(--nx-scrim);
  /* ⭐ ÖRTÜ PANELLE BİRLİKTE GİRER (Tur C taban-10, L-115 A — 2 Eki 2026): pencere
     paneliyle (nx-modal-in) aynı süre ve eğri. Önceden örtü ilk karede tam
     koyulukta beliriyordu, panel ise yavaşça geliyordu. Çıkış (.is-kapaniyor,
     nx-perde-cik) aynen; telefondaki çift aşağıdaki @media (max-width: 599px)'te. */
  animation: nx-perde-gir var(--nx-dur-base) var(--nx-ease); }
/* YÜZEN YÜZEY KURALI (21 Tem 2026, T4 ölçümü):
   Toast ve modal paneli sayfa içi bir kart değildir; altlarında rastgele
   içerik/perde var ve DOLGULARI yeterli ayrım vermiyor. Ölçüm:
     · toast dolgusu / sayfa          = 1.5:1
     · modal dolgusu / perde (koyu)   = 1.07:1  ← paletten çıkmadan düzelmiyor
   Yani bu iki yüzeyi TANIMLAYAN öğe dolgu değil KENARDIR → WCAG 1.4.11
   gereği ≥3:1 (`--nx-border-float`). Sayfa içi yüzeyler (kart) `--nx-border`
   ile kalır; onlarda ayrımı zaten dolgu yapıyor. */
.nx-modal__panel {
  position: relative;
  width: min(560px, 100%);
  max-height: calc(var(--nx-ekran-y) * .85); overflow-y: auto;   /* ölçeğe duyarlı */
  /* Klavye odağı alanı kaydırma kenarına yaslamasın: dışa kaçık odak halkası kenarda kırpılıyordu (Tur E,
     ASTRA şart 5 — üni kurum modalı 1280: alt 3,7 px). Emsal `.nx-sheet__govde` (aynı değer). */
  scroll-padding-block: var(--nx-space-lg);
  background: var(--nx-surface-2);
  border: 1px solid var(--nx-border-float);
  border-radius: var(--nx-radius-xl);
  padding: var(--nx-space-lg);
  display: flex; flex-direction: column; gap: var(--nx-space-md);
  animation: nx-modal-in var(--nx-dur-base) var(--nx-ease);
}
@keyframes nx-modal-in { from { opacity: 0; transform: translateY(8px); }
                         to   { opacity: 1; transform: none; } }
.nx-modal__handle { display: none; }   /* yalnız mobil alt sayfada görünür */

/* ==========================================================================
   ÇEKMECE / ALT SAYFA — `.nx-sheet`  (JS eşi: kabuk.js → nxSheet)
   Sisteme alındı: 6 Ağu 2026 · Notes/DEVIR-kesfet-alt-sayfalar §nxSheet turu

   NE İŞE YARAR
   Her genişlikte ALTTAN gelen, sürükleyip kapatılabilen, aşağı kaydırıldıkça
   bir kez büyüyen modal katman. Keşfet'in alt sayfalarının filtre · sayfa boyu ·
   başvuru · kebap · yorumlar çekmecelerinin hepsi bu.

   ⚠️ NEDEN `.nx-modal` DEĞİL — ikisi AYRI bileşendir, biri ötekinin varyantı değil:
     · `.nx-modal` masaüstünde ORTADA yüzen kutudur, alt sayfaya yalnız mobilde
       dönüşür (mobile.css). `.nx-sheet` her genişlikte alt sayfadır (İLKE ① —
       öncelik native app; masaüstü o arayüzü aynen alır).
     · `.nx-modal` yüksekliği içeriktendir (`max-height: 85%`). `.nx-sheet`in
       ÖLÇÜLMÜŞ bir tavanı var (aşağıda `is-tam`) ve kısmi hâlden ona büyür.
     · `.nx-modal`da sürükleyip kapatma yok.
   `.nx-modal`ı bu ihtiyaca göre esnetmek üç TESLİM EDİLMİŞ ekranı (adaylar ·
   profil · kimlik) etkilerdi. Bu yüzden yanına yeni bileşen olarak kondu.

   ⚠️ ERİŞİLEBİLİRLİK SÖZLEŞMESİ JS TARAFINDA (kabuk.js → nxSheet):
   odak · `inert` · Esc · Tab tuzağı · dönüş odağı. Bu dosya yalnız GÖRÜNÜŞ.
   Sözleşmenin tamamı: kesfet_alt_TASARIM_SPEC.md §11.1.
   ========================================================================== */
.nx-sheet {
  position: fixed; inset: 0; z-index: var(--nx-z-modal);
  display: flex; align-items: flex-end; justify-content: center;
}
.nx-sheet[hidden] { display: none; }
.nx-sheet__perde { position: absolute; inset: 0; background: var(--nx-scrim);
  /* L-115 A (Tur C taban-10, 2 Eki 2026): örtü çekmece paneliyle (nx-sheet-gir)
     aynı süre ve eğriyle girer; çıkış .is-kapaniyor kuralında aynen. */
  animation: nx-perde-gir var(--nx-dur-sheet) var(--nx-ease-out); }
.nx-sheet__panel {
  position: relative;
  /* 430px = öğrenci içerik sütunu (tokens.css §TARAF İSTİSNASI). Çekmece
     `fixed` olduğu için sütunu miras alamaz; aynı ölçüyü kendisi tutar. */
  width: min(430px, 100%);
  /* Kısmi hâl: ekranın %62'si. `--nx-ekran-y` ölçeğe duyarlı (tokens.css). */
  height: calc(var(--nx-ekran-y) * .62);
  display: flex; flex-direction: column;
  background: var(--nx-surface-2);
  border: 1px solid var(--nx-border-float);   /* yüzen yüzey → kenar ≥3:1 */
  border-bottom: 0;
  border-radius: var(--nx-radius-xl) var(--nx-radius-xl) 0 0;
  /* ⚠️ BİLİNÇLİ LAYOUT ANİMASYONU — `transform` bunu VEREMEZ.
     Sistemde emsali var ve aynı gerekçeyle yazılmış: `.nx-sidebar` genişlik
     geçişi (yukarıda — "içeriğin yeniden akması İSTENEN etkidir").
     Transform çözümü ŞU YÜZDEN ÇALIŞMIYOR: paneli tam boy yapıp aşağı ötelersek
     alt eylem çubuğu (`.nx-sheet__alt`) panelin dibinde, yani görünür alanın
     ALTINDA kalır — "N sonucu göster" düğmesi kısmi hâlde hiç görünmez.
     Yükseklik geçişi çubuğu görünür kenarda tutuyor.
     Sayfada TEK öğe, sürekli değil tek jestte BİR KEZ çalışır; kaydırma
     sırasında layout animasyonu yasağı (spec §13) ihlal edilmiyor — o yasak
     akıştaki kartlar içindir. */
  transition: height var(--nx-dur-sheet) var(--nx-ease-out);
  animation: nx-sheet-gir var(--nx-dur-sheet) var(--nx-ease-out);
  overflow: hidden;
}
/* Panel açılışta odak alır (§11.1-3) ama görsel halka istemiyoruz — halka
   kullanıcının GÖTÜRÜLDÜĞÜ yeri değil, seçtiği yeri gösterir. */
.nx-sheet__panel:focus { outline: none; }

/* ═══ PROGRAMATİK ODAĞIN HALKASI (taban turu #1, 21 Eyl 2026) ═══════════════
   ⛔ DONDURULMUŞ TABANA YAZILDI — Efe'nin AI Loop brief'iyle verdiği TEK TOPLU
      TABAN İZNİ kapsamında; tören `catal-kapisi` açılıp kapatılarak yürütüldü.

   SORUN, ÖLÇÜLDÜ: JS ile odak verilen hedeflerin yazılı `:focus-visible`
   kuralı yoktu ⇒ Chromium kendi `outline: auto`sunu çiziyordu ve o halka
   **SAF BEYAZ piksel** üretiyor (21 Eyl final denetiminde `ayarlar.html`
   render'larında 846 birebir `#FFFFFF` sayıldı). Marka kuralı saf beyazı
   yasaklıyor.
   🪤 GÖZLE BULUNAMAZ: gerçek fareyle `:focus-visible` hiç eşleşmiyor
      (`outlineStyle: "none"` ölçüldü) ⇒ kusur yalnız KLAVYE yolunda görünür,
      yani odak göstergesine en çok ihtiyacı olan kullanıcıda.

   İKİ HEDEF, İKİSİ DE ÖLÇÜMLE BULUNDU:
   ① `.nx-sheet__baslik` — `nxSheet` açılışta odağı BAŞLIĞA verir (bu dosyanın
      §11.1-3 kuralı, `kabuk.js:1003`).
   ② `.nx-modal__panel` — öğrenci EKRANLARI modal açarken odağı PANELİN
      KENDİSİNE veriyor (`gorevlerim.html:1046`; `kimlik.html`/`profil.html` de
      aynı kabı tutuyor) ve o modallerin odaklanan bir başlığı YOK.
      ⇒ Yukarıdaki `.nx-sheet__panel:focus { outline: none }` kuralı buraya
        KOPYALANMADI ve bu bilinçli: orada odak BAŞLIĞA gidiyor, gösterge orada;
        burada odak kabın kendisine düşüyor ve halka kalkarsa kullanıcı `Tab`a
        basana kadar hiçbir gösterge görmez (WCAG 2.4.7 · F78 yönü).
        Codex bağımsız olarak aynı ayrımı yaptı; **Efe A'yı seçti: halka olsun.**
      ⛔ Çatallara (`-uni`/`-sirket`) bu ikinci kural YAZILMADI: ölçüldü, orada
        ne kabuk ne ekran paneli odaklıyor — kural ölü CSS olurdu.

   KAÇIKLIK **DIŞA** — Efe seçimi (artifact'te üç hâl yan yana görüldü).
   Ölçüldü, kırpılma yok: çekmece başlığı ile tutamaç çizgisi arası **8px**
   (`--nx-space-sm`), halkanın üst kenarı panelin **içinde** kalıyor; modal
   başlıklarında kabın dolgusu **24px**, pay **25px**.
   ⭐ Yeni değer üretilmedi: `2px solid var(--nx-accent-on)` bu dosyadaki 21
      odak kuralının tamamının yazdığı tek reçete.
   ⛔ JS DEĞİŞMEDİ: odak tuzağı (`Tab`/`Shift+Tab` sırası, `inert` yönetimi,
      odak iadesi) aynen duruyor; `kabuk.js`e tek satır yazılmadı. */
.nx-sheet__baslik:focus-visible,
.nx-modal__panel:focus-visible {
  outline: 2px solid var(--nx-accent-on); outline-offset: 2px;
}

/* ⭐ İÇERİK BOYUNDA ÇEKMECE (Efe kararı, 6 Ağu 2026)
   Efe: "Filtre çekmece boyu iyi ama soldaki liste sayısını belirlemede boy
   gereksiz uzun, boş alan olunca çekmece sadece yazının başladığı yerden başlasın."
   ⇒ Kısa içerikli çekmeceler (sayfa boyu seçici · kebap menüsü) %62'lik sabit
     yüksekliği kullanmaz; boyu içerikten alır. Tavan yine var ki uzun bir içerik
     ekranı taşırmasın. Bu varyant BÜYÜMEZ de — büyüyecek içeriği yok.
   Ölçüldü: %62 → %32. */
.nx-sheet--otomatik .nx-sheet__panel {
  height: auto;
  max-height: calc(var(--nx-ekran-y) * .85);
}
.nx-sheet--otomatik .nx-sheet__govde { overflow-y: auto; }

/* ⭐ TAVAN: TAM EKRAN DEĞİL — ÜST ÇUBUĞUN 2/3'Ü AÇIKTA KALIR (Efe, 6 Ağu 2026)
   Efe: "çekmece tam ekran olmayacak, tam ekrana kadar çıkacak ama yukarıdaki
   geri dönün bulunduğu başlık çubuğunun 3'te 2'si hâlâ görünür olmalı, koyulaşarak."

   ⇒ Panel yüksekliği = ekran − (üst çubuğun 2/3'ü). Çubuğun yalnız alt 1/3'ü
     örtülüyor; geri düğmesinin bulunduğu şerit açıkta. Ölçüldü: 775px panel,
     37px şerit, çubuğun %66'sı görünür.
   ⚠️ `--nx-ust-cubuk` çentiği de içeriyor, yani şerit gerçek cihazda da doğru
     oranda kalıyor — literal px yazılmadı.
   ⭐ "Koyulaşarak" ayrıca kural GEREKTİRMİYOR: perde `inset: 0` ve çekmece
     `--nx-z-modal` (300) katmanında; üst çubuk `--nx-z-sticky` (200) olduğu için
     perde onun üstüne düşüyor ve şerit kendiliğinden koyulaşıyor.
   ⚠️ Üst köşe yarıçapı KORUNUR: panel ekranın tepesine yapışmadığı için
     köşeleri düzleştirmek yanlış olurdu — "sayfa" gibi değil "çekmece" gibi durmalı. */
.nx-sheet.is-tam .nx-sheet__panel {
  height: calc(var(--nx-ekran-y) - (var(--nx-ust-cubuk) * 2 / 3));
}

.nx-sheet.is-kapaniyor .nx-sheet__panel {
  animation: nx-sheet-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }
.nx-sheet.is-kapaniyor .nx-sheet__perde {
  animation: nx-perde-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }

@media (prefers-reduced-motion: reduce) {
  /* ⚠️ `!important` ZORUNLU: tokens.css'te reduced-motion altında evrensel bir
     `animation-duration: .01ms !important` var; onsuz bu dal ÖLÜ KOD olur.
     Aynı ders `.nx-modal`da da yazılı (aşağı bkz.). */
  .nx-sheet__panel { animation: none; transition: none; }
  .nx-sheet.is-kapaniyor .nx-sheet__panel,
  .nx-sheet.is-kapaniyor .nx-sheet__perde {
    animation: nx-sadece-soluk 120ms linear forwards !important;
    animation-duration: 120ms !important;
  }
}

/* Tutamaç + başlık: sürükleme bölgesi. Jest YALNIZ buradan başlar — gövdeden
   başlasaydı listeyi kaydırmak çekmeceyi kapatırdı (profil.html kalıbı). */
.nx-sheet__tut {
  flex: 0 0 auto; padding: var(--nx-space-sm) var(--nx-space-lg) 0;
  cursor: grab; touch-action: none;
}
.nx-sheet__cizgi {
  width: 36px; height: 4px; margin: 0 auto var(--nx-space-sm);
  background: var(--nx-border-strong); border-radius: var(--nx-radius-full);
}
.nx-sheet__baslik {
  margin: 0 0 var(--nx-space-sm); font-size: var(--nx-fs-h3);
  font-weight: var(--nx-fw-bold); text-align: center;
}
/* Kaydırılan gövde — sayfa gövdesi DEĞİL, çekmecenin kendisi kayar (§11.1-8). */
.nx-sheet__govde {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 0 var(--nx-space-lg) var(--nx-space-md);
  scroll-padding-block: var(--nx-space-lg);
  overscroll-behavior: contain;
}
/* Alt eylem çubuğu YOKSA ana ekran çubuğu payını gövde taşır — yoksa listenin
   son satırı telefonun home bar'ının altında kalır.
   🔴 Bu, dört kopyadan YALNIZ BİRİNDE (`sirket_sayfasi` kebap menüsü) vardı;
   aynı durumdaki öteki üç çekmece (sayfa boyu seçicileri · kebap) paysızdı ve
   masaüstünde `env()` sıfır döndüğü için fark GÖRÜNMÜYORDU. Çentikli cihazda
   ortaya çıkacaktı. `:last-child` doğru koşul: `nxSheet` alt çubuğu istenmediğinde
   DOM'dan siliyor, yani gövde gerçekten son çocuk oluyor. */
.nx-sheet__govde:last-child {
  padding-bottom: calc(var(--nx-space-md) + env(safe-area-inset-bottom, 0px));
}
/* Alt eylem çubuğu — çekmecenin İÇİNDE sabit, sayfanınkiyle karışmaz. */
.nx-sheet__alt {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: var(--nx-space-sm);
  padding: var(--nx-space-md) var(--nx-space-lg);
  padding-bottom: calc(var(--nx-space-md) + env(safe-area-inset-bottom, 0px));
  background: var(--nx-surface-2);
  border-top: 1px solid var(--nx-border);
}
/* Alt çubuğun düzeni İKİ kalıbı birden taşır:
   · İki buton (filtre: "Temizle" + "N sonucu göster") → asıl eylem yeri kaplar,
     ikincil buton kendi boyunda kalır.
   · Tek buton (başvuru: "Gönder" · onay: "Evet, geri çek") → tam genişlik.
   ⚠️ `:only-child` şart: tek butonlu çekmecelerde eylem `--danger` olabiliyor
   (geri çekme onayı) ve yalnız `--accent`e kural yazmak onu dar bırakırdı. */
.nx-sheet__alt .nx-btn--accent { flex: 1; justify-content: center; }
.nx-sheet__alt > .nx-btn:only-child { flex: 1; justify-content: center; }

/* ==========================================================================
   AKORDEON — .nx-akordeon   (sisteme alındı 6 Ağu 2026)

   YERİNDE açılan panel. ⚠️ ÇEKMECE DEĞİL: çekmece (`.nx-sheet`) sayfanın
   ÜSTÜNE biner ve arkayı kilitler; akordeon sayfanın İÇİNDE büyür, arka plan
   erişilebilir kalır. Kullanıcı "bir yere gitmiyor", sadece daha fazlasını
   görüyor — bu yüzden modal değil.

   NEREDE KULLANILIYOR (üç yer — bu yüzden sisteme çıktı):
     · eğitim/sertifika sayfası → müfredat üniteleri
     · şirket sayfası → "N açık ilan" (Efe, 6 Ağu: kart açılır olsun)
     · ilan sayfası → şirket bilgileri (Efe, 6 Ağu: kart içinde açılsın)

   ⭐ NATIVE `<details>/<summary>` ÜSTÜNE KURULU — kendi buton+bölge kalıbımız
   DEĞİL. Klavye desteği, ekran okuyucu duyurusu ve tarayıcı-içi "sayfada bul"
   davranışı hazır geliyor; üçünü de elle yazmak spec §11.6-1'in
   *"sonradan değiştirilmesi en pahalı kararlar"* listesindeki tam da o hata.
   ⚠️ React Native'de `<details>` YOKTUR — CTO tarafında kendi açılır bileşeni
   yazılacak ve klavye/ekran okuyucu sözleşmesi ELLE kurulacak (CTO deltasında).

   🔴 **ESKİ NOT YANLIŞTI — DÜZELTİLDİ (Efe, 7 Ağu 2026).**
   Burada *"açılma animasyonu YOK, bilerek — spec §13 yasağı"* yazıyordu.
   Efe: *"'ilanda açık değil' açarken animasyon yok, zınk diye açılıyor; yavaşça
   açılıp app animasyonlarına bütünlük sağlaması lazım."* **Haklı, ve bu bir
   tercih değil KURAL İHLALİYDİ:**
     · spec §13 *"**kaydırma sırasında** layout animasyonu yok"* diyor — akordeon
       dokunmayla açılıyor, o yasağın kapsamında değil. Notu yazarken §13'ü
       olduğundan geniş okumuşum.
     · `karar-animasyon-sistemi` ise TERSİNİ **şart koşuyor**: *"Açılan menü ·
       **akordeon** · çekmece · modal · toast: animasyonla açılır VE animasyonla
       kapanır."* (250–300ms giriş `ease-out` · ~180ms çıkış `ease-in`)
     · `karar-faz1-normatif-kapilar` §M2 kapsamı zaten bölmüş: sayfa
       YERLEŞİMİNDE layout animasyonu yasak, **tek bir bileşenin kendi
       yüksekliği** serbest.
   ⇒ Akordeon oluşturulduğu günden beri (6 Ağu) bu kuralı ihlal ediyormuş;
     dört kullanım yerinin dördü birden bu düzeltmeyi alıyor.

   ⭐ TEKNİK — `karar-animasyon-sistemi`'nin ŞART KOŞTUĞU yol:
   `grid-template-rows: 0fr → 1fr` (dış kap grid, iç kap `overflow:hidden`).
   ⛔ `max-height` hilesi KULLANILMAZ (içerik kısaysa zamanlama bozulur).
   ⛔ `interpolate-size`/`calc-size()` KULLANILMAZ (Safari/Firefox'ta yok, ayrıca
     bu iskelet React Native'e çevrilecek).
   ⚠️⚠️ `display: grid` tarayıcının kapalı `<details>` içeriğini gizlemesini
     **EZER** — içerik kapalıyken de DOM'da ve odaklanabilir kalır.
     ⇒ Erişilebilirlik **`inert`** ile korunur (kapalı gövdeye klavye ve ekran
       okuyucu giremez). Bu, karar dosyasının kendi uyarısı.
   ⚠️ İç sarmalayıcı (`__ic`) `kabuk.js` tarafından **bir kez** kuruluyor;
     kurulmadan önce eski davranış aynen sürer (JS düşerse akordeon çalışır,
     yalnız animasyonsuz kalır — bozulmaz).
   ========================================================================== */
/* ⭐ ÇERÇEVE YOK — sadece kart zemini + yüzen gölge (Efe kararı, 12 Eyl 2026).
   Efe: *"Kartlarda çerçeve olmayacak, sadece kart arkaplanı olacak."*
   ⛔ `0 0 0 1px` bir gölge DEĞİL: bulanıklık 0 + yayılım 1px ⇒ ekranda ÇİZGİ.
   Kartın kimliğini artık zemin tonu + yumuşak gölge taşıyor. Üniversite ve
   şirket çatallarında aynı reçete uygulandı; taban en son geldi.
   ⭐ ZEMİN DE DEĞİŞTİ (aynı karar): eskiden `--nx-surface-2` idi ve bu, aynı
      bileşenin İKİ FARKLI görünmesine yol açıyordu — `.nx-card.nx-akordeon`
      yazan ekranlarda (profil) `.nx-card` kuralı dosyada DAHA SONRA geldiği
      için hem zemini hem gölgeyi eziyordu. Yani ilan_sayfasi'ndaki akordeon
      halkalı + surface-2, profildeki halkasız + surface-kart çiziliyordu.
      Ölçüldü, tahmin değil. Efe: *"akordeonlar aynı olsun."*
   📌 Bu yüzden `--nx-surface-kart` seçildi: `.nx-card`ın zaten verdiği değer.
      Başka bir değer seçseydim iki akordeon yine ayrışırdı. */
.nx-akordeon {
  background: var(--nx-surface-kart);
  border-radius: var(--nx-radius-lg);
  box-shadow: var(--nx-yuzen);
  overflow: hidden;
}
.nx-akordeon + .nx-akordeon { margin-top: var(--nx-space-sm); }

.nx-akordeon__bas {
  display: flex; align-items: center; gap: var(--nx-space-md);
  min-height: var(--nx-tap-min);
  padding: var(--nx-space-md);
  cursor: pointer; list-style: none;
  font-size: var(--nx-fs-body-md); font-weight: var(--nx-fw-semibold);
  color: var(--nx-text);
}
/* Varsayılan açılır üçgeni iki motorda da kaldır — kendi okumuz var. */
.nx-akordeon__bas::-webkit-details-marker { display: none; }
.nx-akordeon__bas::marker { content: ""; }
@media (hover: hover) and (pointer: fine) {
  .nx-akordeon__bas:hover { background: var(--nx-surface-3); }
}
.nx-akordeon__bas:focus-visible { outline: 2px solid var(--nx-accent-on);
                                  outline-offset: -2px; }

.nx-akordeon__ad   { flex: 1; min-width: 0; }
/* Başlığın sağındaki ikincil bilgi (süre · sayı · konum). Ağırlık DÜŞÜK:
   başlıkla yarışmamalı, `regular` ve `--nx-muted`. */
.nx-akordeon__meta { flex: 0 0 auto; font-size: var(--nx-fs-caption);
                     font-weight: var(--nx-fw-regular); color: var(--nx-muted);
                     white-space: nowrap; }
/* ⭐ OK, GÖVDENİN SAATİNİ İZLER (taban turu #2, 22 Eyl 2026 — Efe: "A").
   ÖLÇÜLDÜ (canlı, `ogrenci/profil.html`, 2 akordeon): ok ile gövde AYRI saat ve
   AYRI eğri tutuyordu — ok `--nx-dur-fast` (150ms) + `--nx-ease` (.2,0,0,1),
   gövde ise 250ms `--nx-ease-out` / kapanışta 180ms `--nx-ease-in`:
     açılış : 150 ↔ 250 ms  ⇒ ok 100 ms ÖNCE biter, üstelik başka eğriyle
     kapanış: 150 ↔ 180 ms  ⇒ 30 ms fark + başka eğri
   Efe ürünü kullanırken gördü: *"profilde ve auradaki kariyer kimliğimdeki
   akordeonları açınca o chevronlar saçma sapan hareket ediyor."*
   ⇒ Tek jest, tek saat: ok artık gövdeyle AYNI token'ları kullanır.
   ⛔ Yeni değer üretilmedi: `--nx-dur-base` + `--nx-ease-out` zaten gövdenin
     açılış reçetesi. Kapanış dalı aşağıda, gövdenin `.is-kapaniyor` kuralının
     hemen ardında. */
.nx-akordeon__ok   { flex: 0 0 auto; display: inline-flex; color: var(--nx-muted);
                     transition: transform var(--nx-dur-base) var(--nx-ease-out); }
.nx-akordeon__ok .nx-icon { width: var(--nx-ikon-sm); height: var(--nx-ikon-sm); }
.nx-akordeon[open] .nx-akordeon__ok { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .nx-akordeon__ok { transition: none; } }
/* ⭐ DÖNÜŞLÜ OK DÜRTÜLMEZ (Tur C taban-10, L-117 — 2 Eki 2026): ok açılınca ya da
   kapanınca kabıyla 180° dönüyorsa oynatması O DÖNÜŞTÜR. Dokunuşta başlayan dürtme
   (ikon-animasyon.css «chev», pointerdown) tıklamada başlayan dönüşün üstüne binince
   bir dokunuşun iki ayrı hızlı cevabı oluyordu (O3): ok önce 2 px aşağı iniyor,
   dönüşle yana savruluyor, liste aşağı açılırken 3 px YUKARI çıkıyordu (üni seçim
   listesinde ölçüldü). `.nx-dropdown__btn` okun kendisini döndürür; dürtme o dönüşü
   oynatma boyunca eziyordu (karar-ikon-yon-katmani). `.play` zamanlayıcıyla kalkar
   (ikon.js) — animationend beklenmez. */
:is(.nx-akordeon__ok, .nx-dropdown__btn) .nx-ico.play :is(svg, svg *) { animation-name: none; }

/* JS henüz sarmalayıcıyı kurmadıysa ESKİ davranış: dolgu kapta, animasyon yok.
   (Böylece JS düşse bile akordeon çalışır — yalnız "zınk" açılır.) */
.nx-akordeon__govde { padding: 0 var(--nx-space-md) var(--nx-space-md); }

/* ── HAZIRLANMIŞ HÂL: yükseklik animasyonu (grid motoru) ────────────────── */
.nx-akordeon__govde[data-nx-hazir] {
  display: grid;               /* ⚠️ tarayıcının gizlemesini EZER → `inert` şart */
  /* 🔴 `0fr` DEĞİL, `minmax(0, 0fr)` — canlı ölçümle yakalandı.
     `0fr` aslında `minmax(auto, 0fr)` demek; otomatik-minimum iç kabın
     DOLGUSUNU (16px) taşımaya devam ediyor ve kapalı akordeon 0 yerine
     **16px** yer kaplıyordu. `min-height: 0` bunu çözmez: min-height içerik
     kutusuna uygulanır, dolgu onun üstüne eklenir. */
  grid-template-rows: minmax(0, 0fr);
  /* 🔴 Sütun da `minmax(0, 1fr)` (Efe, L-77 A · 29 Eyl 2026): örtük sütun `auto`
     en uzun tek satırlık çocuğun min-içeriğine açılıyor, iç kabın `overflow:clip`i
     sağı kesiyordu — öğrenci Profil › Referanslar'da ⋮ menüsü ve e-posta 320–361px'te
     görünmez, menü ERİŞİLEMEZ idi. Sığan içerikte genişlik değişmez. */
  grid-template-columns: minmax(0, 1fr);
  padding: 0;                  /* dolgu iç kaba taşındı, yoksa kapalıyken boşluk kalırdı */
  transition: grid-template-rows var(--nx-dur-base) var(--nx-ease-out);
}
.nx-akordeon[open] .nx-akordeon__govde[data-nx-hazir] {
  grid-template-rows: minmax(0, 1fr);
}
/* Kapanış: DAHA HIZLI ve ease-in — "giriş yavaşlayarak yerleşir, çıkış
   hızlanarak kaybolur" (spec §13 · karar-animasyon-sistemi tablosu).
   ⚠️ `[open]` kuralıyla aynı özgüllükte (0,2,0) — SONRA geldiği için kazanır. */
.nx-akordeon.is-kapaniyor .nx-akordeon__govde[data-nx-hazir] {
  grid-template-rows: minmax(0, 0fr);
  transition-duration: var(--nx-dur-exit);
  transition-timing-function: var(--nx-ease-in);
}
/* Ok da kapanışta gövdenin saatini izler (taban turu #2).
   ⚠️ Üstteki kuralla BİRLEŞTİRİLMEDİ: o kural `grid-template-rows` da yazıyor
     ve bu ok'a (inline-flex bir span) ait bir özellik değil. Aynı iki token,
     bitişik iki kural — değişirlerse birlikte görünürler. */
/* 🔴 `transform: rotate(0deg)` ŞART — Efe ürününde yakaladı, İZ ÖLÇÜMÜ
     doğruladı (22 Eyl): *"chevron önce dönüyor, sonra ışınlanıp yerine
     geliyor."* Sebep: kapanışta JS `is-kapaniyor` verir ama `open` özniteliği
     gövdenin `transitionend`ine kadar DURUR (`kabuk.js` akordeon motoru)
     ⇒ `[open]` kuralı hâlâ 180°'yi dayatıyor, ok kapanış boyunca BEKLİYOR;
     gövde bitince `open` kalkıyor ve ok ancak O ZAMAN dönmeye başlıyor.
     ÖLÇÜLDÜ (`hareket-izi.mjs`, `ogrenci/profil.html`):
       gövde  15,9 ms → 165,6 ms
       ok    198,5 ms → 398,8 ms      başlangıç farkı **182,6 ms**
   ⛔ Yalnız `transition-duration` yazmak BU KUSURU GÖRMEZ: süre doğruydu,
     hedef açı değişmiyordu ⇒ kural ölüydü. Hedefi burada veriyoruz.
   ⚠️ Özgüllük: bu seçici (3 sınıf) ile `[open]` seçicisi (2 sınıf + 1
     öznitelik) EŞİT ağırlıkta; bu kural dosyada SONRA geldiği için kazanır.
     Yeri değişirse kusur sessizce geri gelir. */
.nx-akordeon.is-kapaniyor .nx-akordeon__ok {
  transform: rotate(0deg);
  transition-duration: var(--nx-dur-exit);
  transition-timing-function: var(--nx-ease-in);
}
/* İç kap KIRPAR — `min-height: 0` olmadan grid öğesi içeriğinden küçülmez.
   🔴 `overflow: hidden` DEĞİL `clip` (Efe bildirdi, 7 Ağu: *"şirket detayından
     ilanları göstertince iç içe geçme var"* — içerik yukarı kaymış görünüyordu).
     `hidden` bir KAYDIRMA KABI yaratır: kap görünmez şekilde kaydırılabilir ve
     içine düşen odak (ör. akordeon açılırken karta gelen odak, `#acikIlanlar`
     çıpası) tarayıcıya kabı kaydırtır — içerik yukarı kayar, üstü kırpılmış
     görünür. `clip` kaydırma kabı YARATMAZ, o yüzden kaydırılamaz.
   ⚠️ `overflow-clip-margin: 0` şart: `clip`in varsayılan taşma payı yok ama
     açıkça yazmak, kutu gölgesi/odak halkası taşmalarını da kesin kılıyor. */
/* 🔴 ÜST PAY ŞART (Efe, 7 Ağu: *"kartın üst çizgisi açılan kısmın altında
     kalıyor; kartları 1-2px aşağı kaydırsan çözülür"* — haklıydı).
   Sebep: içerik kırpma sınırının TAM ÜSTÜNDE başlıyordu. Kartın halkası
   (`box-shadow: 0 0 0 1px`) border-box'ın DIŞINA çizilir; sınır kartın üst
   kenarındayken o 1px kırpılıyor ve kart üstsüz görünüyordu.
   ⛔ Literal 1-2px yazılmadı: uzam merdiveninin en küçük adımı `--nx-space-xs`
     (4px) kullanıldı — halkaya + yüzen gölgenin üst kenarına pay bırakıyor ve
     `--nx-nesne-olcek` knob'una bağlı kalıyor (CLAUDE.md §Ölçeklenebilirlik). */
.nx-akordeon__ic {
  min-height: 0;
  overflow: clip; overflow-clip-margin: 0;
  /* ⭐ 16 Ağu 2026 — YATAY DOLGU 16 → 4 (Efe, sayfa sayfa tur):
     *"bu şirket ilanlarını gösteren kartlarda neden hâlâ arka plan içinde durma
     sağ sol mesafeleri diğerleriyle aynı değil de fazla içeride..."*
     🔬 ÖLÇÜLDÜ: aynı `.nx-ilan-kart`, `ilan_sayfasi`nda ekran kenarından **4px**,
       `sirket_sayfasi`nın akordeonu içinde **20px**'te başlıyordu. Fark tam olarak
       buradaki `--nx-space-md` (16) idi — akordeon D37/D49'un özyinelemeli
       kenar sözleşmesine hiç alınmamıştı.
     ⇒ Yatay ölçü artık kademe token'ından: her iç içe geçme **4px** ilerletir
       (sayfa 4 → akordeon 4 ⇒ kart 8), tıpkı panel→kart kademesi gibi.
     ⛔ DİKEY DEĞİŞMEDİ (üst `xs`, alt `md`): D37 kararı açıkça YATAYDI ve
       akordeonun dikey nefesi içerik ritmine ait. */
  padding: var(--nx-space-xs) var(--nx-kart-dolgu-yatay) var(--nx-space-md);
}
@media (prefers-reduced-motion: reduce) {
  .nx-akordeon__govde[data-nx-hazir] { transition: none; }
}

/* ⭐ SAYI ÖNDE varyantı — "12 Açık ilan" gibi, rakamın kendisi başlık olduğunda.
   Şirket sayfasındaki çıpa kartından geldi; oradaki görünüş korunuyor. */
.nx-akordeon__sayi { flex: 0 0 auto;
                     font-size: var(--nx-fs-h3); font-weight: var(--nx-fw-bold);
                     font-variant-numeric: tabular-nums; }

/* ==========================================================================
   TOAST
   ========================================================================== */
/* ⭐ YIĞIN KABI (Efe, 7 Ağu 2026 — denetimde iki toast üst üste bindi).
   Eskiden her toast KENDİ `position: fixed`ini taşıyordu; iki toast aynı anda
   doğduğunda ikisi de aynı koordinata basılıyor ve metinler üst üste okunuyordu.
   ⇒ Konum artık KAPTA; toast'lar sıradan flex çocuğu.
   Efe'nin üç şartı: **üst üste binmez · en fazla 3 · kaydırarak kapatılır.**

   ⚠️ YAN KAZANÇ: `translateX(-50%)` ortalaması da kaba taşındı. Eskiden bu -50%
     toast'ın kendi `transform`unda duruyordu ve mobilde `transform: none` ile
     ezildiği için giriş/çıkış animasyonlarının İKİ AYRI kopyası yazılmak zorunda
     kalmıştı (mobile.css'in kendi notu: *"çıkışta -50% geri geliyor, toast aşağı
     gitmek yerine SOLA savruluyordu"*). Artık toast'ın `transform`u boşta ⇒ tek
     keyframe seti yetiyor VE sürükleme jesti o eksene serbestçe yazabiliyor.
   ⚠️ `pointer-events` kapta `none`: yığın ekranın altını kaplıyor, tıklamayı
     yutarsa altındaki tab bar ölür. Toast'ın kendisi `auto` — jest ona lazım. */
.nx-toast-yigin {
  position: fixed; left: 50%; bottom: var(--nx-space-lg);
  transform: translateX(-50%);
  z-index: var(--nx-z-toast);
  display: flex; flex-direction: column; align-items: center;
  gap: var(--nx-space-sm);
  width: max-content; max-width: min(92vw, 420px);
  pointer-events: none;
}
.nx-toast {
  display: flex; align-items: center; gap: var(--nx-space-sm);
  max-width: 100%;
  padding: var(--nx-space-md) var(--nx-space-lg);
  background: var(--nx-surface-3); color: var(--nx-text);
  /* Toast'ın kendi dolgusu sayfadan yalnız 1.5:1 ayrılıyor → yüzeyi TANIMLAYAN
     öğe kenardır, o yüzden ≥3:1 şartına tabi (WCAG 1.4.11). */
  border: 1px solid var(--nx-border-float);
  border-radius: var(--nx-radius-full);
  font-size: var(--nx-fs-body-sm); font-weight: var(--nx-fw-semibold);
  pointer-events: auto;
  /* Yatay jest BİZİM, dikey kaydırma sayfanın — `pan-y` tam bunu der.
     `none` yazılsaydı toast'ın üstünden sayfa kaydırılamazdı. */
  touch-action: pan-y;
  animation: nx-toast-in var(--nx-dur-base) var(--nx-ease);
}
/* ⚠️ Sınıf adları ASCII — Türkçe karakter (ı/ş/ğ) CSS'te geçerli olsa da
   JS/CSS/HTML üçlüsünde kodlama farkı sessiz eşleşmeme üretir.
   ⚠️ `grab` imleci SINIFA bağlı, `.nx-toast`a değil: eylemli toast'lar
   (ör. Adaylar'daki 15 sn'lik "Geri al") jesti kurmuyor — hepsine grab
   vermek yapmadığı bir şeyi vaat etmek olurdu. */
.nx-toast.is-suruklenebilir { cursor: grab; }
.nx-toast.is-surukleniyor   { cursor: grabbing; }
@keyframes nx-toast-in { from { opacity: 0; transform: translateY(12px); }
                         to   { opacity: 1; transform: none; } }
/* Kaydırarak kapatma: çıkış yatay ve JS'ten gelen inline `transform` ile sürülür,
   keyframe YOK — jestin bıraktığı yerden devam etmesi gerekiyor. */
.nx-toast.is-savruluyor {
  transition: transform var(--nx-dur-exit) var(--nx-ease-in),
              opacity   var(--nx-dur-exit) var(--nx-ease-in);
  opacity: 0;
}
/* Eşiğin ALTINDA bırakılınca toast yerine oturur — bu AYRI bir sınıf olmak
   zorunda. 🔴 Önce `is-savruluyor` "geçişi ödünç almak" için kullanılmıştı; o
   sınıf `opacity: 0` da taşıdığı için toast ~200 ms **kaybolup geri geliyordu**
   (final denetiminde yakalandı). Burada yalnız geçiş var, opaklık hedefi yok. */
.nx-toast.is-geri-oturuyor {
  transition: transform var(--nx-dur-exit) var(--nx-ease-out),
              opacity   var(--nx-dur-exit) var(--nx-ease-out);
}
/* Toast'ta da E1 geçerli: metin nötr, rengi yalnız ikon taşır.
   Başarı ikonu `--nx-success` kullanır (marka aksanı değil, semantik işaret) —
   `.nx-badge--success` ve `.nx-alert--success` ile aynı dil. */
.nx-toast--success .nx-icon { color: var(--nx-success); }
.nx-toast--error   .nx-icon { color: var(--nx-danger); }
/* L-148 B (Tur E · E4 Y2): ikonlu toast (`nxToast(mesaj, "basari" | "hata")`) — ikon + metin dizilimi
   `.nx-toast`un kendi flex'inden gelir; ayrı kural yok (aynı değerli kopya etkisizdi — Tur E kör denetçi). */

/* ==========================================================================
   ⚡ ÇIKIŞ ANİMASYONU — Efe kuralı, 25 Tem 2026 (TÜM APP)
   Notes/karar-animasyon-sistemi.md

   Sistemde yalnız GİRİŞ animasyonu vardı: perdeye/Esc'e basınca panel DOM'dan
   anında siliniyor, "pat" diye kayboluyordu. Sürüklemeyle kapatmada hareket
   görünüyordu (parmağı takip ettiği için) — tutarsızlık buradan doğuyordu.

   KURAL: giriş yavaşlayarak yerleşir, çıkış hızlanarak kaybolur ve girişten
   KISADIR (~2/3). Çıkışın yavaş olması "sistem takıldı" hissi verir.
   KULLANIM: kapatmadan önce `.is-kapaniyor` sınıfını ekle, `animationend`
   (ya da --nx-dur-exit kadar bekleme) sonrası DOM'dan kaldır/gizle.
   ========================================================================== */
.nx-modal.is-kapaniyor .nx-modal__panel {
  animation: nx-panel-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }
.nx-modal.is-kapaniyor .nx-modal__scrim {
  animation: nx-perde-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }
@keyframes nx-panel-cik { to { opacity: 0; transform: translateY(8px); } }
@keyframes nx-perde-cik { to { opacity: 0; } }

/* Alt sayfa giriş/çıkışı — aşağıdan gelir, aşağı gider.
   🔴 KEYFRAME'LER MEDYA SORGUSUNDAN ÇIKARILDI (6 Ağu 2026, nxSheet turu).
   Eskiden ikisi de `@media (max-width: 768px)` bloğunun İÇİNDEYDİ. `@keyframes`
   bir medya sorgusunun içindeyse sorgu eşleşmediğinde TANIMSIZDIR — ve tanımsız
   bir animasyon adı hata vermez, sessizce hiç oynamaz.
   Sonucu: `.nx-sheet` (alt sayfa kalıbı, her genişlikte alttan gelir) masaüstünde
   animasyonsuz "pat" diye beliriyordu. Öğrenci masaüstü 430px sütun olduğu için
   bu, telefonla birebir aynı görünmesi gereken düzendi.
   ⚠️ `.nx-modal`ın DAVRANIŞI DEĞİŞMEDİ: aşağıdaki kural bloğu medya sorgusunda
   kaldı, yani modal masaüstünde hâlâ `nx-modal-in` (soluk + 8px) ile giriyor.
   Dışarı çıkan yalnız keyframe TANIMLARI. */
@keyframes nx-sheet-gir { from { transform: translateY(100%); } to { transform: none; } }
@keyframes nx-sheet-cik { to { transform: translateY(100%); } }

/* Mobilde MODAL paneli de bir alt sayfaya dönüşür → aynı iki keyframe'i kullanır.
   ⚠️ Eşik 13 Ağu 2026'da 768 → 599'a indi (kabukla birlikte, D27). Yukarıdaki
   tarihsel notta geçen "768" KASITLI: o cümle bugünü değil geçmişi anlatıyor. */
@media (max-width: 599px) {
  .nx-modal__panel { animation: nx-sheet-gir var(--nx-dur-sheet) var(--nx-ease-out); }
  /* L-115 A (④ ölçümü, 2 Eki 2026): üstteki panel satırı ÖLÜ — telefonda panel mobile.css:175 `nx-sheet-in`
     (base + ease) oynuyor. Örtüye burada ayrı çift YAZILMAZ: masaüstü kuralı (base + ease) panelle aynı;
     sheet + ease-out örtü panelden 70 ms geç bitiyordu (getAnimations ile ölçüldü, üç taraf). */
  .nx-modal.is-kapaniyor .nx-modal__panel {
    animation: nx-sheet-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }
}

/* Toast da aynı kurala tabi: girdiği gibi çıkar.
   ⚠️ 7 Ağu: `translate(-50%, …)` kalktı — ortalama artık `.nx-toast-yigin`de,
   toast'ın kendi `transform`u boşta (jest onu kullanıyor). */
.nx-toast.is-kapaniyor {
  animation: nx-toast-cik var(--nx-dur-exit) var(--nx-ease-in) forwards; }
@keyframes nx-toast-cik { to { opacity: 0; transform: translateY(12px); } }

@media (prefers-reduced-motion: reduce) {
  .nx-modal__panel, .nx-toast { animation: none; }
  /* ⚠️ Hareket AZALIR ama durum değişimi GÖRÜNÜR kalır: animasyonu tamamen
     silmek "kapandı mı kapanmadı mı" belirsizliği yaratır. Kayma yerine kısa
     opaklık geçişi bırakılır (Notes/karar-animasyon-sistemi.md).

     ⚠️⚠️ `!important` ZORUNLU — süs değil (denetim bulgusu, 27 Tem 2026):
     `tokens.css`'te `prefers-reduced-motion` altında evrensel bir
     `*, *::before, *::after { animation-duration: .01ms !important }` kuralı var.
     `!important` özgüllükten bağımsız kazandığı için buradaki 120ms'lik kasıtlı
     geçiş sessizce ~0ms'ye eziliyordu — yani bu dal ÖLÜ KODDU ve tam olarak
     önlemek istediği belirsizliği geri getiriyordu. */
  .nx-modal.is-kapaniyor .nx-modal__panel,
  .nx-modal.is-kapaniyor .nx-modal__scrim,
  .nx-toast.is-kapaniyor {
    animation: nx-sadece-soluk 120ms linear forwards !important;
    animation-duration: 120ms !important;
  }
  @keyframes nx-sadece-soluk { to { opacity: 0; } }
}

/* ==========================================================================
   İSKELET + DURUM GEÇİŞİ (Tur E taban-12 · L-146 B · L-149 A — 3 Eki 2026)
   JS eşi: kabuk.js → nxIskelet · nxDurumDegistir · nxDurumKancasi
   ========================================================================== */
/* İSKELET — gerçek kartın klonu; parıltı YOK (kesfet.html «parıltısız» kararı).
   Beş ekran-yerel kopyanın (`.kf-iskelet` · `.tl-iskelet` ×4) tek kaynağı: kural gövdesi
   birebir aynı, çıktı değişmez. `[hidden]` telafisi kesfet'ten (kart sınıfı `display`
   yazıyorsa gizli iskelet yine görünürdü).
   ⚠️ ÖZGÜLLÜK (0,2,0) — süs değil: `.nx-card` bu bloktan SONRA (§KART YÜZEYİ) zemin + yüzen gölge
   yazıyor ve aynı (0,1,0)'da sırayla kazanıyordu; yerel kopyalar sayfanın `<style>`ında, yani en son
   yüklendiği için kazanıyordu (ölçüldü 3 Eki: iskelet hâli %0,67–80 fark → çift sınıfla %0). */
.nx-iskelet.nx-iskelet {
  background: var(--nx-surface-3);   /* kart tonunun bir kademe altı */
  box-shadow: none;                  /* halka yok: iskelet bir denetim öğesi değil */
  pointer-events: none;
}
.nx-iskelet[hidden] { display: none; }
.nx-iskelet > * { visibility: hidden; }
/* DURUM GEÇİŞİ (G2 — O5 «durum geçişinde ışınlanma yok»): eski hâl hızlanarak söner
   (toast çıkışının dili, §ÇIKIŞ ANİMASYONU), yeni hâl yavaşlayarak yerleşir (`.tl-yeni`
   girişinin dili). Sınıfları yalnız `nxDurumDegistir` yazar ve siler. */
.nx-durum-cik { opacity: 0; transition: opacity var(--nx-dur-exit) var(--nx-ease-in); }
.nx-durum-gir { animation: nx-durum-gir var(--nx-dur-base) var(--nx-ease-out) both; }
@keyframes nx-durum-gir { from { opacity: 0; transform: translateY(6px); }
                          to   { opacity: 1; transform: none; } }
@keyframes nx-durum-soluk { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  /* Az hareket: kayma yok, yalnız soluk — süre HAREKET SÖZLÜĞÜ'nden (`--nx-sahne-soluk`, 120 ms; O6:
     merdivene oturmayan değer kuralın içine gömülmez — Codex ASTRA, Tur E). `!important` tokens.css'in evrensel
     sıfırlamasını aşmak için — §ÇIKIŞ ANİMASYONU `nx-sadece-soluk` emsali. */
  .nx-durum-cik { transition: opacity var(--nx-sahne-soluk) linear !important; transition-duration: var(--nx-sahne-soluk) !important; }
  .nx-durum-gir { animation: nx-durum-soluk var(--nx-sahne-soluk) linear both !important; animation-duration: var(--nx-sahne-soluk) !important; }
}

/* ==========================================================================
   BOŞ DURUM (spec §3b: her listenin VARSAYILAN hali)
   ========================================================================== */
.nx-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--nx-space-sm); padding: var(--nx-space-2xl) var(--nx-space-lg);
  text-align: center; color: var(--nx-muted);
}
/* İkon %75 (Tur E L-152 C · E1 Y1): SOLUK DURUM tek tarifi (L-128 A «%75»), üç tarafta aynı.
   .6 açık temada 2,71:1 veriyordu (WCAG 1.4.11 eşiği 3:1; ikon metin değil). */
.nx-empty__icon  { color: var(--nx-muted); opacity: .75; }
.nx-empty__title { font-size: var(--nx-fs-h3); font-weight: var(--nx-fw-semibold);
                   color: var(--nx-text); }
/* Satır uzunluğu 42ch ile sınırlı — okunabilirlik üst sınırı */
.nx-empty__text  { max-width: 42ch; }

/* HATA BANDI (Tur E L-154 A · E3 Y1 ii) — ekran/bölüm yüklenemedi hâli: nötr `.nx-alert` (bilgi ikonu;
   ⛔ `--danger` yok — kullanıcının hatası değil) + «Tekrar dene» halka düğmesi; kap ROLSÜZ — duyuru
   ekranın önceden var olan canlı bölgesinden (C14, Codex SOL; ⛔ "alert" de değil: kesintili değil). Kaynak: tum_* `.tl-hata` + kesfet `.kf-hata` (iki ekran-yerel kopya
   → tek sınıf). Markup'ı kabuk `nxHataBandi(mesaj, tekrarEt)` üretir; yerleşim payı (margin) ekranın. */
.nx-hata-bandi { display: flex; flex-direction: column; align-items: flex-start; gap: var(--nx-space-md); }
.nx-hata-bandi[hidden] { display: none; }
/* İkon iletinin ortasında — toast ve alan hatasıyla aynı; flex-start yazı %125/%200'de ikonu 2–10 px yukarıda bırakıyordu (Tur E tam ölçüm ⑤). */
.nx-hata-bandi .nx-alert { width: 100%; align-items: center; }
/* Kart ızgarasında bant veri bölgesinin yerine geçer, bütün satırı kaplar (tum_* kalıbı); tek hücrede «Tekrar dene» %125'te taşıyordu (keşfet). */
.nx-kart-izgara > .nx-hata-bandi { grid-column: 1 / -1; }

/* Silik yer-tutucu: kullanıcının dolduracağı alanların boş hali.
   OPACITY KULLANILMAZ (T4 ölçümü, 21 Tem 2026): `.75` opaklıkta açık temada
   kontrast 3.49:1'e düşüyordu — AA altı. Yer-tutucu okunması GEREKEN bir
   metindir (kullanıcıya ne yazacağını söyler), dekoratif değil.
   "Silik" hissi rengi kısmadan İTALİK ile veriliyor; renk --nx-muted'de kalır
   ve her iki temada ≥4.5:1 ölçülür. */
.nx-placeholder {
  color: var(--nx-muted); font-style: italic;
  user-select: none;
}

/* ==========================================================================
   EŞLEŞME ROZETİ — .nx-match   (Efe kararı, 23 Tem 2026)
   Yüzdelik eşleşme değeri. Renk skalası ve gerekçesi tokens.css'te.
   Yapı: KOYU ADA (ink pill) + kademe rengiyle yazı + aynı renkten ince halka.
   Ada iki temada da ink'tir → aynı yüzde her temada AYNI renkte görünür.
   Kullanım: <span class="nx-match" data-match="7">%85</span>
   (data-match 1-8 arası kademe; sayı HER ZAMAN yazılır — renk tek taşıyıcı değil)
   ========================================================================== */
.nx-match {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 52px; padding: 3px var(--nx-space-sm);
  background: var(--nx-match-ada);
  border-radius: var(--nx-radius-full);
  font-size: var(--nx-fs-caption); font-weight: var(--nx-fw-bold);
  font-variant-numeric: tabular-nums;   /* sayılar sütun sütun hizalansın */
  line-height: 1.4; white-space: nowrap;
  /* ══ DOLGU KURALI — skala rengiyle (Efe, 31 Tem 2026) ══
     Pill artık ink ada DEĞİL: dolgu kademenin KENDİ RENGİ, yazı ink. Yani
     lime dolgu + ink yazı kalıbının birebir aynısı, lime yerine skala rengi.
     Ölçüldü: 8 kademenin hepsinde ink yazı kontrastı ≥5.02:1 (eşik 4.5) —
     en zayıfı EPIC mor #B14BFF 5.02, en güçlüsü #D7E62F 14.38.
     Kademe 7 (80-90) zaten lime; orada kural birebir standart hâline düşüyor.

     GLOW: iki temada da İÇE ink. Sebep iki katlı —
     (1) dolgu her iki temada da PARLAK, yani "açık tema dolgusu" gibi davranır;
         parlak dolguda kenarı tanımlayan şey içeri koyulaşan glow'dur.
         Aynı renkte inset glow görünmez olurdu (dolguyla aynı renk).
     (2) Dışa glow zaten yapılamaz: pill'in kırpan iki atası var —
         `.ad-sutun__govde` (overflow:auto) ve `.ad-pano` (overflow:auto hidden),
         canlı ölçüldü; dışa glow orada KARE görünür. Bu, kuralın "kırpılan kap
         içinde hep inset" maddesi (Efe'nin EPIC'te bulduğu tuzağın aynısı). */
  background: var(--nx-match-1);
  color: var(--nx-ink);
  box-shadow: inset 0 0 var(--nx-glow-r-md) rgba(10, 10, 10, .55);
}
.nx-match[data-match="1"] { background: var(--nx-match-1); }
.nx-match[data-match="2"] { background: var(--nx-match-2); }
.nx-match[data-match="3"] { background: var(--nx-match-3); }
.nx-match[data-match="4"] { background: var(--nx-match-4); }
.nx-match[data-match="5"] { background: var(--nx-match-5); }
.nx-match[data-match="6"] { background: var(--nx-match-6); }
.nx-match[data-match="7"] { background: var(--nx-match-7); }
/* EPIC: en üst kademe ayrıca hafif bir parıltı alır — "nadir" hissi.
   Ada koyu olduğu için parıltı açık temada da marka kuralını bozmaz. */
/* EPIC parıltı İÇ glow (inset) olur — pill radius'unu izler, ata kapların
   (kanban gövdesi/liste hücresi overflow'u) tarafından KARE olarak kırpılmaz
   (Efe bulgusu: dış glow kare görünüyordu). */
/* EPIC: en üst kademe daha güçlü bir iç parıltı alır — "nadir" hissi
   dolgunun morundan değil, kenarın daha derin koyulaşmasından gelir. */
.nx-match[data-match="8"] { background: var(--nx-match-8);
                            box-shadow: inset 0 0 var(--nx-glow-r-lg) rgba(10, 10, 10, .62); }
/* Büyük boy — detay/çekmece başlıklarında */
.nx-match--lg { min-width: 64px; padding: 5px var(--nx-space-md);
                font-size: var(--nx-fs-body-sm); }

/* ==========================================================================
   FİLTRE ÇİPİ — .nx-chip   (Efe onayı, 23 Tem 2026)
   Toggle davranışlı süzgeç. Butondan AYRIDIR: buton bir EYLEM yapar, çip bir
   GÖRÜNÜMÜ daraltır. Seçili hâli aksan adasıdır (ayna kuralı token'lardan).
   ========================================================================== */
.nx-chip {
  display: inline-flex; align-items: center; gap: 5px;
  /* Ölçü küçültüldü (Efe, 23 Tem): 36→32px, yazı sm→caption, dolgu daraldı.
     İKON boyutu DEĞİŞMEDİ (16px) — Efe: "ikon boyutları aynı kalabilir". */
  min-height: var(--nx-kontrol-cip); padding: 4px 12px;
  background: var(--nx-surface-2); color: var(--nx-text);
  border: 1px solid var(--nx-border-field);   /* denetim öğesi → ≥3:1 */
  border-radius: var(--nx-radius-full);
  font-family: var(--nx-font); font-size: var(--nx-fs-caption);
  font-weight: var(--nx-fw-semibold); white-space: nowrap; cursor: pointer;
  /* `transform` şart — tokens.css'teki ölçek sözleşmesi bu dosyadan ÖNCE
     yükleniyor, buradaki transition onu ezer (bkz. tokens.css §YAYILIM). */
  transition: background var(--nx-dur-fast) var(--nx-ease),
              color var(--nx-dur-fast) var(--nx-ease),
              border-color var(--nx-dur-fast) var(--nx-ease),
              transform var(--nx-dur-fast) var(--nx-ease);
}
.nx-chip .nx-icon { width: var(--nx-ikon-xs); height: var(--nx-ikon-xs); }
.nx-chip:hover { background: var(--nx-surface-3); }
.nx-chip:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: 2px; }
/* DOLGU KURALI: seçili çip 32px → md kademe (4px). Kenarlık dolguyla aynı
   renk olduğu için ayrı bir kontur değil, dolgunun kenarı. */
.nx-chip[aria-pressed="true"] {
  background: var(--nx-dolgu); color: var(--nx-dolgu-yazi);
  border-color: var(--nx-dolgu); font-weight: var(--nx-fw-on-accent);
  box-shadow: var(--nx-glow-md);
}
/* Hover: açıkta dolgu koyulaşır, koyuda glow güçlenir (butonla aynı sözleşme) */
.nx-chip[aria-pressed="true"]:hover { background: var(--nx-dolgu-hover);
                                      border-color: var(--nx-dolgu-hover);
                                      box-shadow: var(--nx-glow-md-hover); }
.nx-chip__sayac { font-weight: var(--nx-fw-regular); opacity: .72; }
/* Mobilde dokunma hedefi (--nx-tap-min) */
/* ⭐ GENİŞLİK DEĞİL CİHAZ YETENEĞİ (Efe onayı, 13 Ağu 2026).
   Eskiden `@media (max-width: 768px)` idi. Kabuk eşiği 600'e inerken bu kural
   599'a çekilseydi 600-768 bandındaki TABLETLER — ki dokunmatiktirler — 44px
   hedeflerini kaybederdi; Görev 5'in kendi a11y kapısının 1. maddesiyle çelişirdi.
   Bu kural "ekran dar" değil "parmakla kullanılıyor" kuralıdır (D13: cihaz
   yeteneği → capability sorgusu). Sistem bu kalıbı zaten kullanıyor:
   `(hover: hover) and (pointer: fine)` bu dosyada ~18 yerde geçiyor. */
@media (any-pointer: coarse) { .nx-chip { min-height: var(--nx-tap-min); } }

/* ==========================================================================
   AÇMA/KAPAMA ANAHTARI — .nx-anahtar   (Efe kararı, 16 Ağu 2026)

   NEDEN YENİ: sistemde AÇIK/KAPALI bir denetim YOKTU. `.nx-segmented` seçenek
   arasından seçtirir (Sistem/Açık/Koyu), `.nx-chip` bir görünümü daraltır,
   `.nx-check` forma gönderilir. Ayarların "şu davranış açık mı" sorusunun
   karşılığı hiçbirinde yoktu; ayarlar ekranı bu boşluğu görünür kıldı.

   ⭐ DOLGU KURALI: açık hâlde ray LİME, tokmak ink. Aynalanan yalnız glow yönü
     (koyu dışa · açık içe) — kademe `md`, ray 28px yüksekliğinde (16-40 bandı).
   ⭐ RENK TEK TAŞIYICI DEĞİL: tokmağın KONUMU (sol/sağ) durumu renkten bağımsız
     anlatır; `role="switch"` + `aria-checked` ekran okuyucuya söyler.
   ⚠️ `role="switch"` KULLANILIYOR (checkbox değil): anahtar anında etki eder,
     forma gönderilmez — `.nx-segmented`in aynı gerekçesi.
   ⚠️ Dokunma hedefi 44px: ray 28px ama düğmenin kendisi `--nx-tap-min` taşır;
     görsel küçük, hedef tam (`karar-gosterge-ogeleri-aciklanabilir` kalıbı).
   ========================================================================== */
.nx-anahtar {
  flex: 0 0 auto; position: relative;
  display: inline-grid; place-items: center;
  min-inline-size: var(--nx-tap-min); min-block-size: var(--nx-tap-min);
  padding: 0; border: 0; background: none; cursor: pointer;
}
/* 🔴 ÖLÇEKLENEBİLİRLİK İHLALİ DÜZELTİLDİ (final denetim İ-2): literal px
   yazılmıştı ve `--nx-nesne-olcek` knob'u çevrildiğinde HİÇ tepki vermiyordu
   (ölçüldü: knob 1→0.5, ikon 18→9 küçüldü, anahtar 48×28 kaldı). CTO native
   için knob'u çevirince satır geometrisi bozulurdu.
   📌 48px zaten `--nx-kontrol-md` ile birebir aynıydı — merdiven hazır duruyordu.
   ⛔ `--nx-tap-min` BAĞLANMAZ: erişilebilirlik tabanı, estetik ölçek değil. */
.nx-anahtar__ray {
  display: block; inline-size: var(--nx-kontrol-md);
  block-size: calc(28px * var(--nx-nesne-olcek));
  border-radius: var(--nx-radius-full);
  background: var(--nx-surface-3);
  border: 1px solid var(--nx-border-field);
  transition: background var(--nx-dur-fast) var(--nx-ease);
}
.nx-anahtar__tokmak {
  position: absolute;
  inset-inline-start: calc(50% - (var(--nx-kontrol-md) / 2) + (3px * var(--nx-nesne-olcek)));
  inline-size: calc(22px * var(--nx-nesne-olcek));
  block-size: calc(22px * var(--nx-nesne-olcek)); border-radius: var(--nx-radius-full);
  background: var(--nx-muted);
  transition: transform var(--nx-dur-fast) var(--nx-ease),
              background var(--nx-dur-fast) var(--nx-ease);
}
.nx-anahtar[aria-checked="true"] .nx-anahtar__ray {
  background: var(--nx-dolgu); border-color: transparent;
  box-shadow: var(--nx-glow-md);
}
.nx-anahtar[aria-checked="true"] .nx-anahtar__tokmak {
  transform: translateX(calc(20px * var(--nx-nesne-olcek))); background: var(--nx-dolgu-yazi);
}
.nx-anahtar:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: 2px;
                            border-radius: var(--nx-radius-full); }
@media (prefers-reduced-motion: reduce) {
  .nx-anahtar__ray, .nx-anahtar__tokmak { transition: none; }
}

/* ==========================================================================
   GÖRÜNÜM ANAHTARI — .nx-segmented   (Efe onayı, 23 Tem 2026)
   Birbirini dışlayan GÖRÜNÜM seçimi (eylem değil — Apple HIG). ARIA olarak
   radiogroup DEĞİL: role="group" + aria-pressed (Primer kalıbı), çünkü seçim
   anında uygulanır, forma gönderilmez.
   ========================================================================== */
/* ⭐ BÜYÜK YAZIDA SIĞMAYINCA (Efe, L-74 B · 29 Eyl 2026): seçenekler alt satıra
   iner, her satır kabı tam doldurur (aşağıda `button { flex: 1 1 auto }`).
   Kap önceden tek satırda kalıyor, %200 yazıda sayfayı 93px'e dek yana
   kaydırıyordu. Etiket tek satırda kalır — "buton asla iki satır olmaz"
   (yukarıda); gösterge `nxKayanGosterge` ile iki boyutta kayar (`--nx-seg-y`).
   ⚠️ İSTİSNA (kör denetçi 2 A1, 29 Eyl 2026 — KABUL'de yazılı soru): TEK BAŞINA
   satıra sığmayan seçenekte (üni `ogrencilerim` "Uygulamada aktif 16", 320 px ×
   %125 ve üstü) önce sayaç alta iner, etiket yalnız o da sığmazsa sarar
   (aşağıda `button { flex-wrap: wrap }`). Böyle olmasa sayaç düğmeden 24,5 px
   taşıyordu; kısaltma ise büyütülen metni keser (WCAG 1.4.4, F69). */
.nx-segmented {
  display: inline-flex; flex: none; flex-wrap: wrap; max-width: 100%;
  padding: 3px; gap: 2px;
  background: var(--nx-surface-2);
  border: 1px solid var(--nx-border-field);
  /* Köşe göstergeyle EŞMERKEZ (kör denetçi, 29 Eyl 2026): gösterge yarıçapı (düğme
     boyunun yarısı — `--nx-seg-h`, `nxKayanGosterge` ölçüp yazıyor) + kap dolgusu (3)
     + kenarlık (1). Tek satırda bu kabın yarı yüksekliğidir, yani `--nx-radius-full`in
     kısıldığı değerin aynısı (farede düğme 34 px ⇒ 21, dokunmatikte 38 px ⇒ 23). İki
     satırda `--nx-radius-full` kabın yarısına kısılıyor (78 px ⇒ 39), seçili dolgu
     yayın 5,7 px dışına taşıyordu.
     ⛔ Düğme boyu SABİT yazılmaz: dokunmatik kuralı ve ekranların kendi düğme boyları
     onu değiştiriyor. Yedek 34px yalnız JS ölçmeden önceki ilk kare için. */
  border-radius: calc(var(--nx-seg-h, 34px) / 2 + 3px + 1px);
  position: relative;              /* kayan göstergenin kapsayıcı bloğu */
}

/* ⭐⭐ KAYAN GÖSTERGE — Efe kuralı, 19 Ağu 2026.
   Efe: *"seçilenin dolgusu alttab ve rail'da olduğu gibi kayarak geçsin; tüm
   sistemde böyle kaydırmalıya benzeyecek öğeler kayarak geçmeli bundan sonra."*

   ⇒ Dolgu artık AKTİF DÜĞMENİN ÜSTÜNDE değil, kabın kendi sözde-öğesinde.
     Seçim değişince kutu ZIPLAMIYOR, kayıyor.
   ⛔ Alt tab bar'daki mekanizmanın İKİNCİ BİR KOPYASI YAZILMADI (D42):
     ikisi de `kabuk.js` → `nxKayanGosterge()` yardımcısını kullanıyor. Kopya
     olsaydı `nxSheet`in dört kopyasının başına geleni beklerdik.
   ⛔ ANİMASYON YALNIZ `transform` + `width` + `height` — `left` geçişi layout
     animasyonu olurdu (spec §13). Sözde-öğe `position:absolute`, hiçbir şeyi
     itmiyor. `height` yalnız düğme boyları farklıyken değişir (A1, yukarıda).
   📌 Konum ve boy JS ölçümünden gelir (`--nx-seg-x/-y/-w/-h`, aşağıda): gösterge
     aktif düğmenin kutusuna birebir oturur, kap dolgusu ne olursa olsun. */
.nx-segmented::before {
  content: "";
  position: absolute; z-index: 0; pointer-events: none;
  /* ⛔ SABİT `3px` YAZILMAZ (19 Ağu, ölçümde yakalandı): `adaylar.html`
     kabın dolgusunu 2px'e düşürüyor (`.ad-ust .nx-segmented`), sabit yazılsaydı
     gösterge orada her kenardan 1px kısa kalırdı ve kimse fark etmezdi.
     ⇒ Dört değeri de JS ÖLÇÜP yazıyor; kap dolgusu ne olursa olsun gösterge
       aktif düğmenin kutusuna birebir oturur. */
  top: 0; left: 0;
  width: var(--nx-seg-w, 0px);
  height: var(--nx-seg-h, 0px);
  transform: translate(var(--nx-seg-x, 0px), var(--nx-seg-y, 0px));
  background: var(--nx-dolgu);
  border-radius: var(--nx-radius-full);
  /* Kademe `md` — segment 34px ve 3px'lik bir kabın içinde; `lg` (8px) dışa
     glow kardeş segmente ve kabın dışına taşıyordu (aşağıdaki eski not). */
  box-shadow: var(--nx-glow-md);
}
/* İlk boyamada KAYMA YOK: gösterge yerine oturduktan sonra geçiş açılır,
   yoksa sayfa her açılışta gösterge soldan içeri süzülerek gelirdi. */
.nx-segmented.is-gosterge-hazir::before {
  transition: transform var(--nx-dur-base) var(--nx-ease),
              width     var(--nx-dur-base) var(--nx-ease),
              height    var(--nx-dur-base) var(--nx-ease);
}
/* Kap köşesi göstergenin boyundan türüyor (`--nx-seg-h`, yukarıda) ⇒ boyu farklı
   düğmeler arasında (A1: sayacı alta inen seçenek) göstergeyle AYNI süre ve eğriyle
   döner, her karede eşmerkez kalır. Geçişsiz olsaydı köşe tek karede sıçrar,
   gösterge geçiş boyunca yayın dışına taşardı (①a-c'nin kapattığı kusur). */
.nx-segmented.is-gosterge-hazir { transition: border-radius var(--nx-dur-base) var(--nx-ease); }
/* Düğmeler göstergenin ÜSTÜNDE kalmalı, yoksa dolgu yazıyı yutar. */
.nx-segmented button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  flex-wrap: wrap;                 /* A1 İSTİSNASI (yukarıda): sığmayınca önce sayaç alta iner */
  flex: 1 1 auto;                 /* tek satırda fark yok (kap içeriğe göre); satır kırılınca satırı doldurur */
  min-width: 40px; min-height: 34px; padding: 0 var(--nx-space-sm);
  position: relative; z-index: 1;
  background: none; border: 0; border-radius: var(--nx-radius-full);
  color: var(--nx-muted); font-family: var(--nx-font);
  font-size: var(--nx-fs-body-sm); font-weight: var(--nx-fw-semibold); cursor: pointer;
  transition: background var(--nx-dur-fast) var(--nx-ease),
              color var(--nx-dur-fast) var(--nx-ease);
}
.nx-segmented button .nx-icon { width: var(--nx-ikon-sm); height: var(--nx-ikon-sm); }
.nx-segmented button:hover { color: var(--nx-text); }
.nx-segmented button:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: 2px; }
/* DOLGU KURALI: aktif segment 34px → md kademe (4px).
   ⚠️ md ŞART, lg DEĞİL: segment 3px padding'li bir kabın içinde (yukarı bkz.);
   8px dışa glow kardeş segmente ve kabın dışına taşıyordu (ölçüldü). */
/* 🔴 DOLGU BURADAN ALINDI (19 Ağu 2026) — artık `.nx-segmented::before` taşıyor.
   Düğmenin kendi zemini boyansaydı gösterge iki kez çizilir, kayma sırasında
   eski segment dolgusu bir kare boyunca yerinde kalırdı (iki dolgu görünürdü).
   Burada YALNIZ yazı/ikon rengi kalır — dolgunun üstündeki metin ink olur. */
.nx-segmented button[aria-pressed="true"] { color: var(--nx-dolgu-yazi); }
/* Renk geçişi göstergeyle EŞZAMANLI (alt tab bar'daki aynı gerekçe): gösterge
   `--nx-dur-base` ile kayarken renk `--nx-dur-fast` ile değişseydi yazı, dolgu
   daha oraya varmadan ink'e dönerdi. */
.nx-segmented button,
.nx-segmented button .nx-icon { transition: color var(--nx-dur-base) var(--nx-ease); }
@media (prefers-reduced-motion: reduce) {
  .nx-segmented.is-gosterge-hazir,
  .nx-segmented.is-gosterge-hazir::before { transition: none; }
}
/* Dokunma kuralı — genişliğe değil cihaz yeteneğine bağlı (bkz. `.nx-chip` notu). */
@media (any-pointer: coarse) { .nx-segmented button { min-height: 38px; } }

/* ==========================================================================
   KEBAP MENÜSÜ — .nx-menu   (Efe kararı, 16 Ağu 2026)
   Motoru: kabuk.js → `nxKebapMenu()`. Kap `nxSheet` (alt çekmece).

   NEDEN SİSTEMDE (D42 + nxSheet'in kendi dersi): bu 13 satır `ilan_sayfasi`
   (`.il-menu`), `egitim_sayfasi` (`.eg-menu`) ve `sirket_sayfasi` (`.sr-menu`)
   içinde ÜÇ KEZ birebir kopyalanmıştı. Kopyalar bugüne kadar ayrışmamıştı ama
   projede bunun ayrıştığı iki emsal var (nxSheet'in dört kopyası ·
   nxUyumRozeti'nin bir ekranda hiç olmayan kademe tablosu).

   ⛔ NEDEN `.nx-dropdown` DEĞİL: o bir SEÇİM denetimi (btn + değer + liste),
     seçili bir durumu temsil eder. Kebap menüsü EYLEM listesidir, durumu yok.
     İkisini birleştirmek "seçili menü öğesi" gibi anlamsız bir hâl doğururdu.
   ⛔ NEDEN AÇILIR KUTU (popover) DEĞİL: hedef native app (İLKE ①). Sağ üst
     köşeye tutturulmuş bir popover telefonda başparmağın en uzak noktasında
     açılır; alt çekmece parmağın altına gelir. Ayrıca konumlandırma mantığı
     D65'te baloncuktan zaten SÖKÜLMÜŞTÜ — geri getirmek o kararı ters çevirirdi.
   ========================================================================== */
.nx-menu { display: flex; flex-direction: column; gap: var(--nx-space-xs); }
.nx-menu__oge {
  display: flex; align-items: center; gap: var(--nx-space-md);
  min-height: var(--nx-tap-min);
  padding: var(--nx-space-sm) var(--nx-space-md);
  background: none; border: 0; border-radius: var(--nx-radius-md);
  color: var(--nx-text); font-family: var(--nx-font);
  font-size: var(--nx-fs-body-md); text-align: left; cursor: pointer; width: 100%;
}
@media (hover: hover) and (pointer: fine) {
  .nx-menu__oge:hover { background: var(--nx-surface-3); }
}
.nx-menu__oge:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: -2px; }
.nx-menu__oge .nx-icon { width: var(--nx-ikon-sm); height: var(--nx-ikon-sm);
                         color: var(--nx-muted); }

/* ⭐ BÜYÜK MENÜ ÖĞESİ — ADI KONULMUŞ İSTİSNA (Efe, 19 Ağu 2026).
   Efe: *"ayarlar tuşunu biraz daha büyük yap, istisna olacak bu ayarlara özel."*
   Bugün TEK kullanıcısı var: Profil › kebap › Ayarlar. Ekran-yerel bir seçiciyle
   (ör. `[data-git="ayarlar.html"]`) yapılabilirdi ama o zaman istisnanın ADI
   olmazdı; sınıf, istisnayı görünür ve sayılabilir kılıyor.
   ⚠️ Yeni bir öğe bu sınıfı kendine pay çıkaramaz: ölçüt "menünün asıl işi mi"
     — diğerleri ikincil eylemse, biri asılsa o büyük durur. */
.nx-menu__oge--buyuk {
  min-height: calc(var(--nx-tap-min) + 12px);
  font-size: var(--nx-fs-body-lg);
  font-weight: var(--nx-fw-semibold);
}
.nx-menu__oge--buyuk .nx-icon { width: var(--nx-ikon-md); height: var(--nx-ikon-md);
                                color: var(--nx-text); }
/* ⭐ AYRAÇ — "Bug bildir" her menünün EN ALTINDA ve ekranın kendi eylemlerinden
   görsel olarak ayrı durur (Efe: *"en altta bug bildir diye bir seçenek koy"*).
   Ayrım yalnız konumla bırakılsaydı uzun menülerde son öğe sıradan görünürdü. */
.nx-menu__ayrac { height: 1px; background: var(--nx-border-soft);
                  margin: var(--nx-space-xs) var(--nx-space-md); }

/* BİLDİR ÇEKMECESİNİN NEDEN ÇİPLERİ — `nxRapor({ tur: "icerik" })` (kabuk.js).
   L-99 A (Efe, pano 1 Eki 2026): menüdeki «İlanı / Şirketi / Eğitimi bildir»
   öğeleri neden seçtiren çekmeceyi açar. Çip kabı tabanda yoktu (envanter
   taraması: yalnız `--nx-kontrol-cip`); sarar, çipler arası boşluk merdivenden. */
.nx-rapor__nedenler { display: flex; flex-wrap: wrap; gap: var(--nx-space-xs); }

/* DOSYA SEÇME ALANI — `nxDosyaAlani()` (kabuk.js). L-101 A (Efe, pano 1 Eki 2026):
   yerli dosya düğmesi yerine sistem düğmesi + seçilen dosyanın adı (envanter
   taraması: tabanda dosya alanı yoktu). Ad uzunsa tek satırda kısaltılır — düğme
   asla iki satır olmaz; seçilmeden önce soluk, seçilince metin rengi.
   Düğmenin yanında 8em'den az yer kalınca (büyük yazı, dar ekran) ad düğmenin
   ALTINA iner ve satırın tamamını alır — %200'de «Dosya seçilmedi» «Dosya …»ya
   kısalıyordu (kör denetçi Ş4, 1 Eki 2026; WCAG 1.4.4). 16 px'te yerleşim aynı. */
.nx-dosya { display: flex; flex-wrap: wrap; align-items: center;
            gap: var(--nx-space-xs) var(--nx-space-sm); min-width: 0; }
.nx-dosya__sec { flex: none; }
.nx-dosya__ad { flex: 1 1 8em; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                white-space: nowrap; font-size: var(--nx-fs-body-sm); color: var(--nx-muted); }
.nx-dosya__ad.is-secili { color: var(--nx-text); }

/* ==========================================================================
   AÇILIR LİSTE — .nx-dropdown   (Efe kararı, 23 Tem 2026)
   Native <select> tema tanımaz (canlı app bulgusu B13: tarayıcı bileşeni
   tasarım dilinin dışında kalıyor). Kendi açılır listemiz: tetikleyici buton
   + panel; klavye (Enter/Space/oklar/Esc/Home/End) ve ekran okuyucu destekli.
   GENİŞLİK: tetikleyici İÇERİĞE göre uzar — uzun başlık kırpılmaz (Efe).
   ========================================================================== */
.nx-dropdown { position: relative; display: inline-flex; max-width: 100%; }
.nx-dropdown__btn {
  display: inline-flex; align-items: center; gap: var(--nx-space-sm);
  width: 100%; min-height: var(--nx-tap-min);
  padding: var(--nx-space-sm) var(--nx-space-md);
  background: var(--nx-surface-2); color: var(--nx-text);
  border: 1px solid var(--nx-border-field);
  border-radius: var(--nx-radius-md);
  font-family: var(--nx-font); font-size: var(--nx-fs-body-md);
  text-align: left; cursor: pointer;
  transition: border-color var(--nx-dur-fast) var(--nx-ease),
              box-shadow var(--nx-dur-fast) var(--nx-ease),
              background var(--nx-dur-fast) var(--nx-ease);
}
.nx-dropdown__btn:hover { background: var(--nx-surface-3); }
.nx-dropdown__btn:focus-visible { outline: none; border-color: var(--nx-accent-on);
                                  box-shadow: 0 0 0 3px var(--nx-accent-soft); }
.nx-dropdown__deger { flex: 1; min-width: 0; white-space: nowrap; }
.nx-dropdown__btn .nx-icon { flex: none; width: var(--nx-ikon-sm); height: var(--nx-ikon-sm); color: var(--nx-muted);
                             transition: transform var(--nx-dur-base) var(--nx-ease); }
.nx-dropdown__btn[aria-expanded="true"] .nx-icon { transform: rotate(180deg); }
.nx-dropdown__panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: var(--nx-z-dropdown);
  min-width: 100%; max-height: 320px; overflow-y: auto; padding: 6px;
  background: var(--nx-surface-2);
  border: 1px solid var(--nx-border-float);
  border-radius: var(--nx-radius-md);
  box-shadow: var(--nx-yuzen);
}
.nx-dropdown__panel[hidden] { display: none; }
.nx-dropdown__oge {
  display: flex; align-items: center; gap: var(--nx-space-sm);
  width: 100%; min-height: 40px; padding: 0 var(--nx-space-sm);
  background: none; border: 0; border-radius: var(--nx-radius-sm);
  color: var(--nx-text); font-family: var(--nx-font);
  font-size: var(--nx-fs-body-sm); text-align: left; cursor: pointer;
  white-space: nowrap;
}
.nx-dropdown__oge:hover, .nx-dropdown__oge.is-vurgulu { background: var(--nx-surface-3); }
.nx-dropdown__oge:focus-visible { outline: 2px solid var(--nx-accent-on); outline-offset: -2px; }
.nx-dropdown__oge[aria-selected="true"] { font-weight: var(--nx-fw-semibold); }
.nx-dropdown__oge[aria-selected="true"] .nx-dropdown__tik { color: var(--nx-accent-on); }
.nx-dropdown__tik { margin-left: auto; display: inline-flex; }
.nx-dropdown__tik .nx-icon { width: var(--nx-ikon-xs); height: var(--nx-ikon-xs); }
.nx-dropdown__oge[aria-selected="false"] .nx-dropdown__tik { visibility: hidden; }
/* Dokunma kuralı — genişliğe değil cihaz yeteneğine bağlı (bkz. `.nx-chip` notu). */
@media (any-pointer: coarse) { .nx-dropdown__oge { min-height: var(--nx-tap-min); } }

/* ==========================================================================
   ALAN ETİKETİ — .nx-alan   (Efe kararı, 23 Tem 2026)
   "Küçük başlık üstte, büyük içerik altta" kalıbı. Kart ve liste satırında
   aynı bilgi aynı biçimde sunulur (iki mod arasında içerik paritesi).
   ========================================================================== */
.nx-alan { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.nx-alan__baslik {
  font-size: var(--nx-fs-caption); font-weight: var(--nx-fw-semibold);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--nx-muted); line-height: 1.3;
  /* Değer gibi başlık da kırpılır: iki sütunlu kartta alan kutusu kartın
     yarısı kadar ve "ÜNİVERSİTE" gibi tek parça etiketin kırılma fırsatı yok
     (denetçi: 1024px'te taşma sınırında, dar sütunda gerçek taşma riski). */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nx-alan__deger {
  font-size: var(--nx-fs-body-sm); color: var(--nx-text); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nx-alan__deger--sarabilir { white-space: normal; }

/* ==========================================================================
   İPUCU (tooltip) — Efe kararı, 24 Tem 2026
   Kırpılmış metnin tamamını gösterir. Native `title` YERİNE geçer: `title`
   temayı tanımaz, gecikmesi ayarlanamaz, dokunmatikte hiç çıkmaz ve ekran
   okuyucuda metni ikinci kez okutur. (Token `--nx-z-tooltip` bu bileşen için
   zaten ayrılmıştı; "Faz 1'de gerçek tooltip gelebilir" notu artık kapandı.)

   Kural: tek bir düğüm gövdede yaşar ve `position: fixed` ile konumlanır —
   kart/sütun/tablo gibi `overflow: hidden` kaplarından kaçar (popover ile aynı
   gerekçe). YALNIZ gerçekten kırpılmış metinde açılır; sığan metinde gürültü.
   Renk yüzen yüzey ailesinden; lime YOK (lime = yönlendirme, ipucu değil).
   ========================================================================== */
.nx-tooltip {
  position: fixed; top: 0; left: 0; z-index: var(--nx-z-tooltip);
  max-width: 260px;
  padding: var(--nx-space-xs) var(--nx-space-sm);
  background: var(--nx-surface-3); color: var(--nx-text);
  border: 1px solid var(--nx-border-float);
  border-radius: var(--nx-radius-sm);
  box-shadow: var(--nx-yuzen-hover);
  font-family: var(--nx-font); font-size: var(--nx-fs-caption);
  line-height: var(--nx-lh-body);
  pointer-events: none;            /* imleci yakalamaz → titreme/yanıp sönme olmaz */
  opacity: 0; visibility: hidden; transform: translateY(2px);
  transition: opacity var(--nx-dur-fast) var(--nx-ease),
              transform var(--nx-dur-fast) var(--nx-ease),
              visibility 0s linear var(--nx-dur-fast);
}
.nx-tooltip.is-acik { opacity: 1; visibility: visible; transform: none;
                      transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) {
  .nx-tooltip { transition: none; }
}

/* ==========================================================================
   AÇIKLAMA BALONCUĞU — .nx-balon
   Efe kararı 11 Ağu (`karar-gosterge-ogeleri-aciklanabilir`) + D23 (12 Ağu).

   NE İŞE YARAR
   İşlevsiz görünen bir göstergeye (rozet · `%uyum` · huni · yıldız) dokununca
   ne olduğunu anlatır. İlk kullanıcısı `%uyum`: uygunluk açıklaması karttan
   kalktı, buraya taşındı.

   🔴 NEDEN `position: fixed` VE NEDEN GÖVDEDE TEK DÜĞÜM — ÖLÇÜLDÜ (14 Ağu)
   Karar ekranı (`_Taslaklar/ilan_karti_YENI_DUZEN.html`) baloncuğu düğmenin
   İÇİNDE `position: absolute` ile kuruyordu. Gerçek kartta bu ÇALIŞMAZ:
   `.nx-ilan-kart` `overflow: hidden` taşıyor ve baloncuk kartın dışına
   **16,8px taşıp kırpılıyor** (karar ekranında canlı ölçüldü; 95px'lik yeni
   kartta neredeyse tamamı kırpılırdı).
   ⚠️ `absolute`ı kurtarmak için karttan `overflow:hidden` kaldırılamaz — o,
     kartın yuvarlak köşesini ve `line-clamp` kırpmasını tutuyor.
   ⚠️ `fixed` bile TEK BAŞINA yetmez: `.nx-scalable:active` kartta `transform`
     var ve transform'lu bir ata `fixed` için kapsayan blok olur ⇒ dokunma
     anında baloncuk yine kırpılırdı. ⇒ Düğüm GÖVDEDE yaşar, kartın içinde
     değil. Bu, `.nx-tooltip`in 24 Tem'de aynı gerekçeyle seçtiği kalıp.

   ⚠️ GENİŞLİK `cqi`, `vw` DEĞİL: masaüstünde öğrenci sütunu 430px (4 Ağu
     kararı) ama viewport 1280 olabiliyor — `78vw` orada 998px'lik bir baloncuk
     üretirdi. `cqi` Görev 6'da kurulan `ekran` kabına bağlanır.
   ⛔ Lime YOK: baloncuk bir AÇIKLAMA, yönlendirme değil (`karar-semantik-renk`).
   ========================================================================== */
/* ⭐⭐ 16 Ağu 2026 — BALONCUK ARTIK EKRANIN TAM ORTASINDA (Efe kararı)
   *"Bu baloncuklar mobil bazlı bir sistemde olduğu için aslında ekranın tam
   ortasında bir uyarı olarak çıkması daha iyi olur; hepsi tam ortalanmış çıksın,
   boşluğa basınca kapansın şeklinde."*

   🔴 NE GEÇERSİZ OLDU: tetikleyicinin altına/üstüne konumlanan "yüzen balon"
     kurgusu. `kabuk.js`teki `yerlestir()` (aşağı/yukarı çevirme, iki eksende
     kıstırma, sağ kenar hizalama) **tamamen kalktı** — 14 Ağu'da Codex'in
     eklettiği dikey kıstırma da onunla birlikte. Bunlar hatalı değildi;
     dayandıkları "balon tetikleyiciye yapışık durur" varsayımı kalktı.
   📌 KALAN GEREKÇELER AYNEN GEÇERLİ: düğüm hâlâ GÖVDEDE ve `fixed` — kartın
     `overflow:hidden`ı ve `:active` transform'u yüzünden (yukarıdaki uzun not).
     Ortalamak bu iki tuzağı ortadan kaldırmıyor, yalnız konumu sabitliyor.
   ⚠️ `inline-size` artık `cqi` DEĞİL viewport tabanlı: kutu artık içerik
     sütununa değil EKRANA göre ortalanıyor, ölçüsü de oradan gelmeli.
   ⚠️ Metin de ortalandı (`center`): tek-iki satırlık bir uyarı kutusunda
     sola dayalı metin ortalanmış kutunun içinde eğreti duruyor. */
.nx-balon {
  position: fixed; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--nx-z-tooltip);
  inline-size: min(300px, calc(100vw - 2 * var(--nx-space-xl)));
  max-block-size: min(60vh, 420px);
  padding: var(--nx-space-md);
  background: var(--nx-surface-3); color: var(--nx-text);
  border: 1px solid var(--nx-border-float);
  border-radius: var(--nx-radius-lg);
  box-shadow: var(--nx-yuzen-hover);
  font-family: var(--nx-font); font-size: var(--nx-fs-kucuk);
  line-height: 1.45; text-align: center;
  overflow-y: auto; overscroll-behavior: contain;
  /* ⚠️ `pre-line` ŞART: metin `textContent` ile basılıyor (XSS kapalı) ve iki
     parça taşıyor — açıklama + "yapay zekâ tahmini" dürüstlük notu. `\n\n`
     olmadan ikisi tek paragrafa yapışırdı. Baştaki/sondaki boşluklar yine
     sadeleşir, yalnız satır sonları korunur. */
  white-space: pre-line;
}
.nx-balon[hidden] { display: none; }

/* ⭐ PERDE — Efe'nin *"boşluğa basınca kapansın"* cümlesinin karşılığı.
   Basılacak "boşluk" ancak tanımlı bir yüzey varsa vardır; perde hem o hedefi
   veriyor hem uyarıyı arkasındaki içerikten ayırıyor.
   ⚠️ `--nx-scrim` çekmece/modalın kullandığı token — uyarı da aynı dili konuşur.
   ⛔ Arka plan `inert` YAPILMAZ ve kaydırma KİLİTLENMEZ: bu bir diyalog değil,
     tek cümlelik bir açıklama. Çekmecenin odak tuzağı buraya ağır kaçardı. */
.nx-balon-perde {
  position: fixed; inset: 0;
  z-index: calc(var(--nx-z-tooltip) - 1);
  background: var(--nx-scrim);
}
.nx-balon-perde[hidden] { display: none; }

/* Giriş: yavaşlayarak yerleşir (§ÇIKIŞ ANİMASYONU kuralının giriş yönü).
   Ölçek 0.96'dan gelir — ortadan "açılma" hissi; kayma YOK, kutu zaten ortada. */
@keyframes nx-balon-gir {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.96); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes nx-perde-gir { from { opacity: 0; } to { opacity: 1; } }
.nx-balon:not([hidden])       { animation: nx-balon-gir var(--nx-dur-base) var(--nx-ease-out); }
.nx-balon-perde:not([hidden]) { animation: nx-perde-gir var(--nx-dur-base) var(--nx-ease-out); }
/* ⭐⭐ ÇIKIŞ — GİRİŞİN AYNASI (animasyon kalite ölçütü **O5**, 17 Eyl 2026)
   🔴 DÜZELTİLEN KUSUR: baloncuk `nx-balon-gir` ile BÜYÜYEREK açılıyordu ama
     `kapat()` tek karede `hidden = true` yazıyordu — kutu da perde de aynı
     karede yok oluyordu. Kardeşleri (`.nx-modal` · `.nx-sheet` · `.nx-toast`)
     `.is-kapaniyor` dalını taşıyor; baloncuk o turdan SONRA doğduğu için
     kuralın dışında kalmış. → [[../../Notes/karar-animasyon-kalite-olcutu]]
   ⚠️ SIRA KRİTİK: bu kural `.nx-balon:not([hidden])`ten SONRA gelmek ZORUNDA.
     İkisi de 0,2,0 özgüllükte ve kapanış sırasında öğe henüz `hidden` DEĞİL —
     yani giriş kuralı hâlâ eşleşiyor. Yukarı taşınırsa çıkış sessizce
     kaybolur ve baloncuk yine pat diye gider. */
@keyframes nx-balon-cik {
  to { opacity: 0; transform: translate(-50%, -50%) scale(.96); }
}
/* ⛔ `nx-perde-cik` BURADA YENİDEN TANIMLANMAZ — yukarıda (`:1978`) zaten var ve
   çekmece/panel perdesi onu kullanıyor. İlk yazımda ikinci bir kopya eklemiştim;
   etkisi aynı olduğu için sessiz kalırdı, ama bu depoda "ikinci kopya" tam
   olarak sessizce ayrışan şeydir (nxSheet'in dört kopyası dersi).
   ⇒ Tek tanım, iki tüketici. */
.nx-balon.is-kapaniyor {
  animation: nx-balon-cik var(--nx-dur-exit) var(--nx-ease-in) forwards;
}
.nx-balon-perde.is-kapaniyor {
  animation: nx-perde-cik var(--nx-dur-exit) var(--nx-ease-in) forwards;
}

@media (prefers-reduced-motion: reduce) {
  /* ⚠️ `!important`: tokens.css'te reduced-motion altında evrensel bir
     `animation-duration: .01ms !important` var; onsuz bu dal ölü kod olur
     (aynı ders `.nx-sheet` ve `.nx-modal`da da yazılı). */
  .nx-balon:not([hidden]), .nx-balon-perde:not([hidden]) {
    animation: none !important;
  }
  /* ⛔ ÇIKIŞ TAMAMEN KAPATILMAZ, HAREKETSİZE ÇEVRİLİR. `animation: none`
     bırakılsaydı JS yine `--nx-dur-exit` kadar beklerdi ve kullanıcı o süre
     boyunca DONMUŞ bir baloncuğa bakıp sonra pat diye kaybolmasını görürdü.
     Az hareket "geri bildirim yok" demek değil: ÖLÇEK kalkar, SÖNME kalır. */
  .nx-balon.is-kapaniyor, .nx-balon-perde.is-kapaniyor {
    animation: nx-perde-cik var(--nx-dur-exit) var(--nx-ease-in) forwards !important;
  }
}

/* ==========================================================================
   YÜZEN KART — .nx-card revizyonu (Efe kararı, 23 Tem 2026)
   Gerekçe ve kuralın tamamı tokens.css'te ("YÜZEN KART"). Kenar zayıflar,
   yüzey kabından açılır, yumuşak gölge yükseltiyi pekiştirir.
   ========================================================================== */
.nx-card {
  background: var(--nx-surface-kart);
  box-shadow: var(--nx-yuzen);
}
/* Tıklanabilir kart HEM kart HEM denetim öğesidir → yüzen gölge ve ≥3:1
   kenar halkası BİRLİKTE verilir. Halka §261'de tanımlıydı ama yukarıdaki
   `.nx-card` aynı özgüllükte (0,1,0) ve sonra geldiği için onu tamamen
   siliyordu — ölçüldü: etkin box-shadow yalnız yüzen gölgeydi, halka yok
   (WCAG 1.4.11 regresyonu). tokens.css §157 T3 uyarısı bu halkayı şart
   koşuyor (denetçi, 30 Tem 2026). */
/* ⭐ HALKA İNCELTİLDİ (Efe, 6 Ağu 2026): `--nx-border-field` → `--nx-kart-kenar`.
   Efe: "kartların kenar çizgilerini koyuda ve açıkta daha silik yapalım,
   arka plan üstünde yüzüyor gibi olsun."
   ⚠️ BİLİNEREK KABUL EDİLEN BEDEL — ölçülmüş: kart kenarının 1.4.11 kontrastı
   düşüyor (`--nx-border-field` .42/.50 → `--nx-kart-kenar` .10/.12). Kart
   KAYBOLMUYOR: kimliğini artık ağırlıklı olarak yüzen gölge + yüzey tonu
   taşıyor, kenar yalnız onu pekiştiriyor. Aynı sınıf bir karar 31 Tem'de de
   verilmişti (açık temada lime dolgunun dış sınırı 2.08:1) — Efe sayıyı
   görerek seçiyor. CTO paketine "ölçülmüş sapma" olarak yazılır.
   ⛔ ODAK HALKASI BU KARARIN DIŞINDA: `:focus-visible` 2px `--nx-accent-on`da
   kalıyor (aşağıda) — o bir erişilebilirlik tabanı, estetik kenar değil. */
/* ⭐ HALKA KALDIRILDI (Efe kararı, 12 Eyl 2026) — yukarıdaki "bilinerek kabul
   edilen bedel" notu artık GEÇMİŞ KAYDI: kenarın 1.4.11 kontrastını tartışan o
   paragraf halkanın DURDUĞU dönemi anlatıyor, bugün halka yok.
   Efe: *"Kartlarda çerçeve olmayacak, sadece kart arkaplanı olacak."*
   ⇒ Kartın kimliğini TAMAMEN zemin tonu + yüzen gölge taşıyor.
   ⛔ ODAK HALKASI HÂLÂ BU KARARIN DIŞINDA: `:focus-visible` 2px `--nx-accent-on`
      kalıyor (yukarıda) — erişilebilirlik tabanı, estetik kenar değil.
   🔬 Yayılma ölçüldü (16 ekran × iki tema, 11.104 öğe): kutusu kayan öğe 0,
      görünüşü değişen 270 ve hepsi kart/akordeon, beklenmedik 0. `box-shadow`
      yerleşimi etkilemediği için hiçbir yerleşim oynamadı. */
.nx-card--tiklanabilir {
  box-shadow: var(--nx-yuzen);
}
.nx-card--tiklanabilir:hover {
  box-shadow: var(--nx-yuzen-hover);
}

/* ==========================================================================
   İLAN KARTI — .nx-ilan-kart   (sisteme alındı: Efe kararı, 6 Ağu 2026)

   NEDEN BURADA
   Bu kart 3 Ağu'da Keşfet ekranının içinde doğdu ve `.kf-*` (Keşfet) adıyla
   yaşıyordu. 6 Ağu'da "Tüm ilanlar" ekranı da aynı kartı kullanınca İKİ KOPYA
   oluştu; sınıf adları bilerek birebir tutulmuştu ki çıkarma `diff` ile
   doğrulanabilsin. Efe kuralı:

     "Bu gibi değişiklikler sebebiyle hep aynı şeyleri kullanmaya çalışalım
      varyasyon oluşmasın diye. Ayrıca bu gibi tasarımların hepsini tek tek
      bir yerde toplayalım, marka kimliğinde yaptığımız gibi."

   ⇒ Kart artık TEK KAYNAK burası. Ekranlar yalnız sınıfı kullanır, kendi
     kopyalarını TAŞIMAZ. Kalan üç liste ekranı da buradan alacak.

   YAPI — D23 (14 Ağu 2026). Beş DOĞRUDAN çocuk; ara sarmalayıcı YOK.
     <article class="nx-card nx-card--tiklanabilir nx-scalable nx-ilan-kart">
       <span class="nx-logo-kutu nx-logo-kutu--buyuk">...</span>
       <span class="nx-ilan-kart__govde">
         <h3 class="nx-ilan-kart__rol">
           <a class="nx-ilan-kart__baglanti" href="...">Pozisyon</a></h3>
         <span class="nx-ilan-kart__sirket">Sirket</span>
       </span>
       <span class="nx-ilan-kart__alt">
         <span class="nx-ilan-kart__meta">Konum · Tur · Model</span>
       </span>
       <span class="nx-ilan-kart__sure">2 gun</span>
       <button class="nx-ilan-kart__uyum" type="button"
               aria-expanded="false" aria-controls="nx-balon"
               aria-label="%87 uygunluk — nedenini goster"
               data-balon="Figma deneyimin üç şartın üçünü de karşılıyor.">
         <span class="nx-match" data-match="7" aria-hidden="true">%87</span>
       </button>
     </article>

   🔴 D23 ÜÇ ŞEYİ KALDIRDI (Efe, 12 Ağu):
     ① `__neden` — açıklama karta değil baloncuğa gider (`data-balon`)
     ② `.nx-kart-kaydet` — kaydet ilan kartından KALKTI, yalnız ilan detayında
     ③ `__ust` + `__kimlik` sarmalayıcıları — grid onların işini yapıyor
   ⚠️ ②'nin kapsamı YALNIZ İLAN KARTI. Şirket ve eğitim kartları kaydeti
     KORUYOR (6 Ağu kararı orada geçerli) — D23 ilan kartının kararıydı.

   🔴 KAP `<article>`, `<a>` DEĞİL — bu bir tercih değil ZORUNLULUK:
   kart bir `<a>` iken içine kaydet `<button>`'ı koymak İÇ İÇE ETKİLEŞİMLİ
   İÇERİK demektir (geçersiz HTML; ekran okuyucuda düğme ya hiç duyulmaz ya
   bağlantının adına karışır). Asıl hedef başlıktaki bağlantıdır ve `::after`
   ile kartın tamamına GERİLİR; kaydet düğmesi onun üstünde ayrı katmandır.

   ÖLÇÜ SÖZLEŞMESİ (375px ekran) — 🔴 D23 + D37 sonrası ÖLÇÜLDÜ (14 Ağu):
     kart 359 × **92,6** · logo 48 × 48 · dolgu **dikey 12 / yatay 8** ·
     kartlar arası ve kenar payı 8px.
   ⚠️ Eski sözleşme *"359 × 174, dört kenarda 12px"* idi; ikisi de artık yanlış
     (gerekçe karttan kalktı → yükseklik yarıya indi; D37 yatayı 8'e çekti).
     Codex çapraz kontrolü bu satırın bayat kaldığını yakaladı.
   📌 `sirket_sayfasi`ın kartı 86,2 — o ekran şirket adı satırını basmıyor.
     Sözleşme "her ekranda aynı sayı" değil, "her LİSTENİN içinde eşit"tir.
   ========================================================================== */
.nx-ilan-kart {
  /* 📌 `--nx-kart-dolgu` (12px) ARTIK `tokens.css` `:root`ta (13 Ağu 2026).
     Buradaki yerel bildirim KALDIRILDI: Efe *"yatay mesafeleri eşitle hepsi
     için"* dedi ve `profil.html`in belge satırları 16px kullanıyordu. İki yerde
     ayrı dursaydı biri değişince öteki sessizce kayardı — 4 Ağu'da ölçülerek
     seçilen 12px'in gerekçesi de token'ın yanına taşındı. */
  min-height: 0; overflow: hidden;
  background: var(--nx-surface-2);   /* Efe: kart sayfadan 1-2 ton ayrışır */
  /* ⭐⭐ D23 — ÜÇ SÜTUN × İKİ SATIR (Efe kararı, 12 Ağu; uygulandı 14 Ağu)
       ┌─────────┬──────────────────┬────────┐
       │  logo   │ rol + şirket     │ %uyum  │   satır 1
       │ (2 satır│──────────────────┼────────┤
       │  boyunca│ meta             │ süre   │   satır 2
       └─────────┴──────────────────┴────────┘
     ⭐ Efe: *"saat/gün belirteci en sağ altta olacak, boşu boşuna soldaki
       yazıyı sıkıştırmış."* ⇒ Süre içerik sütunundan ÇIKTI, kendi hücresinde.
       İki kazanç: ① süre kartın gerçek sağ kenarına yaslanıyor ② meta, içerik
       sütununun TAMAMINI geri aldı.
     ⛔ FLEX DEĞİL GRID: süre `__alt` içinde `space-between` ile duruyordu;
       %uyum akışa girince oradaki "sağ kenar" kartın değil içerik sütununun
       sağ kenarıydı. Grid'de hücre koordinatı bunu kökten çözüyor.
     📌 Koordinatlar AÇIK yazılır (D20/Codex): yalnız satır verilirse
       auto-placement öğeyi başka sütuna koyabilir. */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  /* ⛔ 1. SATIRIN TABANI = DOKUNMA HEDEFİ (44px) — ÖLÇÜMLE ZORUNLU OLDU.
     `%uyum` düğmesi bu satırda ve `--nx-tap-min` taşıyor. Taban yazılmasaydı
     satır içeriğe göre kısalır, rozeti OLAN kart 44'e gerilir, olmayan kart
     kısa kalırdı. 14 Ağu'da tam bu ölçüldü: `sirket_sayfasi` şirket adı
     satırını basmadığı için kartlar **86,2 ↔ 74,4** ayrıştı (D22 ihlali).
     ⚠️ `kesfet`/`tum_ilanlar`da bu taban HİÇBİR ŞEYİ DEĞİŞTİRMEZ (orada satır
       zaten 50,4px: rol 2lh + şirket adı) — yani kural görünmez ama koruyucu.
       "Bugün etkisi yok" diye yazılmazsa yarınki varyant sessizce bozulur. */
  grid-template-rows: minmax(var(--nx-tap-min), auto) auto;
  align-items: start;
  /* ⭐ Logo ↔ yazı sütunu arası 16px (Efe, 6 Ağu: "biraz daha aç ki çok
     sıkışık gözükmesin"). Satır arası 2px — iki satır tek bloğu okunur. */
  column-gap: var(--nx-space-md);
  row-gap: 2px;
  padding: var(--nx-kart-dolgu) var(--nx-kart-dolgu-yatay);   /* D37: yatay 8 */
  text-decoration: none; text-align: left;
  position: relative;   /* gerilmiş bağlantının çapası */
}
/* ⭐ "Logo dikeyde ortalı olacak SADECE" (Efe, 12 Ağu) — hizalama TEK TEK
   verilir; kaba `align-items: center` YAZILMAZ, o üç sütunu birden ortalardı.
   Logo boyu DEĞİŞMEZ: `--nx-avatar-*` merdiveninde kalır (D23'ün açık şartı). */
.nx-ilan-kart > .nx-logo-kutu { grid-column: 1; grid-row: 1 / span 2;
                                align-self: center; }
.nx-ilan-kart__govde { grid-column: 2; grid-row: 1; }
.nx-ilan-kart__alt   { grid-column: 2; grid-row: 2; }
.nx-ilan-kart__uyum  { grid-column: 3; grid-row: 1; }
.nx-ilan-kart__sure  { grid-column: 3; grid-row: 2;
                       justify-self: end; align-self: end; }
/* 🔴 YÜKLEME SIRASI TUZAĞI — kart sisteme taşınırken CANLIDA YAKALANDI (6 Ağu).
   Kart ekran dosyasındayken `padding: 12px` kuralı sayfanın kendi <style>'ındaydı,
   yani TÜM stil dosyalarından SONRA geliyordu ve kazanıyordu. Buraya taşınınca
   sıra değişti: `components.css` → `mobile.css`, ve mobile.css'te
   `.nx-card { padding: var(--nx-space-md) }` (16px) var. İki kural da (0,1,0);
   sonra gelen kazandı ⇒ dolgu sessizce 12 → 16 oldu ve **kart 174 → 182px**
   yükseldi (ölçüldü).
   ⇒ Kart HER ZAMAN `.nx-card` ile birlikte kullanıldığı için (0,2,0) seçici
     hem doğru hem kararlı. mobile.css'e dokunmaya gerek yok.
   ⚠️ DERS: bir kuralı ekran-yerelden sisteme taşımak ÖZGÜLLÜK DEĞİL SIRA
     değiştirir. Taşınan her kuralda "mobile.css aynı şeyi söylüyor mu?" diye
     bakılır — ölçü sözleşmesi bunu yakaladı, göz yakalayamazdı (8px). */
.nx-card.nx-ilan-kart { padding: var(--nx-kart-dolgu) var(--nx-kart-dolgu-yatay); }

/* ⚠️ D23'te `__ust` ve `__kimlik` yuvaları KALKTI — üç sütunlu grid onların
   işini yapıyor. `__govde` artık yalnız rol + şirket taşır (eski `__kimlik`'in
   işi). Eski adlar korunmadı: iki boş sarmalayıcı, grid koordinatlarının
   üstünde ikinci bir hizalama katmanı kurup hata kaynağı olurdu. */
.nx-ilan-kart__govde { min-width: 0; display: flex; flex-direction: column;
                       gap: 2px; }
/* Rol başlığı: ekranın en önemli metni. 2 satır tavan + 2lh taban → metin
   karta boy değiştiremez. ⚠️ `lh` ÖĞENİN KENDİ font-size'ından hesaplanır,
   kaptan değil — punto bu öğede yazılmak zorunda. */
.nx-ilan-kart__rol {
  margin: 0; font-size: var(--nx-fs-body-md); font-weight: var(--nx-fw-semibold);
  line-height: var(--nx-lh-tight);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; min-height: 2lh;
}
.nx-ilan-kart__sirket { font-size: var(--nx-fs-caption); color: var(--nx-muted);
                        line-height: 1.35;
                        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ⭐⭐ %UYUM ARTIK SAĞDA VE DOKUNULABİLİR — D23 (Efe, 12 Ağu)
   🔴 6 AĞU KARARI DÜŞTÜ: rozet sol üst köşede, `position:absolute` ve
   `pointer-events:none` idi. Gerekçesi koddaydı: *"kapatılmasaydı kartın sol
   üst köşesinde tıklamayı yutan ölü bir alan oluşurdu."* Rozet kendi sütununa
   (3) taşınınca o gerekçe ortadan kalktı — artık akışta, kasıtlı bir hedef.

   ⭐ Efe: uygunluk AÇIKLAMASI karttan kalkar, `%uyum`a DOKUNUNCA baloncukta
     çıkar. ⇒ Rozet bir `<button>`; `data-balon` özniteliği metni taşır.
   ⭐ Dikeyde ortalı (D varyantı): `align-self: center` rozeti KENDİ SATIRINDA
     ortalar. ⚠️ Bu, kartın dikey merkezi DEĞİL — 95px'lik kartta "süre sağ
     altta" ile "%uyum tam ortada" aynı anda geometrik olarak mümkün değil;
     rozet ~10,5px yukarıda kalıyor. Efe: *"kabul edilebilir."*
   ⚠️ Dokunma hedefi 44px tabanında (D4 — asla ezilmez). Görsel rozet küçük
     kalır, hedef tam: `karar-gosterge-ogeleri-aciklanabilir` kalıbı.
   ⚠️ `z-index` gerilmiş bağlantının ÜSTÜNDE olmak zorunda, yoksa rozete
     dokunmak ilan sayfasını açar. */
.nx-ilan-kart__uyum {
  align-self: center;
  position: relative; z-index: 2;
  display: grid; place-items: center;
  min-inline-size: var(--nx-tap-min); min-block-size: var(--nx-tap-min);
  padding: 0; border: 0; background: none; cursor: pointer; font: inherit;
}
.nx-ilan-kart__uyum:focus-visible { outline: 2px solid var(--nx-accent-on);
                                    outline-offset: 2px;
                                    border-radius: var(--nx-radius-sm); }
/* Sponsorlu kartın dürüstlük etiketi %uyum'un HÜCRESİNİ kullanır (sütun 3,
   satır 1) — çakışma yok, çünkü sponsorlu kartta `%uyum` hiç basılmaz (reklam
   kullanıcı hakkında iddia etmez). D23 öncesi `flex: 0 0 auto` ile üst satırın
   sağ ucundaydı; grid'de koordinat açık yazılır (D20).
   📌 Etiket düz METİN kalır, düğme DEĞİL: tanıtım metni 14 Ağu'da Efe kararıyla
     sponsorlu karttan tümüyle kalktı ⇒ etiketin açacağı bir şey yok. */
.nx-ilan-kart__sponsor-etiket {
  grid-column: 3; grid-row: 1; align-self: center; justify-self: end;
}
/* 🔴 `.nx-ilan-kart__neden` KARTTAN KALKTI — D23 (Efe, 12 Ağu).
   *"Uygunluk açıklaması karttan kalkar → `%uyum`a dokununca baloncukta çıkar."*
   Metnin kendisi ölmedi, `data-balon` özniteliğine taşındı; biçimi artık
   `.nx-balon` bileşeninden geliyor. Yuva 3 satır (3lh ≈ 50px) yer kaplıyordu —
   kartın 170 → 95px'e inmesinin TEK BÜYÜK kalemi bu.
   📌 Eski kural burada tutulmuyor; `.nx-balon`a bakılır. */

/* Alt satır: yalnız konum/çalışma tipi. ⛔ SÜRE ARTIK BURADA DEĞİL — kendi
   hücresinde (col3/row2). Süre içerideyken `space-between` onu içerik
   sütununun sağ kenarına yaslıyordu, kartın sağ kenarına değil.
   ⭐ Bunun ÖLÇÜLMÜŞ bir yan faydası var: eski `__alt` `align-items: baseline`
     idi ve süre yuvası 16px'lik saat ikonuyla satır kutusunu geriyordu ⇒
     süresi OLAN kart 20,28px, olmayan 16,19px ⇒ **4,09px**. Kardeş kartlar
     arasında ölçülen 4px'lik D22 ihlalinin tamamı buydu (14 Ağu, zincir
     ölçümü). Süre satırdan çıkınca sebep kökten kalktı. */
.nx-ilan-kart__alt { display: flex; align-items: center;
                     gap: var(--nx-space-sm); min-width: 0; }
/* Meta DÜZ METİN — ⛔ `.nx-chip` değil (mobilde 44px + kalıcı katman üretirdi). */
.nx-ilan-kart__meta {
  flex: 1; min-width: 0;
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ⭐ Süre metninde "önce" YOK (Efe, 12 Ağu): yalnız `2 gün` · `6 saat` ·
   `3 hafta`. Yan fayda: Türkçe ek çekimi sorununun bir kaynağı kapandı. */
.nx-ilan-kart__sure {
  display: inline-flex; align-items: center; gap: var(--nx-space-xs);
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
  white-space: nowrap;
}
/* ⚠️ Boy SVG'nin KENDİSİNE yazılır (`.nx-icon`), sarmalayıcıya değil: sarmalayıcı
   16px kalıp SVG 24px'te kaldığında ikon kabından TAŞIYORDU (Keşfet F4 bulgusu). */
.nx-ilan-kart__sure :is(.nx-ico, .nx-icon) {
  width: var(--nx-ikon-xs); height: var(--nx-ikon-xs);
}

/* ── Gerilmiş bağlantı ──
   ⚠️ `:focus-visible` kabın kendisinde tetiklenemez (<article> odak almaz);
   halka `:has()` ile gerilmiş bağlantıdan türetilir. */
.nx-ilan-kart__baglanti { color: inherit; text-decoration: none; }
.nx-ilan-kart__baglanti::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.nx-ilan-kart:has(.nx-ilan-kart__baglanti:focus-visible) {
  outline: 2px solid var(--nx-accent-on); outline-offset: 3px;
}

/* ── KAYDET (bookmark) ──
   Boş = kaydedilmemiş · İÇİ DOLU = kaydedilmiş. Durum değişimi DOĞRUDAN.
   🔴 SİSTEMDE ÇAKIŞMA: `ikon-animasyon.css` bookmark ikonuna `bmfill` bağlıyor —
      ikon dolup SONRA BOŞALIYOR. Efe bunu açıkça yasakladı ("full başlayıp dolan
      ve sonra boşalan animasyon OLMAMALI"). Burada iptal ediliyor.
      🗒️ Kalıcı çözüm ikon katmanında; tüm app'i etkiler, ayrı tur. */
/* ⭐ KAYDET DÜĞMESİ — 🔴 ARTIK İKİ KART TÜRÜNDE (D23, 14 Ağu 2026)
   Efe, 6 Ağu: *"kullanıcının dönüp tekrar bakmak isteyeceği tüm kartlarda
   kaydet olması lazım. Kaydettiklerine Başvurularım hub'ından ulaşacak."*

   🔴 **İLAN KARTINDAN KALKTI** — D23 (Efe, 12 Ağu): *"Kaydet (bookmark)
   karttan kalkar — yalnız ilan detayında."* Kaydetme yeteneği kaybolmuyor,
   yeri değişiyor: ilan sayfasının kendisinde duruyor. Gerekçe kartın 170 →
   95px'e inmesi; 44px'lik bir hedef 95px'lik kartın yarısını yiyordu.
   ⚠️ KAPSAM: karar YALNIZ ilan kartı içindi. **Şirket ve eğitim/sertifika
     kartları kaydeti KORUYOR** — aşağıdaki `__ust > .nx-kart-kaydet` kuralları
     onlar için hâlâ canlı. 6 Ağu kararı o iki kartta aynen geçerli.

   🔴 ADI DEĞİŞTİ: `.nx-ilan-kart__kaydet` → `.nx-kart-kaydet`.
   Artık ilan kartına ait değil; ilan · şirket · eğitim/sertifika kartlarının
   ORTAK parçası. Eski ad kalsaydı şirket kartında "ilan-kart" sınıfı taşımak
   gerekirdi — sistemin adları işini anlatmalı.

   ⛔⛔ D46 GERİ ALINDI — Efe, 16 Ağu 2026, ekrana bakarak.
     *"Şirket kartlarının uzaması hiçbir işe yaramamış, hatta berbat etmiş her
     şeyi. Kart boyutunu geri al, eski haline çek."*
     ⇒ Negatif dış boşluk geri kondu; kartlar eski boylarına döndü.

     📌 D46 NEYDİ (kayıt kalsın): 15 Ağu'da bu satır silinmişti çünkü 44px'lik
       dokunma hedefi düzende yer kaplamıyor, komşu içeriğin üstüne taşıyordu
       (ölçüldü: dokunulan alan görünen ikonun **3,36 katı**). Gerekçesi 11 Ağu
       kararıydı. **Bedeli de ölçülmüştü ve Efe onu görerek seçmişti** —
       ama sayıyı görmek ile ekranı görmek aynı şey değilmiş: canlıda kartlar
       şişkin durdu. ⭐ Ders: boy değişikliği kararı ölçüyle DEĞİL gözle verilir.
     🔴 Bu geri alma, 11 Ağu kararının ② maddesini (*"öğe = dokunma alanı"*)
       bu üç seçici için askıya alır. Karar notu güncellendi; bir daha
       "uygulanmamış" sanılıp yeniden denenmesin.
   ⚠️ GERİLMİŞ BAĞLANTININ ÜSTÜNDE: `position: relative; z-index: 1` olmadan
     kaydete dokunmak kartın kendisini açardı.
   📌 Kaydedilenler "Başvurularım" hub'ını besleyecek (o ekran sonraki tur). */
.nx-kart-kaydet {
  flex: 0 0 auto; position: relative; z-index: 1;
  width: var(--nx-tap-min); height: var(--nx-tap-min);
  margin: calc(var(--nx-space-xs) * -1) calc(var(--nx-space-xs) * -1) 0 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--nx-muted); border-radius: var(--nx-radius-full);
  transition: color var(--nx-dur-fast) var(--nx-ease);
}
.nx-kart-kaydet:focus-visible { outline: 2px solid var(--nx-accent-on);
                                outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) {
  .nx-kart-kaydet:hover { color: var(--nx-text); }
}
.nx-kart-kaydet[aria-pressed="true"] { color: var(--nx-text); }
/* Dolu hâl: strok ikonun gövdesi doldurulur — ayrı bir "dolu bookmark" SVG'si
   ÜRETİLMEZ (ikon seti tek kaynak; ikinci varyant iki kaynak demek). */
.nx-kart-kaydet[aria-pressed="true"] .nx-icon .bm { fill: currentColor; }
/* ⛔ "Dolup sonra boşalan" animasyon YOK — Efe'nin açık yasağı (spec §5.7b). */
.nx-kart-kaydet .i-bookmark.play .bm { animation: none !important; }

/* Üç kartta da üst satırın en sağında.
   ⚠️ Şirket kartında yıldızın (puan) SAĞINDA: yıldız İÇERİĞE dair bir eylem
   (yorumları aç), kaydet ise KARTA dair. Karta ait olan en dışta durur.

   🔴 SİMETRİK NEGATİF BOŞLUK ŞART — canlı ölçümle yakalandı (6 Ağu):
   İlan kartının `margin: -xs -xs 0 0` değeri burada YETMEDİ ve şirket kartı
   **94 → 116px**'e çıktı. Sebep: ilan kartının üst satırında zaten daha uzun
   içerik var (iki satırlık rol + şirket adı), 44px'lik düğme satırı sürüklemiyor.
   Şirket/eğitim kartında üst satır TEK SATIRLIK bir addan ibaret; düğme satırın
   en uzun öğesi oluyor ve kartı kendisi büyütüyor.
   ⇒ `.nx-sirket-kart__puan`la AYNI çözüm: dokunma hedefi 44px kalır ama satıra
     yalnız metin yüksekliği kadar katılır. Ölçü sözleşmeleri korunuyor.

   ⛔ 15 Ağu'da D46 ile SİLİNDİ, 16 Ağu'da Efe GERİ ALDIRDI (ekrana bakarak:
     *"berbat etmiş her şeyi"*). Kural 6 Ağu'daki hâline döndü.
     📌 Bu kuralın bir kaçamak olmadığı iki kez ölçüldü: onsuz şirket kartı
       116-134px'e çıkıyor ve Keşfet tile'ı %30 şişiyor. */
.nx-sirket-kart__ust > .nx-kart-kaydet,
.nx-egitim-kart__ust > .nx-kart-kaydet {
  margin: calc(var(--nx-tap-min) / -2 + 0.6em) calc(var(--nx-space-xs) * -1)
          calc(var(--nx-tap-min) / -2 + 0.6em) 0;
}

/* ⛔ KOMPAKT (Keşfet, 176px) TILE'LARDA KAYDET YOK — Efe kararı, 6 Ağu 2026
   ⚠️ Bu karar ÜÇ ADIMDA netleşti; kayıt önemli çünkü ikisi CANLI ÖLÇÜMLE elendi:

   ① Önce "dar kartta yer yok" diye basmamıştım.
   ② Efe düzeltti: *"Keşfet'te de kaydetme olmalı, orada güzel bir ilana denk
      gelip kaydedebilir çünkü."* ⇒ Sağ üst köşeye koyup başlığa yer açtım.
      🔴 ÖLÇÜLDÜ VE ELENDİ: şirket adına kalan genişlik **92 → 60px**;
      *"Türkiye İş Bankası"* → **"Türkiye İş…"** diye kırpıldı.
   ③ Meta satırına taşıdım — ad kurtuldu (92px geri geldi) ama alt satır ÜÇ
      öğeye çıktı ve yıldızı olmayan kartta bookmark tek başına ortada kaldı.
      Efe gördü ve kapsamı yeniden çizdi.

   ⭐ SON KARAR (Efe): kaydet **geniş kartlarda kalır, dar tile'lardan kalkar.**
   Gerekçe ölçüye dayanıyor: geniş kartta (359px) kaydet eklendiğinde **tek
   piksel değişmedi** ve hiçbir metin kırpılmadı — bedel yalnız 176px'te var.
   ⇒ Triyaj refleksi (listede görüp kaydetme) korunuyor; feragat yalnız gerçekten
     dar olan tek yerde. Keşfet'te kaydet **yine var** — geniş ilan kartlarında.
   📌 Dar tile'daki içerik zaten "detaya git" davetidir; kaydet orada, detay
     sayfasının üst çubuğunda yaşıyor. */
.nx-sirket-kart--kompakt .nx-kart-kaydet,
.nx-egitim-kart--kompakt .nx-kart-kaydet { display: none; }

/* ── ÖLÇEK GERİ BİLDİRİMİ — SABİT PİKSEL (Efe, 4 Ağu) ──
   `scale` ORANSALDIR: sistemin 1.06'sı 343px'lik kartta her yandan ~10px büyüme
   demek ve kart kenar payını yiyip ekran dışına taşıyordu.
   ÇÖZÜM: büyüme PİKSEL olarak sabit; ölçek genişlikten türetilir → her yandan 2px.
   ⭐ KAPSAM ÖLÇÜTÜ boyut değil ORAN: öğe içerik genişliğinin ~%80'inden genişse
     sabit-piksel kullanır; dar kartlar sistemin %6'sıyla devam eder.
   ⚠️ Sistemin :active ve reduced-motion İPTALLERİNİ geri veren iki blok ŞART —
     özgüllük yükseltildiği anda o varyantlar da eziliyor (Keşfet F7 dersi). */
/* 🔴 7 Ağu 2026 — KURAL VARDI, KAPSAMI EKSİKTİ (Efe: *"üçünü eşitle"*).
   Yukarıdaki ölçüt ("içerik genişliğinin ~%80'inden genişse sabit-piksel")
   **üç geniş kartın üçünü de** kapsıyor, ama uygulama yalnız ilan kartına
   yazılmıştı. Şirket ve eğitim kartının GENİŞ varyantı da 359px — aynı ölçüde —
   ve sistemin %6'sıyla kalmışlardı.
   **Canlı ölçüldü (375px):** 359 → **380,5px**, yani her yandan **2,8px ekran
   DIŞINA** taşıyorlardı; kart kenar payı 8px, büyüme 10,8px. İlan kartı bu
   hatayı yaşamıyordu çünkü kendi yumuşak ölçeği vardı.
   ⇒ Token artık ilan'a değil **GENİŞ KART** kavramına ait: `--nx-genis-kart-olcek`.
   ⚠️ `--kompakt` varyantlar KAPSAM DIŞI (`:not(...)`): onlar 175,5px, yani
     ölçütün "dar kart" tarafı — sistemin %6'sıyla devam ederler ve 8px'lik
     ızgara aralığına sığarlar (her yandan 5,3px). */
.nx-ilan-kart,
.nx-sirket-kart:not(.nx-sirket-kart--kompakt),
.nx-egitim-kart:not(.nx-egitim-kart--kompakt) { --nx-genis-kart-olcek: 1.0117; }
@media (hover: hover) and (pointer: fine) {
  .nx-ilan-kart.nx-scalable:hover,
  .nx-sirket-kart:not(.nx-sirket-kart--kompakt).nx-scalable:hover,
  .nx-egitim-kart:not(.nx-egitim-kart--kompakt).nx-scalable:hover {
    transform: scale(var(--nx-genis-kart-olcek));
  }
}
.nx-ilan-kart.nx-scalable:active,
.nx-sirket-kart:not(.nx-sirket-kart--kompakt).nx-scalable:active,
.nx-egitim-kart:not(.nx-egitim-kart--kompakt).nx-scalable:active {
  transform: scale(var(--nx-scale-active));
}
@media (prefers-reduced-motion: reduce) {
  .nx-ilan-kart.nx-scalable:hover,
  .nx-ilan-kart.nx-scalable:active,
  .nx-sirket-kart:not(.nx-sirket-kart--kompakt).nx-scalable:hover,
  .nx-sirket-kart:not(.nx-sirket-kart--kompakt).nx-scalable:active,
  .nx-egitim-kart:not(.nx-egitim-kart--kompakt).nx-scalable:hover,
  .nx-egitim-kart:not(.nx-egitim-kart--kompakt).nx-scalable:active { transform: none; }
}

/* ==========================================================================
   LOGO KUTUSU — .nx-logo-kutu   (ilan ve şirket kartları paylaşır)
   Logo VAR → açık levha (iki temada) · Logo YOK → SAYDAM kap + `building` ikonu.
   ========================================================================== */
.nx-logo-kutu {
  flex: 0 0 auto;
  width: var(--nx-avatar-sm); height: var(--nx-avatar-sm);   /* ⛔ literal px değil */
  border-radius: var(--nx-radius-sm);
  display: grid; place-items: center;
  overflow: hidden;
}
/* 🔴 `padding: 10%` HATAYDI: yüzdeli dolgu öğenin KENDİ genişliğine değil
   KAPSAYICI BLOĞUN genişliğine göre çözülür — ilan kartında kutu 32px yerine
   67px'e şişiyordu. Dolgu artık avatar boyuna bağlı, kaptan bağımsız. */
.nx-logo-kutu--dolu { background: var(--nx-offwhite);
                      padding: calc(var(--nx-avatar-sm) * .1); }
.nx-logo-kutu--dolu img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* ⚠️⚠️ `--nx-accent` geçersiz kılması `.nx-ico` SEVİYESİNDE olmak ZORUNDA:
   `.nx-ico` kendi üzerinde `--nx-accent: var(--nx-accent-on)` bildiriyor
   (ikon.css) ve TORUN kendi bildirimiyle atayı ezer. Kaba yazılırsa kural
   SESSİZCE ETKİSİZ kalır ve building ikonu koyu temada lime aksan basar. */
.nx-logo-kutu--bos { background: transparent; color: var(--nx-muted); opacity: .6; }
.nx-logo-kutu--bos .nx-ico { --nx-accent: currentColor;
                             width: var(--nx-ikon-md); height: var(--nx-ikon-md); }
.nx-logo-kutu--buyuk { width: var(--nx-avatar-md); height: var(--nx-avatar-md); }
/* Detay sayfasının ortalanmış üst bloğu için — merdivenin en üst basamağı. */
.nx-logo-kutu--hero  { width: var(--nx-avatar-lg); height: var(--nx-avatar-lg); }

/* ==========================================================================
   DETAY SAYFASI ÜST BLOĞU — .nx-detay-bas / .nx-detay-bilgi
   Efe kararı, 16 Ağu 2026 · tam düzen kaydı: Notes/spec-detay-sayfasi-ust-blok.md

   NEDEN SİSTEMDE (D42): iskelet ÜÇ ekranda da aynı (ilan · şirket · eğitim).
   Ekran ekran kopyalansaydı bu blok dördüncü kez aynı kaderi yaşardı —
   `nxSheet`in dört kopyası sessizce birbirinden kaymıştı, `nxUyumRozeti`nin
   `KADEME_AD` tablosu bir ekranda hiç yoktu. Tek kaynak bunu yapısal olarak kapatır.

   SIRA (üçünde de aynı):
     ① görsel/logo — TAM ORTADA, boyu sabit
     ② kaynak adı  — şirket: kendi adı (bir kademe büyük) · ilan: veren şirket
                     · eğitim: sağlayıcı
     ⑥ birincil eylem (yalnız şirket: "Takip Et") — ortalı, TAM GENİŞLİK DEĞİL
     ③ ana başlık  — BELİRGİN mesafeyle. ⛔ Şirkette BİLEREK BOŞ, adı ②'de.
     ④ bilgi ızgarası — 3 sütun

   ⚠️ Efe'nin ilkesi: *"1e1 aynı sayfa olamaz; öğeler hep aynı olabilir."*
     Bir slotun boş kalması eksik değil, kuralın kendisi.
   ========================================================================== */
.nx-detay-bas {
  padding: var(--nx-space-lg) var(--nx-kart-dolgu-yatay) var(--nx-space-md);
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
.nx-detay-bas__kaynak {
  margin: var(--nx-space-sm) 0 0;
  font-size: var(--nx-fs-govde); font-weight: var(--nx-fw-semibold);
  color: var(--nx-text); line-height: var(--nx-lh-tight);
}
/* Şirket sayfasında bu satır SAYFANIN ADI olduğu için bir kademe büyür. */
.nx-detay-bas__kaynak--ana {
  font-size: var(--nx-fs-baslik-sm); font-weight: var(--nx-fw-bold);
}
/* ⭐ Efe: *"tüm sayfa genişliğinde olmasın, ortalanmış ideal bir boyut olmalı."* */
.nx-detay-bas__eylem { margin-top: var(--nx-space-md); }
.nx-detay-bas__eylem .nx-btn { min-inline-size: 168px; }
/* ⭐ *"belirgin mesafe"* — kaynak ile ana başlık birbirine yapışmasın
   (Efe: *"üst kısımdaki başlık ve bilgi satırları iç içe gibiler, ferahlat"*). */
/* ⛔ SEÇİCİ NEDEN KAP ÖNEKLİ (0,2,0) — 16 Ağu 2026, ölçümle öğrenildi:
   çıplak `.nx-detay-bas__ad` (0,1,0) yazılmıştı ve ekranların KENDİ eski
   sınıfları (`il-bas__rol` · `eg-bas__ad` · `sr-bas__ad`, hepsi `margin: 0`)
   aynı özgüllükte + ekran `<style>`ı sonra yüklendiği için KAZANIYORDU.
   Sonuç: Efe'nin *"belirgin mesafe"* şartı sessizce düştü — ölçüldü,
   `margin-top: 0px`, kaynak ile başlık arası **0px**. Bu, `HATALARIM.md` §33'ün
   birebir tekrarıydı; önek onu yapısal olarak imkânsız kılar. */
.nx-detay-bas .nx-detay-bas__ad {
  margin: var(--nx-space-xl) 0 0;
  font-size: var(--nx-fs-baslik-sm); font-weight: var(--nx-fw-bold);
  line-height: var(--nx-lh-tight); color: var(--nx-text);
  text-wrap: balance;
}
/* Kaynak satırı da aynı korumayı alır — aynı tuzağın komşusu. */
.nx-detay-bas .nx-detay-bas__kaynak { margin: var(--nx-space-sm) 0 0; }

/* ⭐⭐ IZGARA YUVASI — Efe, 16 Ağu 2026: *"tüm matrisler aynı düzende olmalı,
   hepsi aynı ölçülerde olmalı."*
   🔴 ÖLÇÜLDÜ, ÜÇÜ FARKLIYDI: ilan **277,8** · şirket **359** · eğitim **222,2px**.
   SEBEP: `.nx-detay-bas` bir `flex-direction: column` kabı ve `align-items:
   center` taşıyor ⇒ çocuklar çapraz eksende BÜZÜLÜYOR (shrink-to-fit). Izgarayı
   saran yuva da büzülünce içindeki `inline-size: 100%` **yuvanın içerik
   genişliğine** çözülüyordu ⇒ her sayfada kendi metnine göre başka bir ölçü.
   ⇒ Yuva `stretch` alır; ızgara artık sayfanın içerik genişliğine oturur ve üç
     ekranda BİREBİR aynı olur. (Görsel/başlık ortalı kalmaya devam eder.) */
.nx-detay-bas__bilgi { align-self: stretch; inline-size: 100%; }

.nx-detay-bilgi {
  margin: var(--nx-space-lg) 0 0;
  inline-size: 100%;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--nx-space-md) var(--nx-space-sm);
}
/* Hücre bir DÜĞME (baloncuk için) ama görünüşü düz metin: kutu/kenar verilmez,
   ızgaranın sakin ritmi bozulmasın. */
.nx-detay-bilgi__h {
  min-inline-size: 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font: inherit; color: inherit; text-align: center;
  background: none; border: 0; padding: 4px 2px; cursor: pointer;
  border-radius: var(--nx-radius-sm);
}
.nx-detay-bilgi__h:focus-visible { outline: 2px solid var(--nx-accent-on);
                                   outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .nx-detay-bilgi__h:hover .nx-detay-bilgi__ikon { color: var(--nx-text); }
}
.nx-detay-bilgi__ikon { color: var(--nx-muted); display: inline-flex; }
.nx-detay-bilgi__ikon .nx-icon { width: var(--nx-ikon-xs); height: var(--nx-ikon-xs); }
/* ⛔ `display: none` DEĞİL — etiket görsel olarak yok ama ekran okuyucu değeri
   etiketsiz okumamalı ("İstanbul" tek başına ne demek?). Projenin sr-only kalıbı. */
.nx-detay-bilgi__et {
  position: absolute; inline-size: 1px; block-size: 1px;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
.nx-detay-bilgi__dg {
  font-size: var(--nx-fs-govde); font-weight: var(--nx-fw-semibold);
  line-height: var(--nx-lh-tight); color: var(--nx-text);
  overflow-wrap: anywhere;
  /* 🔴 `min-block-size: 2lh` GERİ ALINDI — Efe, 16 Ağu 2026: *"eşitleme
     saçmalığını da geri al."*
     NEYDİ: üç ızgaranın BOYUNU da eşitlemek için her değere iki satırlık taban
     verilmişti (şirket 118,3 ↔ diğerleri 102,2 ayrışıyordu). Bedeli: tek
     satırlık her değer boş bir satır kadar yer ayırıyor, ızgara 134,4'e şişiyordu.
     ⇒ Hücre yine içeriği kadar. Genişlik eşitliği (359px) DURUYOR — sorun
       oradaki değil, dikeyde zorlamalı eşitlemedeydi. */
}
/* Hazır bir bileşen (ör. `%uyum` pill'i) taşıyan hücre — Efe: *"%uyum her
   zamanki gibi renkli pill olarak kalacak."* */
.nx-detay-bilgi__h--oge {
  display: flex; align-items: center; justify-content: center;
  cursor: default;
}

/* ==========================================================================
   REKLAM DÜRÜSTLÜK ETİKETİ — .nx-reklam-etiket
   ⚠️ Reklamın kendi metnine GÖMÜLMEZ, ayrı bir işaret olarak durur.
   ========================================================================== */
.nx-reklam-etiket {
  font-size: var(--nx-fs-caption); color: var(--nx-muted);
  text-transform: uppercase; letter-spacing: .06em;
  font-weight: var(--nx-fw-semibold);
  white-space: nowrap;
}

/* ==========================================================================
   ŞİRKET KARTI — .nx-sirket-kart   (sisteme alındı 6 Ağu 2026, aynı gün
   İKİ VARYANTA AYRILDI — Efe düzeltmesi)

   ⭐ EFE DÜZELTMESİ (6 Ağu): "Şirket arama sayfasındaki kartlar aslında ilan ile
   AYNI BOY olacaklar; bu kartlar sadece KEŞFET'e özel olarak küçüktü."
   ⇒ Kompakt tile, listelerin kalıbı DEĞİL — Keşfet hub'ına özel bir İSTİSNA.
     Bu yüzden GENİŞ hâl VARSAYILAN, kompakt hâl MODİFİER oldu.
     (Tersi yazılsaydı üç liste ekranı da istisnayı miras alırdı.)

   ┌─ VARSAYILAN (geniş) ─ liste ekranları: tam genişlik satır, ilan kartıyla
   │  aynı kap · logo + ad + puan + sektör/konum + açık ilan sayısı
   └─ `--kompakt` ─ YALNIZ KEŞFET: 2 sütunlu ızgarada dar tile (175,5 × 94,3)

   🔴 KAP <article> (6 Ağu — yukarıdaki uyarı GERÇEKLEŞTİ, aynı gün):
   Efe yıldızı tıklanabilir yaptı ("yıldıza basınca yorumlar çıkmalı"), yani
   kartın içine ikinci bir etkileşimli öğe girdi ⇒ kart <a> KALAMAZDI
   (iç içe etkileşimli içerik). İlan kartıyla aynı yol: <article> + gerilmiş
   bağlantı, yıldız onun üstünde ayrı katman.
   ⇒ İki kart da artık AYNI yapısal sözleşmede: kap <article>, hedef başlıktaki
     bağlantı, ikincil eylemler onun üstünde.
   ========================================================================== */
.nx-sirket-kart {
  /* 🔴 YEREL `--nx-kart-dolgu: 12px` BİLDİRİMİ KALDIRILDI (14 Ağu 2026).
     D31 token'ı `tokens.css` `:root`a çıkarmıştı ama bu iki kartta (şirket ve
     eğitim) yerel kopya kalmıştı — değeri aynı olduğu için hiç fark etmedi.
     D37'de kök değişince ortaya çıkacaktı: kök yatayı 8'e indirirken bu iki
     kart 12'de kalıp sessizce ayrışırdı. Tek kaynak artık gerçekten tek. */
  min-height: 0; overflow: hidden;
  background: var(--nx-surface-2);
  /* ⚠️ ASPECT-RATIO KULLANILMAZ — bu kartta YANLIŞ ARAÇ (canlı ölçümle elendi).
     Yükseklik LOGO + METİNden gelir, ikisi de kart genişliğiyle büyümez; sabit
     oranla iki uçta da kırılıyordu (dar ekranda taşma, geniş ekranda absürt boy). */
  display: flex; flex-direction: row; align-items: center;
  gap: var(--nx-space-md);      /* geniş hâlde ilan kartıyla aynı: 16px */
  text-align: left;
  text-decoration: none;
  position: relative;           /* gerilmiş bağlantının çapası */
}
/* Gerilmiş bağlantı — ilan kartıyla aynı sözleşme. */
.nx-sirket-kart__baglanti { color: inherit; text-decoration: none; }
.nx-sirket-kart__baglanti::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.nx-sirket-kart:has(.nx-sirket-kart__baglanti:focus-visible) {
  outline: 2px solid var(--nx-accent-on); outline-offset: 3px;
}
/* 🔴 YÜKLEME SIRASI: `mobile.css`teki `.nx-card { padding: 16px }` bu kuraldan
   SONRA geliyor ve aynı özgüllükte (0,1,0) — dolgu sessizce 16'ya çıkardı.
   İlan kartında ölçülen aynı tuzak (bkz. §İLAN KARTI). */
.nx-card.nx-sirket-kart { padding: var(--nx-kart-dolgu) var(--nx-kart-dolgu-yatay); }

.nx-sirket-kart__govde { flex: 1; min-width: 0; display: flex; flex-direction: column;
                         gap: var(--nx-space-sm); }
/* Üst satır: ad (esner) + puan (sabit). Yalnız GENİŞ hâlde kullanılır. */
.nx-sirket-kart__ust { display: flex; align-items: flex-start;
                       gap: var(--nx-space-sm); width: 100%; min-width: 0; }
.nx-sirket-kart__ad {
  margin: 0; flex: 1; min-width: 0;
  font-size: var(--nx-fs-body-md); font-weight: var(--nx-fw-semibold);
  line-height: var(--nx-lh-tight);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  /* ⛔ A6 KAPANDI (14 Ağu) — D22 tabanı eksikti: tavan (`line-clamp: 2`) vardı,
     taban yoktu. Bugün patlamıyordu çünkü `tum_sirketler`in 20 kaydının
     hepsinin adı TESADÜFEN iki satıra taşıyor (ölçüldü: 20 kart da 89,1px).
     ⚠️ Bu, `.nx-egitim-kart__ad`ın 13 Ağu'da patlamasıyla AYNI kusur: orada da
       eşitlik tesadüfendi, punto 16→14'e inince kısa başlıklar tek satıra
       düştü ve 16px'lik ayrışma ölçüldü. Aynı tuzağın ikinci örneği. */
  min-height: 2lh;
}
/* Sektör · konum — ilan kartının "neden" yuvasının karşılığı. */
.nx-sirket-kart__ozet {
  font-size: var(--nx-fs-caption); color: var(--nx-text); line-height: 1.4;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  min-height: 2lh;   /* A6 — gerekçe yukarıda */
}
/* Alt satır: açık ilan sayısı SOLDA, çalışan sayısı SAĞDA. */
.nx-sirket-kart__alt { display: flex; align-items: baseline;
                       justify-content: space-between;
                       gap: var(--nx-space-sm); width: 100%; min-width: 0; }
.nx-sirket-kart__metin {
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
}
/* ⭐ PUAN ARTIK BİR DENETİM — yorumları açar (Efe, 6 Ağu 2026)
   Efe: "yıldıza basınca bir de yorumlar çıkmalı; kullanıcı anonim yorumlarını
   okumak faydalı bir özelliğimiz."
   ⇒ Yıldız kartın bir SÜSÜ değil, kendi hedefi olan ikincil bir eylem.
   ⚠️ `z-index: 1` + `position: relative`: gerilmiş bağlantının ÜSTÜNDE kalmalı,
     yoksa yıldıza dokunmak şirket sayfasını açardı.
   ⭐⭐ NEGATİF DIŞ BOŞLUK KALDIRILDI — D46 (Efe, 15 Ağu 2026).
     Eski satır: `margin-block: calc(var(--nx-tap-min) / -2 + 0.6em);`
     ve yanındaki yorum *"kart boyu DEĞİŞMİYOR"* diyordu — doğruydu, sorun oydu.
     📏 Ölçüldü: dokunulan alan görünenin **3,35-3,41 katı** (kutu 44×44,
        içerik 36×16). Kart 122 → 133,8 (geniş) · 93 → 120,8 (Keşfet kompakt).

   ⚠️ BU ÖĞE BİR GÖSTERGE DEĞİL, DENETİM — 15 Ağu'da ölçümle doğrulandı.
     11 Ağu notu *"yıldız+puan bir gösterge, işlevi yok"* diyordu ve bu öğe için
     YANLIŞTI: `tum_sirketler`de `yorumlariAc()` ile tam çalışan yorum çekmecesi
     açıyor (özet + yıldız kırılımı + filtre çipleri), `kesfet`te aynı hizada
     `data-yakinda` ile bağlı. Erişilebilir adı da *"…puan X, yorumları oku"*.
     ⇒ Baloncuk kapsamına GİRMEZ. Gerçek gösterge, eğitim kartındaki
       `.nx-egitim-kart__puan` (`<span>`, işlevi yok) — o baloncuk alır. */
.nx-sirket-kart__puan {
  flex: 0 0 auto; position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: flex-end;
  gap: var(--nx-space-xs);
  min-height: var(--nx-tap-min); min-width: var(--nx-tap-min);
  /* ⛔ D46 GERİ ALINDI (Efe, 16 Ağu) — negatif kenar geri kondu. Dokunma hedefi
     44px kalır ama satıra yalnız metin yüksekliği kadar katılır; kart boyu
     değişmez. Gerekçe ve geri alma kaydı §.nx-kart-kaydet blogunda. */
  margin-block: calc(var(--nx-tap-min) / -2 + 0.6em);
  padding-inline: var(--nx-space-xs);
  background: none; border: 0; cursor: pointer;
  font-family: var(--nx-font);
  font-size: var(--nx-fs-caption); color: var(--nx-muted);
  border-radius: var(--nx-radius-full);
  transition: color var(--nx-dur-fast) var(--nx-ease);
}
@media (hover: hover) and (pointer: fine) {
  .nx-sirket-kart__puan:hover { color: var(--nx-text); }
}
.nx-sirket-kart__puan:focus-visible { outline: 2px solid var(--nx-accent-on);
                                      outline-offset: -2px; }
/* ⚠️ Boy SARMALAYICIYA değil SVG'NİN KENDİSİNE de yazılır: sarmalayıcı 16px
   kalıp SVG 24px'te kaldığında yıldız kabından 8px TAŞIYORDU (Keşfet F4). */
.nx-sirket-kart :is(.nx-sirket-kart__puan, .nx-sirket-kart__alt) :is(.nx-ico, .nx-icon) {
  width: var(--nx-ikon-xs); height: var(--nx-ikon-xs);
}

/* ══════════════ --kompakt · YALNIZ KEŞFET HUB'I ══════════════
   2 sütunlu ızgarada dar tile. ÖLÇÜ SÖZLEŞMESİ (375px): 175,5 × 94,3.
   ⚠️ Yatay aralık 12px'e DÜŞER: tile yalnız ~175px geniş, 16 metni boğuyor.
   ⚠️ Ad yuvası `2lh` SABİT ve metin yuvanın İÇİNDE dikey ortalı (Efe: "şirket
     isimlerini dikeyde logoya ortala") — tek satırlık adlar yuvanın üstüne
     yapışıyordu. `lh` KAPTAN değil öğenin kendi font-size'ından hesaplanır,
     o yüzden punto `__adkap`ta da yazılı. */
/* ⛔⛔ D47 GERİ ALINDI — Efe, 16 Ağu 2026. D46 geri alınınca bu tabanın
   dayanağı da kalktı: şirket tile'ı 120,8'e çıktığı için eğitim tile'ı da
   ona eşitlenmişti. D46 geri gelince ikisi de kendi doğal boylarına döndü
   (93 ↔ 102,8) ve 15 Ağu'daki 18px'lik ritim farkı da ORTADAN KALKTI —
   fark zaten D46'nın ürünüydü, D47 onun yamasıydı.
   📌 Silinen kural: `.nx-card.*--kompakt { min-block-size: calc(2*dolgu +
     2*(fs-body-sm*lh-body) + space-sm + tap-min) }` = 120,8px.
     Türetme aritmetiği doğruydu (Codex doğruladı); geri alınma sebebi
     yanlışlığı değil, dayandığı kararın kalkması. */
.nx-sirket-kart--kompakt { gap: var(--nx-kart-dolgu); }
.nx-sirket-kart--kompakt .nx-sirket-kart__adkap {
  flex: 1; min-width: 0;
  font-size: var(--nx-fs-body-sm);
  min-height: 2lh;
  display: flex; align-items: center;
}
.nx-sirket-kart--kompakt .nx-sirket-kart__ad {
  width: 100%; font-size: inherit; font-weight: var(--nx-fw-semibold);
  line-height: normal;
}
/* Kompaktta meta kartın DİBİNE yapışır: ilan sayısı solda, puan sağda (Efe). */
.nx-sirket-kart--kompakt .nx-sirket-kart__meta {
  width: 100%; min-width: 0; margin-top: auto;
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--nx-space-xs);
}
.nx-sirket-kart--kompakt .nx-sirket-kart__meta :is(.nx-ico, .nx-icon) {
  width: var(--nx-ikon-xs); height: var(--nx-ikon-xs);
}

/* ==========================================================================
   İKİ SÜTUNLU KART IZGARASI — .nx-kart-izgara
   Şirket · eğitim · sertifika kartlarının listelendiği ızgara.
   ⛔ `auto-fill` KULLANILMAZ: geniş ekranda 3+ sütun üretip iki-sütun niyetini
     bozuyor (Codex bulgusu). React Native karşılığı `FlatList numColumns={2}`.
   ⚠️ `minmax(0, 1fr)`: ızgara öğesinin `min-width` varsayılanı `auto`dur ve öğe
     min-content'in altına inmez — uzun bir ad ızgarayı kaba taşırır. Bu, ilan
     listesinde canlı ölçülen 97px'lik taşmanın aynısıdır.
   ========================================================================== */
.nx-kart-izgara {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--nx-space-sm);
}

/* ==========================================================================
   EĞİTİM / SERTİFİKA KARTI — .nx-egitim-kart   (sisteme alındı 6 Ağu 2026)

   ⭐ EFE KARARI (6 Ağu): *"kartların boyu aynı olacak (ilan ve şirket ile aynı)
   ama zaten tüm içerik ayrıştırılabilir olup üzerinde olsun dediğim kurala göre
   bunun üzerindeki kısım önerdiğin gibi olabilir."*
   ⇒ KAP ilan/şirket kartıyla aynı (tam genişlik satır, yükseklik içerikten);
     ÜSTÜNE BİNEN katman — kapak görseli yuvası + metin düzeni — kendi işini yapar.
   Şirket kartıyla birebir aynı yön: **geniş VARSAYILAN, kompakt MODİFİER**.

   ┌─ VARSAYILAN (geniş) ─ Tüm eğitimler / Tüm sertifikalar: tam genişlik satır ·
   │  kapak yuvası + ad + sağlayıcı + seviye/format + süre + ücret rozeti
   └─ `--kompakt` ─ YALNIZ KEŞFET HUB'I: 2 sütunlu ızgarada dar tile (175,5 × 99,3)

   ⚠️ TEK BİLEŞEN, İKİ İÇERİK: eğitim ve sertifika kartı BİREBİR aynı bileşendir
   (spec §8 "tek kalıp, iki içerik"). Ayrımı bölüm başlığı ve içerik taşır, kart
   değil — Keşfet'te de böyle çalışıyordu.

   🔴 KAP <article> + GERİLMİŞ BAĞLANTI — ilk günden, sonradan değil.
   İlan ve şirket kartı bu yola SONRADAN girdi ve ikisinde de aynı sebeple:
   karta ikinci bir etkileşimli öğe (kaydet / yıldız) girince <a> geçersiz oldu
   (iç içe etkileşimli içerik). Bu kartta bugün ikincil eylem YOK, ama
   *"kaydet bu kart türlerine de gelecek mi?"* açık bir soru (DEVIR §Tur 3).
   Aynı düzeltmeyi üçüncü kez yapmamak için kap baştan <article>.
   ⇒ Üç kart da artık AYNI yapısal sözleşmede.
   ========================================================================== */
.nx-egitim-kart {
  /* 🔴 Yerel `--nx-kart-dolgu` bildirimi kaldırıldı — gerekçe §ŞİRKET KARTI. */
  min-height: 0; overflow: hidden;
  background: var(--nx-surface-2);
  display: flex; flex-direction: row; align-items: center;
  gap: var(--nx-space-md);       /* geniş hâlde ilan/şirket kartıyla aynı: 16px */
  text-align: left; text-decoration: none;
  position: relative;            /* gerilmiş bağlantının çapası */
}
/* 🔴 YÜKLEME SIRASI: `mobile.css`teki `.nx-card { padding: 16px }` bu kuraldan
   SONRA geliyor ve aynı özgüllükte (0,1,0). İki kardeş kartta da ölçülen tuzak. */
.nx-card.nx-egitim-kart { padding: var(--nx-kart-dolgu) var(--nx-kart-dolgu-yatay); }

.nx-egitim-kart__baglanti { color: inherit; text-decoration: none; }
.nx-egitim-kart__baglanti::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.nx-egitim-kart:has(.nx-egitim-kart__baglanti:focus-visible) {
  outline: 2px solid var(--nx-accent-on); outline-offset: 3px;
}

/* ⭐ KAPAK GÖRSELİ YUVASI — bugün tür ikonu, yarın gerçek kapak.
   Efe'nin ileriye dönük tarifi (spec §6): *"ileride arkada fotoğraf olur, üstünde
   eğitimin adı, altında sağlayıcının adı."* Yuva BUGÜNDEN ayrı bir eleman ki
   görsel geldiğinde başlık ve sağlayıcı satırı yerinde kalsın, iskelet değişmesin.
   ⚠️ Boy merdivenden (`--nx-avatar-lg` = 72px) — literal px yazılmaz, `--nx-nesne-olcek`
     knob'u buraya da ulaşır (CLAUDE.md §Ölçeklenebilirlik).
   ⚠️ 4:3 — logo kutusunun karesinden bilerek AYRI: bu bir marka işareti değil,
     bir içerik görseli; kapak görselleri kare değil yatay gelir. */
.nx-egitim-kart__gorsel {
  flex: 0 0 auto;
  width: var(--nx-avatar-lg); aspect-ratio: 4 / 3;
  display: grid; place-items: center;
  overflow: hidden;
  border-radius: var(--nx-radius-sm);
  background: var(--nx-surface-3);
  color: var(--nx-accent-on);
}
.nx-egitim-kart__gorsel img { width: 100%; height: 100%; object-fit: cover; display: block; }

.nx-egitim-kart__govde { flex: 1; min-width: 0; display: flex; flex-direction: column;
                         gap: var(--nx-space-xs); }
/* Üst satır: ad (esner) + ücret rozeti (sabit). Yalnız GENİŞ hâlde. */
.nx-egitim-kart__ust { display: flex; align-items: flex-start;
                       gap: var(--nx-space-sm); width: 100%; min-width: 0; }
.nx-egitim-kart__ad {
  margin: 0; flex: 1; min-width: 0;
  font-size: var(--nx-fs-body-md); font-weight: var(--nx-fw-semibold);
  line-height: var(--nx-lh-tight);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  /* ⛔ D22 TABANI (13 Ağu 2026) — tavan (`line-clamp:2`) TEK BAŞINA YETMEZ.
     Eskiden burada taban yoktu ve eşitlik TESADÜFEN sağlanıyordu: punto
     büyükken her başlık zaten 2 satıra taşıyordu. Punto reformu 16→14'e
     inince kısa başlıklar 1 satıra düştü, uzunlar 2'de kaldı ⇒ `tum_egitimler`
     ve `tum_sertifikalar`da 16px'lik (tam bir satır) eşitsizlik ÖLÇÜLDÜ.
     📌 `--kompakt` varyantında bu taban zaten vardı (aşağıda) — yani kural
        biliniyordu, liste varyantına yazılmamıştı.
     ⚠️ `lh` ÖĞENİN KENDİ font-size'ından hesaplanır; punto bu kuralda yazılı
        olduğu için taban punto değişirse birlikte kayar. */
  min-height: 2lh;
}
/* Kaynak satırı: sağlayıcı SOLDA (esner), puan SAĞDA (sabit).
   Spec §8 eğitim/sertifika üst bloğunda "sağlayıcı + puan" birlikte anılıyor;
   kartta da birlikte duruyorlar ki listeden detaya geçiş tutarlı olsun. */
.nx-egitim-kart__kaynak { display: flex; align-items: baseline;
                          gap: var(--nx-space-sm); width: 100%; min-width: 0; }
/* Sağlayıcı — geniş hâlde KIRPILMADAN okunur (dar tile'da "İTÜ Sür…" oluyordu,
   bu kartın liste hâline geçmesinin somut kazancı budur). */
.nx-egitim-kart__saglayici {
  flex: 1;
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--nx-fs-caption); color: var(--nx-text); line-height: 1.35;
}
/* ⚠️ PUAN BURADA BİR DÜĞME DEĞİL — şirket kartındakinin aksine. Orada yıldız
   yorumları açıyor (Efe, 6 Ağu); eğitimde okunacak bir yorum akışı YOK, o yüzden
   hedef de verilmiyor. Tıklanamayan bir şeyi düğmeye benzetmek yalan söyler.
   ⚠️ SEMANTİK RENK KURALI (E1): yıldız renkli değil; nötr, doluluk `fill`'den. */
.nx-egitim-kart__puan {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--nx-space-xs);
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
  font-variant-numeric: tabular-nums;
}
.nx-egitim-kart__puan .nx-icon path,
.nx-egitim-kart__puan .nx-icon polygon { fill: currentColor; }
.nx-egitim-kart :is(.nx-egitim-kart__puan) :is(.nx-ico, .nx-icon) {
  width: var(--nx-ikon-xs); height: var(--nx-ikon-xs);
}
/* Ücret rozeti — üst satırın sağında, adın yanında. "Ücretsiz" bir SATIŞ
   argümanı, meta bilgi değil; alt satıra gömülmüyor. */
.nx-egitim-kart__ucret {
  flex: 0 0 auto;
  font-size: var(--nx-fs-caption); font-weight: var(--nx-fw-semibold);
  line-height: 1.35; color: var(--nx-text); white-space: nowrap;
}
/* Alt satır: seviye · format SOLDA, süre SAĞDA — şirket kartının alt satırıyla
   aynı kalıp, o da ilan kartından türemişti. */
.nx-egitim-kart__alt { display: flex; align-items: baseline;
                       justify-content: space-between;
                       gap: var(--nx-space-sm); width: 100%; min-width: 0; }
.nx-egitim-kart__metin {
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
}
.nx-egitim-kart__sure {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--nx-space-xs);
  font-size: var(--nx-fs-caption); color: var(--nx-muted); line-height: 1.35;
}
.nx-egitim-kart :is(.nx-egitim-kart__sure, .nx-egitim-kart__alt) :is(.nx-ico, .nx-icon) {
  width: var(--nx-ikon-xs); height: var(--nx-ikon-xs);
}

/* ══════════════ --kompakt · YALNIZ KEŞFET HUB'I ══════════════
   ÖLÇÜ SÖZLEŞMESİ (375px): 175,5 × 99,3. Keşfet'in görünüşü DEĞİŞMEZ; kural
   artık kendi dosyasından değil buradan geliyor.

   ⭐ Efe'nin 4 Ağu'da bu tile'a verdiği üç karar aynen korunuyor:
   ① ORAN KİLİDİ YOK — yükseklik içerikten. (*"kartların içindeki gereksiz
      boşluklar çok alan öldürüyor"*; oran kilidiyle içerideki boşluğu kısmak
      kartı KÜÇÜLTMEZ, ölü alanı sadece alta kaydırır.)
   ② KART İÇİ TÜR İKONU YOK — *"kartlar zaten aynı gruba ait olduğu için ikonun
      tekrar tekrar gözükmesine gerek yok"*; ikon bölüm başlığında. ⇒ kompaktta
      kapak yuvası BASILMAZ.
   ③ SÜRE KARTIN DİBİNE YAPIŞIR — *"diğerlerinden daha yukarıda duruyor, hepsi
      eşit olacak"*; sağlayıcısı olmayan kartta süre yukarı kayıyordu.
   ⚠️ Ad yuvası `2lh` SABİT → metin karta boy değiştiremez, ızgara satırındaki
     kartlar eşit kalır. `lh` KAPTAN değil öğenin kendi font-size'ından hesaplanır,
     o yüzden punto öğenin üstünde yazılı (F2'nin ölçülmüş tuzağı). */
.nx-egitim-kart--kompakt {
  flex-direction: column; align-items: stretch; justify-content: center;
  gap: var(--nx-space-xs);
}
.nx-egitim-kart--kompakt .nx-egitim-kart__gorsel { display: none; }
.nx-egitim-kart--kompakt .nx-egitim-kart__govde { flex: 1; gap: var(--nx-space-xs); }
.nx-egitim-kart--kompakt .nx-egitim-kart__ad {
  font-size: var(--nx-fs-body-sm); min-height: 2lh;
}
/* Dar tile'da sağlayıcı ile süre AYNI satıra sığmıyor — kart ~163px geniş, dolgu
   ve süre düşünce sağlayıcıya ~65px kalıyor ve "İTÜ Sürekli Eğitim Merkezi"
   okunmaz hâle geliyordu (ölçüldü). ⇒ Sağlayıcı kendi satırında, süre kendi
   satırında sağa yaslı. Geniş hâlde bu sorun yok, orada ikisi yan yana. */
/* ⛔ İÇİ BOŞ OLSA BİLE SATIR YÜKSEKLİĞİNİ KORUR (14 Ağu, D22).
   Boş bir `<span>`ın yüksekliği 0'dır; yuva basılıp taban verilmeseydi
   ölçülen 3px'lik ayrışma aynen kalırdı — yalnız DOM'da görünür olurdu. */
.nx-egitim-kart--kompakt .nx-egitim-kart__saglayici { flex: 1; min-block-size: 1lh; }
.nx-egitim-kart--kompakt .nx-egitim-kart__alt {
  margin-top: auto; justify-content: flex-end; min-block-size: 1lh;
}

/* ==========================================================================
   ⭐ AÇIK TEMADA LİME KİMLİK — "K2" ÇİPİ   (Efe kararı, 6 Ağu 2026)

   Efe: *"sayfalarda açık temada neredeyse hiç lime öğemiz bulunmuyor; bazı
   yıldızları ikonları lime yapalım ki kimliğimiz açık temada da belli olsun."*
   → sonra: *"bence hepsi K2 olmalı… ayna kuralı her ikisinde de devam etsin,
   koyuda da açıkta koyacağımız kadar lime olsun koyu kuralıyla."*

   ⛔ ÖNCE ÖLÇÜLDÜ, SONRA YAZILDI. Ham lime ikon açık zeminde GÖRÜNMÜYOR:
      lime/sayfa #F0EDE6 = 1.16 · lime/kart #E7E3DA = 1.06 · lime/kapak = 1.06.
      Sebep: lime'ın bağıl parlaklığı .724, yani lime ≈ #DDDDDD gri kadar AÇIK.
      ⇒ Zemini bir tık koyulaştırmak kontrastı DÜŞÜRÜR (Efe'nin hipotezi ölçümle
      elendi); 3:1 için zemin ≤ #7D7D7D olmalı. Açık temada öyle bir yüzey yok.
   ⇒ Tek çalışan yol: lime'ı DOLGU yapıp üstündeki ikonu ink'e almak. Bu zaten
      31 Tem DOLGU KURALI'nın kendisi — burada ikon ölçeğine iniyor.

   ⭐ AYNA KURALI KORUNUYOR, TEK KURALLA: `--nx-dolgu` iki temada da lime,
      `--nx-glow-md` koyuda DIŞA lime / açıkta İÇE ink. Tema başına ayrı kural YOK.
      Ölçüldü: ikon/dolgu 14.60:1 (iki temada da) · çipin dış kenarı açık 1.06 ·
      koyu 13.59. Açıktaki 1.06 bilinerek kabul edilen bedel — %uyum rozetiyle
      aynı sınıf (31 Tem kararı).

   ⭐ İKİ DAVRANIŞ AİLESİ (Efe):
     ① ETKİLEŞİMLİ — kullanıcı durumu değiştirir (kaydet).
        Kaydedilmemiş: bugünkü NÖTR ikon, çip YOK. Basınca: lime çip + dolu ink ikon.
        ⇒ "Okuma B" (Efe seçti). Gerekçesi ölçülmüş: çip her zaman dursaydı
          20 kartlık listede ~40 lime çip olurdu ve kaydedilmiş/kaydedilmemiş
          ayrımı okunmazdı (ikisi de aynı lime daire). B'de kaydedilen kart
          kendiliğinden öne çıkıyor ve lime "burada bir şey var" anlamını koruyor.
     ② GÖSTERİM — tıklayınca BAŞKALARININ verdiğini açar (puan yıldızı).
        BAŞTAN dolu lime çip. Kullanıcı buradan puan VERMEZ.

   ⛔ KAPSAM: yalnız bookmark + yıldız. Süre/konum/meta ikonları DIŞARIDA —
      yoğunluk endişesi Efe tarafından bu iki ikona daraltılarak çözüldü.

   ⚠️⚠️ MARKUP DEĞİŞMİYOR — beş ekranın hiçbirine dokunulmuyor. Çip, mevcut
     kutuların İÇİNE (`.nx-ico`) ya da ARKASINA (`::before`) çiziliyor.
   ⚠️⚠️ KART BOYU DEĞİŞMEZ: iki host da ZATEN 44px hedef + simetrik negatif
     boşluk taşıyor. Çip görsel katman olduğu için kutu ölçüsüne dokunmuyor.
     (Taslakta çipi kutunun KENDİSİNE vermek kartı 97 → 108px yapmıştı.)
   ========================================================================== */

/* ── ① ETKİLEŞİMLİ: kaydet — yalnız BASILI hâlde çip ────────────────────── */
/* Çip, 44px hedefin İÇİNDEKİ `.nx-ico`ya biner: görsel küçük, hedef tam (§11.3).
   Kutunun kendisi büyümediği için üç kartın ölçü sözleşmesi korunuyor. */
.nx-kart-kaydet[aria-pressed="true"] .nx-ico {
  width: var(--nx-kontrol-cip); height: var(--nx-kontrol-cip);
  display: grid; place-items: center;
  border-radius: var(--nx-radius-full);
  background: var(--nx-dolgu);
  box-shadow: var(--nx-glow-md);
}
/* ⚠️ İkon çipten TAŞMASIN: `.nx-ico` artık 32px, SVG kendi boyunu korumalı.
   (Keşfet F4'ün tuzağı: boy yalnız sarmalayıcıya yazılınca SVG 24'te kalıp
   kabından taşıyordu — burada tersi lazım, SVG'ye açıkça yazılıyor.) */
.nx-kart-kaydet[aria-pressed="true"] .nx-ico :is(.nx-ico, .nx-icon),
.nx-kart-kaydet[aria-pressed="true"] .nx-icon {
  width: var(--nx-ikon-md); height: var(--nx-ikon-md);
}
/* 🔴 YAZI RENGİ `--nx-text` OLAMAZ: koyu temada kırık beyaz demek ve lime
   dolgu üstünde 1.16:1 ile KAYBOLUR. Dolgunun üstünde duran her işaret
   `--nx-dolgu-yazi`dır (checkbox tikinin 31 Tem'de yaşadığı hatanın aynısı). */
.nx-kart-kaydet[aria-pressed="true"] { color: var(--nx-dolgu-yazi); }
@media (hover: hover) and (pointer: fine) {
  /* Hover cevabı METİNDE değil DOLGUDA — sistemin hover sözleşmesi (accent buton). */
  .nx-kart-kaydet[aria-pressed="true"]:hover { color: var(--nx-dolgu-yazi); }
  .nx-kart-kaydet[aria-pressed="true"]:hover .nx-ico { background: var(--nx-dolgu-hover); }
}

/* ── ② GÖSTERİM: puan yıldızı — BAŞTAN dolu çip ────────────────────────── */
/* Şirket kartında `<button>` (yorumları açar), eğitim kartında `<span>`.
   İkisinde de çip bir `::before` KATMANI: kutu ölçüsüne dokunmaz, dolayısıyla
   şirket kartının 44px hedefi ve negatif boşluğu olduğu gibi kalır. */
/* 🔴 DÜZELTME (Efe, 6 Ağu — aynı oturum): *"Yıldızlar lime olmayacaktı."*
   İlk yazımda puan yıldızına da lime çip vermiştim; YANLIŞTI ve geri alındı.
   ⭐ DOĞRUSU: **lime YALNIZ kaydet'in BASILI hâlinde.** Lime, kullanıcının kendi
   EYLEMİNİ/DURUMUNU işaretler; puan yıldızı bir BİLGİ gösterimidir, marka aksanı
   değil. (Ayrıca `karar-semantik-renk` §E1 zaten *"yıldız renkli değil, nötr;
   doluluk `fill`'den gelir"* diyordu — lime çip o kararı da deliyordu.)
   ⇒ Yıldıza dair tek değişiklik: "dolu" görünmesi. Renk NÖTR kalıyor. */
/* Yıldız "baştan DOLU" (Efe): şirket kartındaki yıldız strok-only idi, gövdesi
   dolduruluyor. Eğitim kartındakinde bu kural ZATEN vardı — ikisi eşitlendi.
   ⛔ Ayrı bir "dolu yıldız" SVG'si ÜRETİLMEZ (ikon seti tek kaynak);
      kaydet düğmesinin `.bm` dolgusuyla birebir aynı yol. */
.nx-sirket-kart__puan .nx-icon :is(path, polygon) { fill: currentColor; }

/* ── ③ ODAK HALKASI — yalnız KAYDET dolgulandığı için o dışarı alındı ──── */
/* 🔴 GERÇEK HATA ÖNLENDİ: `.nx-kart-kaydet:focus-visible` `outline-offset: -2px`
   (İÇERİ) idi. Odak halkası `--nx-accent-on` kullanır ve o token KOYU temada
   LİME'dır ⇒ basılı hâlin lime çipinin İÇİNE çizilen lime halka GÖRÜNMEZ olurdu.
   Sistemin dolgulu denetimlerinde offset zaten POZİTİF (`.nx-btn` 3px ·
   `.nx-check` 2px · `.nx-chip` 2px) — halka dolgunun dışında, kart yüzeyinde yaşar.
   📌 `.nx-sirket-kart__puan` DOKUNULMADI: dolgusu olmadığı için -2px'i doğru. */
.nx-kart-kaydet:focus-visible { outline-offset: 2px; }

/* ── ④ ALT TAB BAR — aktif sekme lime dolgu + KAYAN gösterge ───────────────
   Efe, 6 Ağu 2026: *"bu lime dolguları seçili alt tab öğelerine de uygulayalım.
   ayrıca başka bir öğe seçildiğinde o öğeye kayarak geçsin."*

   🔴 BU, `CLAUDE.md`'DEKİ BİR İSTİSNAYI KAPATIYOR. Dolgu kuralı yazılırken
   *"aktif sekme metni/ikonu `--nx-accent-on`da KALIR; lime'a çevrilirse açık
   temada 1.16:1 ile görünmez olur"* denmişti. O gerekçe METNİ lime yapmaya
   dairdi. Burada yapılan bunun TERSİ: metin ink kalıyor, LİME ARKAYA geçiyor.
   ⇒ Ölçülen sonuç 1.16 değil **14.60:1** — istisnanın sebebi ortadan kalkıyor.
   ⚠️ `CLAUDE.md`'nin o satırı GÜNCELLENMELİ (master dosya ⇒ ONAY KURALI).
      Odak halkaları ve ikon aksanları istisnada KALMAYA devam ediyor.

   ⚠️ GÖSTERGE `::before` KATMANI, öğelerin kendisi değil: sekme kutularına
     dokunulmuyor ⇒ hap ölçüsü (327×65) ve etiket kırpma sözleşmesi korunuyor.
   ⚠️ GLOW `-ic` (inset) VARYANTI: `.nx-tabbar` `overflow: hidden` taşıyor
     (mobile.css) ve orada dışa glow KARE görünür — tokens.css'in kendi uyarısı.
   ⚠️ Konum px olarak JS'ten geliyor (`--nx-tab-x` · `--nx-tab-w`): sekme
     sayısı role göre değişiyor (öğrenci 4 · şirket 4) ve etiket genişlikleri
     eşit kalmayabilir. Yüzdeye gömülü bir varsayım sessizce kayardı.
   ⛔ ANİMASYON YALNIZ `transform` — `left`/`width` geçişi layout animasyonu
     olurdu (spec §13 yasağı). Genişlik geçişsiz atanır. */
.nx-tabbar { position: relative; }
.nx-tabbar::before {
  content: "";
  position: absolute; z-index: 0; pointer-events: none;
  /* ⭐ GÖSTERGE ÖĞENİN TAMAMINI KAPSAR — etiket DAHİL (Efe, 12 Ağu:
     "lime dolgu önceki gibi etiketi de içermeli, şu an içermediği için
     bütünlük sağlanamamış").
     ⛔ Aynı gün önce ikonun arkasına daraltılmıştı; canlıda bakılınca
        bütünlüğü bozduğu görüldü ve geri alındı. Stadyum biçimi korunuyor:
        hücre boyu enden kısa olduğu için kutu enine uzun kalır. */
  left: 0; top: var(--nx-space-xs); bottom: var(--nx-space-xs);
  width: var(--nx-tab-w, 0px);
  transform: translateX(var(--nx-tab-x, 0px));
  background: var(--nx-dolgu);
  border-radius: var(--nx-radius-full);
  /* Kademe `lg` (8px): gösterge canlı ölçüldü **70,8 × 54,8px** — iki ekseni de
     ≥40px, yani CLAUDE.md merdiveninin en üst basamağı. 7 Ağu denetimine kadar
     `md` (4px) yazıyordu; sekme HAPININ 65px boyuna değil, göstergenin kendi
     boyuna bakılmalıydı. `-ic` (inset) şart — bkz. yukarıdaki overflow uyarısı.

     ⛔ KOYU TEMADA BU GLOW GÖRÜNMEZ — HATA DEĞİL, EFE KARARI (7 Ağu 2026).
     `--nx-glow-lg-ic` koyu temada LİME'dır, dolgu da lime ⇒ inset glow tanım
     gereği **no-op**. Açık temada ink inset olduğu için orada çalışıyor.
     Denetimde soruldu, Efe: *"koyu temada gösterge glow'u olduğu gibi kalsın"*
     ⇒ koyu temada gösterge **düz lime hap** olarak durur, derinlik almaz.
     Görünür kılmanın tek yolu koyu temada da ink inset yazmaktı; o, Efe'nin
     onayladığı görünüşü değiştirirdi ve **bilerek yapılmadı.**
     📌 Bu, kuralın kendi içindeki bir boşluk: *"kırpan kapta her zaman inset"* +
     *"koyuda glow lime"* birleşince lime dolgulu her öğede glow anlamsızlaşıyor.
     Sonraki oturum bunu "düzeltme" — karar `Notes/karar-denetim-7agu-netlestirmeler.md` §⑤. */
  /* Kademe `lg` (8px): gösterge iki eksende de ≥40px — CLAUDE.md merdiveninin
     en üst basamağı. `-ic` (inset) ŞART: `.nx-tabbar` `overflow:hidden` taşıyor,
     dışa glow orada KARE görünür.
     📌 12 Ağu'da bir ara `md`ye (4px) indirilmişti, çünkü gösterge o sırada
        yalnız ikonun arkasındaydı (32px). Gösterge öğenin tamamına geri dönünce
        kademe de geri döndü — kademe ÖĞENİN BOYUNA bağlı, sabit bir tercih değil.
     📌 Koyu temada bu glow no-op (lime üstünde lime) — Efe kararı, 7 Ağu:
        "koyu temada gösterge glow'u olduğu gibi kalsın". */
  box-shadow: var(--nx-glow-lg-ic);
}
/* İlk boyamada KAYMA YOK: gösterge yerine oturduktan sonra geçiş açılır,
   yoksa sayfa her açılışta soldan içeri süzülürdü. */
/* ⭐ GENİŞLİK DE GEÇİŞLİ (Efe, 6 Ağu: *"yazıya göre boyut alsın"*) — gösterge
   artık her sekmede farklı genişlikte, geçişsiz bırakılsa kayarken ZIPLARDI.
   ⚠️ Bu, spec §13'ün layout-animasyon yasağına AYKIRI DEĞİL: yasak "sayfa
   AKIŞINDA" boy değiştirmeye dair (akordeon `height:auto` vakası). Burada öğe
   `position: absolute` bir sözde-öğe; hiçbir içeriği itmiyor, reflow üretmiyor.
   iOS/M3 tab göstergelerinin de standart davranışı budur. */
.nx-tabbar.is-gosterge-hazir::before {
  transition: transform var(--nx-dur-base) var(--nx-ease),
              width     var(--nx-dur-base) var(--nx-ease);
}
/* Sekmeler göstergenin ÜSTÜNDE kalmalı, yoksa lime dolgu yazıyı yutar. */
.nx-tabbar__item { position: relative; z-index: 1; }
/* ⭐ RENK GEÇİŞİ GÖSTERGEYLE EŞZAMANLI (Efe, 7 Ağu: *"animasyona göre ayarla"*).
   Gösterge `--nx-dur-base` ile kayıyor; yazı/ikon rengi geçişsiz bırakılsa dolgu
   daha oraya varmadan ink'e ZIPLARDI. Aynı süre + aynı eğri ⇒ dolgu ile renk
   birlikte varır. `color` geçişi layout üretmez (spec §13 kapsamı dışında). */
.nx-tabbar__item,
.nx-tabbar__item .nx-icon { transition: color var(--nx-dur-base) var(--nx-ease); }
@media (prefers-reduced-motion: reduce) {
  .nx-tabbar__item,
  .nx-tabbar__item .nx-icon { transition: none; }
}
/* 🔴 Dolgunun üstünde duran her işaret `--nx-dolgu-yazi` (ink) — `--nx-accent-on`
   DEĞİL: o token koyu temada lime'dır ve lime dolgu üstünde 1:1 ile kaybolur.

   📌 12 Ağu: bu kuralın kapsamı bir ara göstergenin içine daraltıldı, çünkü
      gösterge o sırada yalnız ikonun arkasındaydı ve etiket çıplak hap
      yüzeyine düşüyordu (orada ink metin koyu temada kayboluyordu, ölçüldü).
      Efe göstergeyi etiketi de kapsayacak şekilde geri aldı ("bütünlük
      sağlanamamış") ⇒ kapsam da geri geldi. Kural ÖĞENİN NEREDE DURDUĞUNA
      bağlı: dolgunun üstündeyse ink, çıplak yüzeydeyse normal metin. */
.nx-tabbar__item.is-active,
.nx-tabbar__item.is-active .nx-icon { color: var(--nx-dolgu-yazi); }
.nx-tabbar__item.is-active .nx-avatar { box-shadow: 0 0 0 2px var(--nx-dolgu-yazi); }
/* Odak halkası da aynı sebeple ink'e döner — YALNIZ aktif sekmede.
   Hap `overflow: hidden` olduğu için halka DIŞARI alınamıyor (kırpılırdı),
   o yüzden çözüm rengi değiştirmek. Pasif sekmeler `--nx-accent-on`da kalır.
   ⭐ 1 EKİ 2026 (Tur B L-94, taban töreni) — HALKA GÖSTERGENİN ÜSTÜNE ALINDI.
      Ölçüldü (kesfet 375 koyu): gösterge öğenin 4 px içinde, stadyum 44 px
      (yukarıdaki geometri: öğe 52 = 4 + H 44 + 4; içerik 8–44); içe −2 px halka
      öğenin kenarında ⇒ halkanın üst/alt kenarı tamamen, yanlarının yarısı
      göstergenin DIŞINDA, koyu çubukta: ink/koyu ≈ 1:1 (B3: 15 ekran). Ink yalnız
      dolgunun üstünde doğru renk ⇒ halka 4 px daha içe ve stadyum köşeli: bant
      4–6 px, dış kenarı göstergenin kenarına oturur (tamamı lime üstünde, 14,6:1),
      içerikle 2 px boşluk. ⚠️ İlk yazım −5 px idi: ölçüm çubuğun 1 px kenarlığını
      atlayıp göstergeyi 46 saymıştı ⇒ halkanın üst/alt 1 px'i yine dışarıdaydı. */
.nx-tabbar__item.is-active:focus-visible { outline-color: var(--nx-dolgu-yazi);
  outline-offset: -6px; border-radius: var(--nx-radius-full); }
@media (prefers-reduced-motion: reduce) {
  .nx-tabbar.is-gosterge-hazir::before { transition: none; }
}

/* ==========================================================================
   ⭐ PANEL — .nx-panel   (Efe kararı, 6 Ağu 2026 · "2. yol")

   Efe: *"Keşfet'teki Eğitimler, sertifikalar, ilanlar, şirketler bölümlerinin
   arkasına … geniş açık kartları getirelim. Bütün app kartlar üzerinde geziyor
   olsun, boş arkaplana dokunma olmasın gibi düşün."*

   🔴 NEDEN KART DEĞİL, PANEL: `components.css` §KART açıkça *"İç içe kart ASLA"*
   diyor. Keşfet'in bölümleri GERÇEK kart taşıyor (6 şirket · 6 ilan · 4 eğitim ·
   4 sertifika); bölümü `.nx-card` yapmak kart-içinde-kart olurdu.
   `profil`/`kimlik`te bu sorun yok — onlar kart değil SATIR (`.hub-satir`) taşıyor.
   ⇒ Panel bir GRUPLAMA yüzeyidir: kendi zemini + yarıçapı var, ama kart dilinin
     kimlik taşıyan iki parçasını (yüzen gölge `--nx-yuzen` + halka `--nx-ring`)
     TAŞIMAZ. Böylece "kart" olarak okunmaz, yasak delinmez.

   ⭐ YÜZEY SEÇİMİ ÖLÇÜMDEN GELDİ, seçilmedi:
     açık → sayfa #F0EDE6 · panel #E7E3DA · içindeki kart #DCD7CC
     koyu → sayfa #0A0A0A · panel #141414 · içindeki kart #1E1E1E
   Her iki temada da her kademe sayfadan BİR ADIM DAHA UZAK ⇒ ayna kuralı korunuyor
   (Efe, 6 Ağu: *"koyu ve açık tamamen aynalı olacak"*). `--nx-surface-2` zaten
   tokens.css'te *"sütun/panel"* diye adlandırılmış — yeni bir ton üretilmedi.

   ⚠️ İÇERİDEKİ KART BİR KADEME İLERLER: panel `--nx-surface-2`, liste kartları da
     `--nx-surface-2` (tür kuralları oraya çekiyor — ölçüldü). Dokunulmazsa kart
     panelde KAYBOLURDU (aynı renk). Kaydırma yalnız panel İÇİNDE geçerli; başka
     ekranlarda (`tum_ilanlar` vb.) kart rengi değişmez.
   ⚠️ Kaynak SIRASI önemli: `.nx-panel .nx-card` (0,2,0) ile tür kuralları (0,2,0)
     eşit özgüllükte; bu bölüm dosyanın SONUNDA olduğu için kazanır. Bölüm yukarı
     taşınırsa kural sessizce etkisiz kalır (6 Ağu'daki `mobile.css` dersinin aynısı).
   ========================================================================== */
.nx-panel {
  background: var(--nx-surface-2);
  border-radius: var(--nx-radius-lg);
  padding: var(--nx-space-md);
  /* ⛔ `box-shadow` YOK — gölge/halka kartın kimliği; panel gruplama yüzeyidir. */
}
/* Panelin içindeki kart bir kademe daha ilerler ki panelde erimesin. */
.nx-panel .nx-card { background: var(--nx-surface-3); }
/* Tıklanabilir kartın hover'ı da bir kademe ilerlemeli, yoksa panelde hover
   HİÇBİR ŞEY yapmaz (kartın kendi rengi zaten surface-3'e taşındı). */
@media (hover: hover) and (pointer: fine) {
  .nx-panel .nx-card--tiklanabilir:hover { background: var(--nx-surface-2); }
}
/* ── `--tasan` · ARTIK TAŞMIYOR ────────────────────────────────────────────
   🔴 **D37 BU KURALI TERSİNE ÇEVİRDİ (Efe kararı, 14 Ağu 2026).** Efe, tam
   kenara dayanan arka planlar sorulduğunda: *"8|8'e çekilsin — istisna olmasın."*

   ESKİ HÂLİ ve NEDEN VARDI (kayıt için, silinmiyor): panel normal akışta 16px
   yan dolgu ekleyince ilan kartı **359 → 327**, dar tile **175,5 → 159,5**
   düşüyordu; Keşfet'in kartı `tum_ilanlar`ınkinden dar kalmasın diye panel
   kabın yan dolgusu kadar DIŞARI taşıyor, aynı payı içeride geri veriyordu.

   ⚠️ **KABUL EDİLEN BEDEL:** taşma kalkınca panel 8px'e oturuyor ve içindeki
   kartlar panelin 8px'lik dolgusuyla **16px**'e iniyor ⇒ Keşfet'in kartı artık
   `tum_ilanlar`ınkinden 16px DAR. Bu, D37'nin özyineleme kuralının doğrudan
   sonucu (*"arka plan üzerinde duran kartlar arka plana yatayda aynı mesafede
   olsun"*) — hata değil, kuralın kendisi. Eski gerekçe geçersiz kılındı.
   ⚠️ `padding-inline` **8'de kalır** (16 değil): panelin içindeki kartın panele
     uzaklığı, panelin sayfaya uzaklığıyla aynı olmak zorunda. Taban
     `.nx-panel`ın 16px'i bu modifier'da bilerek eziliyor. */
.nx-panel--tasan {
  /* ⭐ 16 Ağu 2026 — Efe: *"kart ile arka plan arasındaki mesafeyi yarı yarıya
     düşür"* + *"iç kartları bir tık daha genişlet."*
     🔴 ÖNCEDEN `--nx-space-sm` (8px) YAZIYORDU ve D37'nin *"mekaniği TEK token"*
       cümlesi bu yüzden **doğru değildi**: kartın iç dolgusu
       `--nx-kart-dolgu-yatay`dan, panelin dolgusu ayrı bir uzam token'ından
       geliyordu. Token'ı 8→4 yapmak paneli hiç etkilemedi — ölçümle görüldü
       (tile genişliği 162,5'te sabit kaldı). ⇒ İkisi BİRLEŞTİRİLDİ; özyineleme
       artık gerçekten tek token'dan geliyor ve Efe'nin kuralı her kademede
       aynı anda değişiyor. */
  padding-inline: var(--nx-kart-dolgu-yatay);
}

/* ============================================================================
   ALT SAYFA (SAHNE) GEÇİŞİ — nxSahneGecir / nxSahneRota (kabuk.js)
   AI Loop Tur D, 24 Eyl 2026 · TABAN TURU (L-31 B: "tek motora insin")

   Kaynak: `ayarlar.html`in Efe tarafından KABUL EDİLMİŞ deseni (18 Eyl, AI Loop
   L3 Tur 1: **B** — giren sahne sağdan gelir, çıkan yerinde solar) ve Aura'nın
   ekran-yerel kopyası (kimlik-A, 21 Eyl). İki kopyanın değerleri AYNIYDI; kural
   bloğu buraya TEK kez taşındı, ekranlar kendi kopyalarını sildi.
   ⛔ Görünür overshoot/bounce YOK (Efe, 18 Eyl · D1): kritik sönümlü.
   ⛔ İki katmana AYRI süre verilmez: biri ötekini yakalar, O3 düşer.
   ============================================================================ */

/* ── HAREKET SÖZLÜĞÜ (O6) — merdivene oturmayan değerler kuralın içine gömülmez.
   JS'in beklediği iki sayı (geçiş süresi + emniyet payı) da buradan OKUNUR.
   📌 Sözlük `body`de: başlık (üst çubuk) ile içerik (ana gövde) kardeş dallardır,
     aynı değişkeni okumaları için ortak ata şart. */
body {
  --nx-sahne-soluk: 120ms;       /* az-hareket dalı (bu dosyanın :2024 emsali) */
  --nx-sahne-emniyet: 200ms;     /* `transitionend` gelmezse söküm payı */
  --nx-sahne-sure: var(--nx-dur-base);
  --nx-sahne-egri: var(--nx-ease-out);
  /* ⭐ Yol 100%'den BÜYÜK: kırpma sınırı kabın dolgu kenarı + kırpma payı olduğu
     için tam 100%'de sahnenin sağda bir şeridi GÖRÜNÜR kalıyordu (Codex bulgusu). */
  --nx-sahne-yol: calc(100% + var(--nx-kart-dolgu-yatay) + var(--nx-space-md));
  /* ── BAŞLIK YOLU (Tur D ESKİZ'inin YÖN değişkenleri) ──────────────────────
     Başlığın yolu içerikten kısadır (iOS'ta da öyle) ve boşluk merdiveninden
     gelir: giren +md'den, çıkan −md'ye (ileri) · tersi (geri).
     METİN (başlık yazısı) ve ÖĞE (başlık bölgesinde görünürlüğü değişen düğme/yuva)
     ayrı değişkendir: bir yön ikisine farklı yol verebilir. */
  --nx-sahne-bas-gir-ileri: var(--nx-space-md);
  --nx-sahne-bas-cik-ileri: calc(-1 * var(--nx-space-md));
  --nx-sahne-bas-gir-geri:  calc(-1 * var(--nx-space-md));
  --nx-sahne-bas-cik-geri:  var(--nx-space-md);
  --nx-sahne-oge-gir-ileri: var(--nx-space-md);
  --nx-sahne-oge-cik-ileri: calc(-1 * var(--nx-space-md));
  --nx-sahne-oge-gir-geri:  calc(-1 * var(--nx-space-md));
  --nx-sahne-oge-cik-geri:  var(--nx-space-md);
}
/* ⭐ GERİ = ÇIKIŞ ÇİFTİ: "çıkış girişten kısadır" kuralının gezinmedeki
   karşılığı — geri gitmek kararı verilmiş bir çıkıştır. */
body[data-nx-sahne-yon="geri"] {
  --nx-sahne-sure: var(--nx-dur-exit);
  --nx-sahne-egri: var(--nx-ease-in);
}

/* İki katman AYNI ızgara gözünde durur ⇒ eş zamanlı hareket eder, akıştan
   çıkmaz (sıralı çapraz geçiş elendi — DEVIR-ui-ux-faz1 §5.1/④). */
.nx-sahne-kap { display: grid; grid-template-columns: minmax(0, 1fr); }
/* ⭐⭐ KATMAN OPAK OLMAK ZORUNDA (Efe, 18 Eyl: *"giden menü tam fadeout olmuyor,
   kötü görünüyor"*): saydam katmanda giren sahne çıkanı örtmüyor, iki ekran yan
   yana görünüyordu. Zemin `body`nin arkasındaki rengin ta kendisi — duruşta
   görsel fark yok. Izgara öğesi satırı doldurur ⇒ kısa sahne uzunun altını örter. */
.nx-sahne-kap > .nx-sahne { grid-area: 1 / 1; min-width: 0; background: var(--nx-surface); }

/* ⚠️ KIRPMA YALNIZ GEÇİŞ SÜRERKEN: kalıcı `overflow-x: clip` duruşta kartların
   yüzen gölgesini keserdi. `clip`, `hidden` DEĞİL: `hidden` öteki ekseni kaydırma
   kabına çevirir, yapışkan öğeleri bozar. `overflow-clip-margin` gölge için
   (emsal bu dosyanın :1864'ü). */
body[data-nx-sahne-yon] .nx-sahne-kap {
  overflow-x: clip;
  overflow-clip-margin: var(--nx-space-md);
}
/* Boyama sırası yöne bağlı: ileri giderken GİREN üstte akar, geri giderken
   ÇIKAN üstte akar (pop). Yanlış sıra = opak katman ötekini örter. */
body[data-nx-sahne-yon="geri"] .nx-sahne-kap > .nx-sahne:not(:last-child) { z-index: 1; }

/* Geçiş YALNIZ oynarken tanımlı: `will-change` kalıcı kompozit katman bırakmasın. */
.nx-sahne[data-oynar] {
  transition: transform var(--nx-sahne-sure) var(--nx-sahne-egri),
              opacity   var(--nx-sahne-sure) var(--nx-sahne-egri);
  will-change: transform;
}
/* Giren katmanın BAŞLANGIÇ karesi · çıkan katmanın BİTİŞ karesi.
   B: yalnız GİREN yer değiştirir, çıkan solar (Efe, 18 Eyl). */
.nx-sahne.nx-sahne--gir-ileri { transform: translateX(var(--nx-sahne-yol)); }
.nx-sahne.nx-sahne--gir-geri  { opacity: 0; }
.nx-sahne.nx-sahne--cik-ileri { opacity: 0; }
.nx-sahne.nx-sahne--cik-geri  { transform: translateX(var(--nx-sahne-yol)); }

/* ── BAŞLIK KATMANI (O3: içerikle AYNI karede, AYNI süre ve eğriyle) ─────────
   Başlık iki katman olmadan eş zamanlı geçemez; tek öğeyle "geç-crossfade"
   SIRALI olur ve elenmiştir. Metin kabı (h1) DÖNÜŞMEZ, içindeki iki `span`
   dönüşür; görünürlüğü değişen öğe (Aura'nın geri düğmesi, hedef yuvası) kendi
   yerinde girer, çıkarken KLONU eski kutusunda kırpılarak gider.
   📌 Metin iki satırda kırpılır — `.nx-topbar__title`ın kendi üçlüsü katmana
     aynen uygulanır (değer icat edilmedi), uzun başlıkta davranış aynı. */
/* ⚠️ İKİ METİN KATMANI AYNI IZGARA HÜCRESİNDE (Tur D mükemmelleştirme, 24 Eyl — canlı
   ölçüldü): hayalet `absolute; inset: 0` iken metin kabı YENİ başlığın boyunu alıyordu ⇒
   uzun başlıktan kısa başlığa dönüşte eski başlık 68 px'lik kutuya sıkışıp dar bir sütunda
   yeniden kırılıyordu (115–253 px gizli satır, üç kip). Hücre ikisinin BÜYÜĞÜDÜR: her metin
   kendi kırılımını korur; hayalet sökülünce kutu yeni başlığa iner. `minmax(0, 1fr)`: tek
   uzun kelime hücreyi kaptan geniş açmasın, kendi kutusunda kırılsın. */
.nx-sahne-metin { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); }
.nx-sahne-metin > .nx-sahne-bas--metin {
  grid-area: 1 / 1; align-self: center;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.nx-sahne-metin > .nx-sahne-bas--hayalet { margin: 0; pointer-events: none; }
.nx-sahne-bas-kirp { position: absolute; overflow: clip; pointer-events: none; margin: 0; }
.nx-sahne-bas-kirp > .nx-sahne-bas--klon { position: absolute; inset: 0; margin: 0; }
/* ⭐ ÇİFT GÖRÜNTÜ ENGELİ (Efe'nin ekran görüntüsü, 18 Eyl): iki başlık aynı
   eğriyle solup dolunca ortada ikisi de ~%50 saydam kalıyor, harfler iç içe
   geçiyordu. HAREKET iki katmanda aynı süre/eğri — O3 bozulmaz; yalnız OPAKLIK
   zarfları ayrıldı: çıkan erken boşalır, giren geç dolar (0.50/0.50 → 0.19/0.29). */
.nx-sahne-bas[data-oynar] {
  transition: transform var(--nx-sahne-sure) var(--nx-sahne-egri),
              opacity   var(--nx-sahne-sure) var(--nx-ease-in);
}
.nx-sahne-bas--hayalet[data-oynar] {
  transition: transform var(--nx-sahne-sure) var(--nx-sahne-egri),
              opacity   var(--nx-sahne-sure) var(--nx-ease-out);
}
/* İleri giderken giren başlık üstte olmalı (hayalet konumlandırıldığı için
   varsayılan boyama sırasında zaten üstte) ⇒ giren yükseltilir. */
body[data-nx-sahne-yon="ileri"] .nx-sahne-bas:not(.nx-sahne-bas--hayalet) { position: relative; z-index: 1; }
.nx-sahne-bas--metin.nx-sahne--gir-ileri                      { transform: translateX(var(--nx-sahne-bas-gir-ileri)); opacity: 0; }
.nx-sahne-bas--metin.nx-sahne--gir-geri                       { transform: translateX(var(--nx-sahne-bas-gir-geri));  opacity: 0; }
.nx-sahne-bas--hayalet.nx-sahne-bas--metin.nx-sahne--cik-ileri { transform: translateX(var(--nx-sahne-bas-cik-ileri)); opacity: 0; }
.nx-sahne-bas--hayalet.nx-sahne-bas--metin.nx-sahne--cik-geri  { transform: translateX(var(--nx-sahne-bas-cik-geri));  opacity: 0; }
.nx-sahne-bas:not(.nx-sahne-bas--metin).nx-sahne--gir-ileri          { transform: translateX(var(--nx-sahne-oge-gir-ileri)); opacity: 0; }
.nx-sahne-bas:not(.nx-sahne-bas--metin).nx-sahne--gir-geri           { transform: translateX(var(--nx-sahne-oge-gir-geri));  opacity: 0; }
.nx-sahne-bas--hayalet:not(.nx-sahne-bas--metin).nx-sahne--cik-ileri { transform: translateX(var(--nx-sahne-oge-cik-ileri)); opacity: 0; }
.nx-sahne-bas--hayalet:not(.nx-sahne-bas--metin).nx-sahne--cik-geri  { transform: translateX(var(--nx-sahne-oge-cik-geri));  opacity: 0; }

/* ── BAŞLIK BOYU AKAR (Tur B taban-6, P17) ──────────────────────────────────
   Satır sayısı değişen geçişte metin kabının boyu içerikle AYNI süre ve eğride akar
   (O3 · O5); katmanlar kabın kutusunda DİKEY kırpılır, yatayda serbest (başlık yolu ±md).
   Geçiş bitince satır içi boy silinir (motor). Az harekette süre evrensel kuraldan
   (`tokens.css`): boy anlık değişir, hareket yok. */
.nx-sahne-metin[data-nx-boy-akar] {
  overflow-y: clip;
  transition: height var(--nx-sahne-sure) var(--nx-sahne-egri);
}
/* Başlık KAYBOLAN geçişte metin kabı gizlidir, boyu tutulamaz ⇒ çubuğun kendisi
   akar: taban boyu (`min-height`) eski boydan yeni doğal boya, aynı süre ve eğride. */
.nx-topbar[data-nx-boy-akar] { transition: min-height var(--nx-sahne-sure) var(--nx-sahne-egri); }
/* Çıkan başlığın KLONU uçarken çubuğun İÇ KUTUSUNDA dikey kırpılır: klon küçülen çubuğun
   altına taşmasın (Aura geri: 1 px). Kırpan çubuğun kendisi DEĞİL, klonun katmanı
   (motor: `.nx-sahne-bas-kat`, çubuğun iç kutusunu izler) — çubukta kalan 36 px ikon
   düğmesinin halkası (2 + 2 px) ve odak alan hedef yuvasının iç halkası 43 px iç boydan
   her yana 0,5 px taşar, çubuk kırpılsaydı kesilirdi (Codex ASTRA K3, 25 Eyl · halka
   ölçümü 26 Eyl). Yatayda serbest (başlık yolu ±md). Duruşta katman yok. */
.nx-sahne-bas-kat { position: absolute; inset: 0; overflow-x: visible; overflow-y: clip; pointer-events: none; margin: 0; }

/* ── AZ HAREKET: yer değiştirme kalkar, DURUM DEĞİŞİMİ GÖRÜNÜR kalır ─────────
   ⚠️⚠️ `!important` ZORUNLU, süs değil: `tokens.css`te evrensel
     `*{transition-duration:.01ms !important}` var ve bu dalı sessizce öldürürdü.
   ⛔ `transition: none` YAZILMAZ: JS süreyi CSS'ten okuyor; 0 olursa hayalet
     bir kare üstte kalır. Her iki yönde OPAKLIK değişir ⇒ `transitionend` her
     zaman gelir (Aura'nın 21 Eyl "hayalet donar" endişesi bu yüzden burada yok —
     Tur D'de canlı ölçüldü: söküm 123–153 ms, donmuş katman 0). */
@media (prefers-reduced-motion: reduce) {
  .nx-sahne[data-oynar],
  .nx-sahne-bas[data-oynar] {
    transition-property: opacity !important;
    transition-duration: var(--nx-sahne-soluk) !important;
    transition-timing-function: linear !important;
  }
  .nx-sahne.nx-sahne--gir-ileri, .nx-sahne.nx-sahne--gir-geri,
  .nx-sahne.nx-sahne--cik-ileri, .nx-sahne.nx-sahne--cik-geri,
  .nx-sahne-bas.nx-sahne--gir-ileri, .nx-sahne-bas.nx-sahne--gir-geri,
  .nx-sahne-bas--hayalet.nx-sahne--cik-ileri, .nx-sahne-bas--hayalet.nx-sahne--cik-geri {
    transform: none !important;
    opacity: 0 !important;
  }
}
